Revert "adding pods method of package managing"
This reverts commit 705203d7bd.
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
# Uncomment the next line to define a global platform for your project
|
||||
# platform :ios, '9.0'
|
||||
|
||||
target 'nirvana-ios' do
|
||||
# Comment the next line if you don't want to use dynamic frameworks
|
||||
use_frameworks!
|
||||
|
||||
# Pods for nirvana-ios
|
||||
pod 'FirebaseUI'
|
||||
pod 'FirebaseUI/Phone'
|
||||
pod 'FirebaseUI/Auth'
|
||||
pod 'FirebaseUI/Facebook'
|
||||
pod 'FirebaseUI/OAuth'
|
||||
pod 'FirebaseUI/Google'
|
||||
|
||||
end
|
||||
-618
@@ -1,618 +0,0 @@
|
||||
PODS:
|
||||
- abseil/algorithm (0.20200225.0):
|
||||
- abseil/algorithm/algorithm (= 0.20200225.0)
|
||||
- abseil/algorithm/container (= 0.20200225.0)
|
||||
- abseil/algorithm/algorithm (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/algorithm/container (0.20200225.0):
|
||||
- abseil/algorithm/algorithm
|
||||
- abseil/base/core_headers
|
||||
- abseil/meta/type_traits
|
||||
- abseil/base (0.20200225.0):
|
||||
- abseil/base/atomic_hook (= 0.20200225.0)
|
||||
- abseil/base/base (= 0.20200225.0)
|
||||
- abseil/base/base_internal (= 0.20200225.0)
|
||||
- abseil/base/bits (= 0.20200225.0)
|
||||
- abseil/base/config (= 0.20200225.0)
|
||||
- abseil/base/core_headers (= 0.20200225.0)
|
||||
- abseil/base/dynamic_annotations (= 0.20200225.0)
|
||||
- abseil/base/endian (= 0.20200225.0)
|
||||
- abseil/base/errno_saver (= 0.20200225.0)
|
||||
- abseil/base/exponential_biased (= 0.20200225.0)
|
||||
- abseil/base/log_severity (= 0.20200225.0)
|
||||
- abseil/base/malloc_internal (= 0.20200225.0)
|
||||
- abseil/base/periodic_sampler (= 0.20200225.0)
|
||||
- abseil/base/pretty_function (= 0.20200225.0)
|
||||
- abseil/base/raw_logging_internal (= 0.20200225.0)
|
||||
- abseil/base/spinlock_wait (= 0.20200225.0)
|
||||
- abseil/base/throw_delegate (= 0.20200225.0)
|
||||
- abseil/base/atomic_hook (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/base (0.20200225.0):
|
||||
- abseil/base/atomic_hook
|
||||
- abseil/base/base_internal
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/dynamic_annotations
|
||||
- abseil/base/log_severity
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/base/spinlock_wait
|
||||
- abseil/meta/type_traits
|
||||
- abseil/base/base_internal (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/meta/type_traits
|
||||
- abseil/base/bits (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/config (0.20200225.0)
|
||||
- abseil/base/core_headers (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/dynamic_annotations (0.20200225.0)
|
||||
- abseil/base/endian (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/errno_saver (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/exponential_biased (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/log_severity (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/malloc_internal (0.20200225.0):
|
||||
- abseil/base/base
|
||||
- abseil/base/base_internal
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/dynamic_annotations
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/base/periodic_sampler (0.20200225.0):
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/exponential_biased
|
||||
- abseil/base/pretty_function (0.20200225.0)
|
||||
- abseil/base/raw_logging_internal (0.20200225.0):
|
||||
- abseil/base/atomic_hook
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/log_severity
|
||||
- abseil/base/spinlock_wait (0.20200225.0):
|
||||
- abseil/base/base_internal
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/errno_saver
|
||||
- abseil/base/throw_delegate (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/container/common (0.20200225.0):
|
||||
- abseil/meta/type_traits
|
||||
- abseil/types/optional
|
||||
- abseil/container/compressed_tuple (0.20200225.0):
|
||||
- abseil/utility/utility
|
||||
- abseil/container/container_memory (0.20200225.0):
|
||||
- abseil/memory/memory
|
||||
- abseil/utility/utility
|
||||
- abseil/container/fixed_array (0.20200225.0):
|
||||
- abseil/algorithm/algorithm
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/dynamic_annotations
|
||||
- abseil/base/throw_delegate
|
||||
- abseil/container/compressed_tuple
|
||||
- abseil/memory/memory
|
||||
- abseil/container/flat_hash_map (0.20200225.0):
|
||||
- abseil/algorithm/container
|
||||
- abseil/container/container_memory
|
||||
- abseil/container/hash_function_defaults
|
||||
- abseil/container/raw_hash_map
|
||||
- abseil/memory/memory
|
||||
- abseil/container/hash_function_defaults (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/hash/hash
|
||||
- abseil/strings/strings
|
||||
- abseil/container/hash_policy_traits (0.20200225.0):
|
||||
- abseil/meta/type_traits
|
||||
- abseil/container/hashtable_debug_hooks (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/container/hashtablez_sampler (0.20200225.0):
|
||||
- abseil/base/base
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/exponential_biased
|
||||
- abseil/container/have_sse
|
||||
- abseil/debugging/stacktrace
|
||||
- abseil/memory/memory
|
||||
- abseil/synchronization/synchronization
|
||||
- abseil/utility/utility
|
||||
- abseil/container/have_sse (0.20200225.0)
|
||||
- abseil/container/inlined_vector (0.20200225.0):
|
||||
- abseil/algorithm/algorithm
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/throw_delegate
|
||||
- abseil/container/inlined_vector_internal
|
||||
- abseil/memory/memory
|
||||
- abseil/container/inlined_vector_internal (0.20200225.0):
|
||||
- abseil/base/core_headers
|
||||
- abseil/container/compressed_tuple
|
||||
- abseil/memory/memory
|
||||
- abseil/meta/type_traits
|
||||
- abseil/types/span
|
||||
- abseil/container/layout (0.20200225.0):
|
||||
- abseil/base/core_headers
|
||||
- abseil/meta/type_traits
|
||||
- abseil/strings/strings
|
||||
- abseil/types/span
|
||||
- abseil/utility/utility
|
||||
- abseil/container/raw_hash_map (0.20200225.0):
|
||||
- abseil/base/throw_delegate
|
||||
- abseil/container/container_memory
|
||||
- abseil/container/raw_hash_set
|
||||
- abseil/container/raw_hash_set (0.20200225.0):
|
||||
- abseil/base/bits
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/endian
|
||||
- abseil/container/common
|
||||
- abseil/container/compressed_tuple
|
||||
- abseil/container/container_memory
|
||||
- abseil/container/hash_policy_traits
|
||||
- abseil/container/hashtable_debug_hooks
|
||||
- abseil/container/hashtablez_sampler
|
||||
- abseil/container/have_sse
|
||||
- abseil/container/layout
|
||||
- abseil/memory/memory
|
||||
- abseil/meta/type_traits
|
||||
- abseil/utility/utility
|
||||
- abseil/debugging/debugging_internal (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/dynamic_annotations
|
||||
- abseil/base/errno_saver
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/debugging/demangle_internal (0.20200225.0):
|
||||
- abseil/base/base
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/debugging/stacktrace (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/debugging/debugging_internal
|
||||
- abseil/debugging/symbolize (0.20200225.0):
|
||||
- abseil/base/base
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/dynamic_annotations
|
||||
- abseil/base/malloc_internal
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/debugging/debugging_internal
|
||||
- abseil/debugging/demangle_internal
|
||||
- abseil/hash/city (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/endian
|
||||
- abseil/hash/hash (0.20200225.0):
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/endian
|
||||
- abseil/container/fixed_array
|
||||
- abseil/hash/city
|
||||
- abseil/meta/type_traits
|
||||
- abseil/numeric/int128
|
||||
- abseil/strings/strings
|
||||
- abseil/types/optional
|
||||
- abseil/types/variant
|
||||
- abseil/utility/utility
|
||||
- abseil/memory (0.20200225.0):
|
||||
- abseil/memory/memory (= 0.20200225.0)
|
||||
- abseil/memory/memory (0.20200225.0):
|
||||
- abseil/base/core_headers
|
||||
- abseil/meta/type_traits
|
||||
- abseil/meta (0.20200225.0):
|
||||
- abseil/meta/type_traits (= 0.20200225.0)
|
||||
- abseil/meta/type_traits (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/numeric/int128 (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/strings/internal (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/endian
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/meta/type_traits
|
||||
- abseil/strings/str_format (0.20200225.0):
|
||||
- abseil/strings/str_format_internal
|
||||
- abseil/strings/str_format_internal (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/meta/type_traits
|
||||
- abseil/numeric/int128
|
||||
- abseil/strings/strings
|
||||
- abseil/types/span
|
||||
- abseil/strings/strings (0.20200225.0):
|
||||
- abseil/base/base
|
||||
- abseil/base/bits
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/endian
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/base/throw_delegate
|
||||
- abseil/memory/memory
|
||||
- abseil/meta/type_traits
|
||||
- abseil/numeric/int128
|
||||
- abseil/strings/internal
|
||||
- abseil/synchronization/graphcycles_internal (0.20200225.0):
|
||||
- abseil/base/base
|
||||
- abseil/base/base_internal
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/malloc_internal
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/synchronization/kernel_timeout_internal (0.20200225.0):
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/time/time
|
||||
- abseil/synchronization/synchronization (0.20200225.0):
|
||||
- abseil/base/atomic_hook
|
||||
- abseil/base/base
|
||||
- abseil/base/base_internal
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/dynamic_annotations
|
||||
- abseil/base/malloc_internal
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/debugging/stacktrace
|
||||
- abseil/debugging/symbolize
|
||||
- abseil/synchronization/graphcycles_internal
|
||||
- abseil/synchronization/kernel_timeout_internal
|
||||
- abseil/time/time
|
||||
- abseil/time (0.20200225.0):
|
||||
- abseil/time/internal (= 0.20200225.0)
|
||||
- abseil/time/time (= 0.20200225.0)
|
||||
- abseil/time/internal (0.20200225.0):
|
||||
- abseil/time/internal/cctz (= 0.20200225.0)
|
||||
- abseil/time/internal/cctz (0.20200225.0):
|
||||
- abseil/time/internal/cctz/civil_time (= 0.20200225.0)
|
||||
- abseil/time/internal/cctz/time_zone (= 0.20200225.0)
|
||||
- abseil/time/internal/cctz/civil_time (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/time/internal/cctz/time_zone (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/time/internal/cctz/civil_time
|
||||
- abseil/time/time (0.20200225.0):
|
||||
- abseil/base/base
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/numeric/int128
|
||||
- abseil/strings/strings
|
||||
- abseil/time/internal/cctz/civil_time
|
||||
- abseil/time/internal/cctz/time_zone
|
||||
- abseil/types (0.20200225.0):
|
||||
- abseil/types/any (= 0.20200225.0)
|
||||
- abseil/types/bad_any_cast (= 0.20200225.0)
|
||||
- abseil/types/bad_any_cast_impl (= 0.20200225.0)
|
||||
- abseil/types/bad_optional_access (= 0.20200225.0)
|
||||
- abseil/types/bad_variant_access (= 0.20200225.0)
|
||||
- abseil/types/compare (= 0.20200225.0)
|
||||
- abseil/types/optional (= 0.20200225.0)
|
||||
- abseil/types/span (= 0.20200225.0)
|
||||
- abseil/types/variant (= 0.20200225.0)
|
||||
- abseil/types/any (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/meta/type_traits
|
||||
- abseil/types/bad_any_cast
|
||||
- abseil/utility/utility
|
||||
- abseil/types/bad_any_cast (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/types/bad_any_cast_impl
|
||||
- abseil/types/bad_any_cast_impl (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/types/bad_optional_access (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/types/bad_variant_access (0.20200225.0):
|
||||
- abseil/base/config
|
||||
- abseil/base/raw_logging_internal
|
||||
- abseil/types/compare (0.20200225.0):
|
||||
- abseil/base/core_headers
|
||||
- abseil/meta/type_traits
|
||||
- abseil/types/optional (0.20200225.0):
|
||||
- abseil/base/base_internal
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/memory/memory
|
||||
- abseil/meta/type_traits
|
||||
- abseil/types/bad_optional_access
|
||||
- abseil/utility/utility
|
||||
- abseil/types/span (0.20200225.0):
|
||||
- abseil/algorithm/algorithm
|
||||
- abseil/base/core_headers
|
||||
- abseil/base/throw_delegate
|
||||
- abseil/meta/type_traits
|
||||
- abseil/types/variant (0.20200225.0):
|
||||
- abseil/base/base_internal
|
||||
- abseil/base/config
|
||||
- abseil/base/core_headers
|
||||
- abseil/meta/type_traits
|
||||
- abseil/types/bad_variant_access
|
||||
- abseil/utility/utility
|
||||
- abseil/utility/utility (0.20200225.0):
|
||||
- abseil/base/base_internal
|
||||
- abseil/base/config
|
||||
- abseil/meta/type_traits
|
||||
- AppAuth (1.4.0):
|
||||
- AppAuth/Core (= 1.4.0)
|
||||
- AppAuth/ExternalUserAgent (= 1.4.0)
|
||||
- AppAuth/Core (1.4.0)
|
||||
- AppAuth/ExternalUserAgent (1.4.0)
|
||||
- BoringSSL-GRPC (0.0.7):
|
||||
- BoringSSL-GRPC/Implementation (= 0.0.7)
|
||||
- BoringSSL-GRPC/Interface (= 0.0.7)
|
||||
- BoringSSL-GRPC/Implementation (0.0.7):
|
||||
- BoringSSL-GRPC/Interface (= 0.0.7)
|
||||
- BoringSSL-GRPC/Interface (0.0.7)
|
||||
- FBAEMKit (11.2.1):
|
||||
- FBAEMKit/AEM (= 11.2.1)
|
||||
- FBAEMKit/AEM (11.2.1):
|
||||
- FBSDKCoreKit_Basics (~> 11.2.1)
|
||||
- FBSDKCoreKit (11.2.1):
|
||||
- FBSDKCoreKit/Core (= 11.2.1)
|
||||
- FBSDKCoreKit/Core (11.2.1):
|
||||
- FBAEMKit (~> 11.2.1)
|
||||
- FBSDKCoreKit_Basics (~> 11.2.1)
|
||||
- FBSDKCoreKit_Basics (11.2.1):
|
||||
- FBSDKCoreKit_Basics/Basics (= 11.2.1)
|
||||
- FBSDKCoreKit_Basics/Basics (11.2.1)
|
||||
- FBSDKLoginKit (11.2.1):
|
||||
- FBSDKLoginKit/Login (= 11.2.1)
|
||||
- FBSDKLoginKit/Login (11.2.1):
|
||||
- FBSDKCoreKit (~> 11.2.1)
|
||||
- FBSDKCoreKit_Basics (~> 11.2.1)
|
||||
- FirebaseAnonymousAuthUI (12.0.0):
|
||||
- FirebaseAuth (~> 8.0)
|
||||
- FirebaseAuthUI
|
||||
- FirebaseCore
|
||||
- FirebaseAuth (8.10.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.6)
|
||||
- GoogleUtilities/Environment (~> 7.6)
|
||||
- GTMSessionFetcher/Core (~> 1.5)
|
||||
- FirebaseAuthUI (12.0.2):
|
||||
- FirebaseAuth (~> 8.0)
|
||||
- FirebaseCore
|
||||
- FirebaseCore (8.10.0):
|
||||
- FirebaseCoreDiagnostics (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 7.6)
|
||||
- GoogleUtilities/Logger (~> 7.6)
|
||||
- FirebaseCoreDiagnostics (8.10.0):
|
||||
- GoogleDataTransport (~> 9.1)
|
||||
- GoogleUtilities/Environment (~> 7.6)
|
||||
- GoogleUtilities/Logger (~> 7.6)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseDatabase (8.10.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- leveldb-library (~> 1.22)
|
||||
- FirebaseDatabaseUI (12.0.0):
|
||||
- FirebaseDatabase (~> 8.0)
|
||||
- FirebaseEmailAuthUI (12.0.0):
|
||||
- FirebaseAuth
|
||||
- FirebaseAuthUI
|
||||
- FirebaseCore
|
||||
- GoogleUtilities/UserDefaults
|
||||
- FirebaseFacebookAuthUI (12.0.0):
|
||||
- FBSDKCoreKit_Basics
|
||||
- FBSDKLoginKit (~> 11.0)
|
||||
- FirebaseAuth
|
||||
- FirebaseAuthUI
|
||||
- FirebaseCore
|
||||
- FirebaseFirestore (8.10.0):
|
||||
- abseil/algorithm (= 0.20200225.0)
|
||||
- abseil/base (= 0.20200225.0)
|
||||
- abseil/container/flat_hash_map (= 0.20200225.0)
|
||||
- abseil/memory (= 0.20200225.0)
|
||||
- abseil/meta (= 0.20200225.0)
|
||||
- abseil/strings/strings (= 0.20200225.0)
|
||||
- abseil/time (= 0.20200225.0)
|
||||
- abseil/types (= 0.20200225.0)
|
||||
- FirebaseCore (~> 8.0)
|
||||
- "gRPC-C++ (~> 1.28.0)"
|
||||
- leveldb-library (~> 1.22)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseFirestoreUI (12.0.0):
|
||||
- FirebaseFirestore (~> 8.0)
|
||||
- FirebaseGoogleAuthUI (12.0.0):
|
||||
- FirebaseAuth
|
||||
- FirebaseAuthUI
|
||||
- FirebaseCore
|
||||
- GoogleSignIn (~> 6.0)
|
||||
- FirebaseOAuthUI (12.0.2):
|
||||
- FirebaseAuth (~> 8.0)
|
||||
- FirebaseAuthUI (< 13.0, >= 12.0.2)
|
||||
- FirebasePhoneAuthUI (12.0.0):
|
||||
- FirebaseAuth
|
||||
- FirebaseAuthUI
|
||||
- FirebaseStorage (8.10.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- GTMSessionFetcher/Core (~> 1.5)
|
||||
- FirebaseStorageUI (12.0.0):
|
||||
- FirebaseStorage (~> 8.0)
|
||||
- SDWebImage (~> 5.6)
|
||||
- FirebaseUI (12.0.2):
|
||||
- FirebaseUI/Anonymous (= 12.0.2)
|
||||
- FirebaseUI/Auth (= 12.0.2)
|
||||
- FirebaseUI/Database (= 12.0.2)
|
||||
- FirebaseUI/Email (= 12.0.2)
|
||||
- FirebaseUI/Facebook (= 12.0.2)
|
||||
- FirebaseUI/Firestore (= 12.0.2)
|
||||
- FirebaseUI/Google (= 12.0.2)
|
||||
- FirebaseUI/OAuth (= 12.0.2)
|
||||
- FirebaseUI/Phone (= 12.0.2)
|
||||
- FirebaseUI/Storage (= 12.0.2)
|
||||
- FirebaseUI/Anonymous (12.0.2):
|
||||
- FirebaseAnonymousAuthUI (~> 12.0)
|
||||
- FirebaseUI/Auth (12.0.2):
|
||||
- FirebaseAuthUI (~> 12.0)
|
||||
- FirebaseUI/Database (12.0.2):
|
||||
- FirebaseDatabaseUI (~> 12.0)
|
||||
- FirebaseUI/Email (12.0.2):
|
||||
- FirebaseEmailAuthUI (~> 12.0)
|
||||
- FirebaseUI/Facebook (12.0.2):
|
||||
- FirebaseFacebookAuthUI (~> 12.0)
|
||||
- FirebaseUI/Firestore (12.0.2):
|
||||
- FirebaseFirestoreUI (~> 12.0)
|
||||
- FirebaseUI/Google (12.0.2):
|
||||
- FirebaseGoogleAuthUI (~> 12.0)
|
||||
- FirebaseUI/OAuth (12.0.2):
|
||||
- FirebaseOAuthUI (~> 12.0)
|
||||
- FirebaseUI/Phone (12.0.2):
|
||||
- FirebasePhoneAuthUI (~> 12.0)
|
||||
- FirebaseUI/Storage (12.0.2):
|
||||
- FirebaseStorageUI (~> 12.0)
|
||||
- GoogleDataTransport (9.1.2):
|
||||
- GoogleUtilities/Environment (~> 7.2)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- GoogleSignIn (6.0.2):
|
||||
- AppAuth (~> 1.4)
|
||||
- GTMAppAuth (~> 1.0)
|
||||
- GTMSessionFetcher/Core (~> 1.1)
|
||||
- GoogleUtilities/AppDelegateSwizzler (7.6.0):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network
|
||||
- GoogleUtilities/Environment (7.6.0):
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- GoogleUtilities/Logger (7.6.0):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Network (7.6.0):
|
||||
- GoogleUtilities/Logger
|
||||
- "GoogleUtilities/NSData+zlib"
|
||||
- GoogleUtilities/Reachability
|
||||
- "GoogleUtilities/NSData+zlib (7.6.0)"
|
||||
- GoogleUtilities/Reachability (7.6.0):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/UserDefaults (7.6.0):
|
||||
- GoogleUtilities/Logger
|
||||
- "gRPC-C++ (1.28.2)":
|
||||
- "gRPC-C++/Implementation (= 1.28.2)"
|
||||
- "gRPC-C++/Interface (= 1.28.2)"
|
||||
- "gRPC-C++/Implementation (1.28.2)":
|
||||
- abseil/container/inlined_vector (= 0.20200225.0)
|
||||
- abseil/memory/memory (= 0.20200225.0)
|
||||
- abseil/strings/str_format (= 0.20200225.0)
|
||||
- abseil/strings/strings (= 0.20200225.0)
|
||||
- abseil/types/optional (= 0.20200225.0)
|
||||
- "gRPC-C++/Interface (= 1.28.2)"
|
||||
- gRPC-Core (= 1.28.2)
|
||||
- "gRPC-C++/Interface (1.28.2)"
|
||||
- gRPC-Core (1.28.2):
|
||||
- gRPC-Core/Implementation (= 1.28.2)
|
||||
- gRPC-Core/Interface (= 1.28.2)
|
||||
- gRPC-Core/Implementation (1.28.2):
|
||||
- abseil/container/inlined_vector (= 0.20200225.0)
|
||||
- abseil/memory/memory (= 0.20200225.0)
|
||||
- abseil/strings/str_format (= 0.20200225.0)
|
||||
- abseil/strings/strings (= 0.20200225.0)
|
||||
- abseil/types/optional (= 0.20200225.0)
|
||||
- BoringSSL-GRPC (= 0.0.7)
|
||||
- gRPC-Core/Interface (= 1.28.2)
|
||||
- gRPC-Core/Interface (1.28.2)
|
||||
- GTMAppAuth (1.2.2):
|
||||
- AppAuth/Core (~> 1.4)
|
||||
- GTMSessionFetcher/Core (~> 1.5)
|
||||
- GTMSessionFetcher/Core (1.7.0)
|
||||
- leveldb-library (1.22.1)
|
||||
- nanopb (2.30908.0):
|
||||
- nanopb/decode (= 2.30908.0)
|
||||
- nanopb/encode (= 2.30908.0)
|
||||
- nanopb/decode (2.30908.0)
|
||||
- nanopb/encode (2.30908.0)
|
||||
- PromisesObjC (2.0.0)
|
||||
- SDWebImage (5.12.1):
|
||||
- SDWebImage/Core (= 5.12.1)
|
||||
- SDWebImage/Core (5.12.1)
|
||||
|
||||
DEPENDENCIES:
|
||||
- FirebaseUI
|
||||
- FirebaseUI/Auth
|
||||
- FirebaseUI/Facebook
|
||||
- FirebaseUI/Google
|
||||
- FirebaseUI/OAuth
|
||||
- FirebaseUI/Phone
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- abseil
|
||||
- AppAuth
|
||||
- BoringSSL-GRPC
|
||||
- FBAEMKit
|
||||
- FBSDKCoreKit
|
||||
- FBSDKCoreKit_Basics
|
||||
- FBSDKLoginKit
|
||||
- FirebaseAnonymousAuthUI
|
||||
- FirebaseAuth
|
||||
- FirebaseAuthUI
|
||||
- FirebaseCore
|
||||
- FirebaseCoreDiagnostics
|
||||
- FirebaseDatabase
|
||||
- FirebaseDatabaseUI
|
||||
- FirebaseEmailAuthUI
|
||||
- FirebaseFacebookAuthUI
|
||||
- FirebaseFirestore
|
||||
- FirebaseFirestoreUI
|
||||
- FirebaseGoogleAuthUI
|
||||
- FirebaseOAuthUI
|
||||
- FirebasePhoneAuthUI
|
||||
- FirebaseStorage
|
||||
- FirebaseStorageUI
|
||||
- FirebaseUI
|
||||
- GoogleDataTransport
|
||||
- GoogleSignIn
|
||||
- GoogleUtilities
|
||||
- "gRPC-C++"
|
||||
- gRPC-Core
|
||||
- GTMAppAuth
|
||||
- GTMSessionFetcher
|
||||
- leveldb-library
|
||||
- nanopb
|
||||
- PromisesObjC
|
||||
- SDWebImage
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
abseil: 6c8eb7892aefa08d929b39f9bb108e5367e3228f
|
||||
AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
|
||||
BoringSSL-GRPC: 8edf627ee524575e2f8d19d56f068b448eea3879
|
||||
FBAEMKit: 5de0a7aaa854eec69bb5be20795952a63d38a5f6
|
||||
FBSDKCoreKit: bf655f808b040ed66a72b9922911b39d703e64f4
|
||||
FBSDKCoreKit_Basics: 73ebe3a27eb688ac5b5aa7e99f68992993042115
|
||||
FBSDKLoginKit: 2e76831ef08d356b8f9150ea51cce865074ea304
|
||||
FirebaseAnonymousAuthUI: dc0d806fb53268e79fa64ae8ffd8e1adfc242244
|
||||
FirebaseAuth: 59a2d2b933b5b79e18fb1e6ad230c6abdaa73d26
|
||||
FirebaseAuthUI: e75ef9d6cfcd8f1ba8bee2b360493a9947533f6c
|
||||
FirebaseCore: 04186597c095da37d90ff9fd3e53bc61a1ff2440
|
||||
FirebaseCoreDiagnostics: 56fb7216d87e0e6ec2feddefa9d8a392fe8b2c18
|
||||
FirebaseDatabase: 5f3e83b0a0d8759378fbd5d05661244d14dfbbb0
|
||||
FirebaseDatabaseUI: 0c16b8e11f58bf9e8644d219fa16b361db142255
|
||||
FirebaseEmailAuthUI: 6d0c5646c49b33a72dbe73a0ff9c908a59b5ff29
|
||||
FirebaseFacebookAuthUI: a478313687c2001b53470d7cc265a48a2c504ab8
|
||||
FirebaseFirestore: 0e7321a508cc9de54316ec45400caba6b5719beb
|
||||
FirebaseFirestoreUI: ec98193d249eaa30ed615857b1daf475fbc75248
|
||||
FirebaseGoogleAuthUI: 6981c0c3c054367f9ccd730fbcf483504deb0a68
|
||||
FirebaseOAuthUI: 8dc3d0270781133b10b2666d1163cd298501f453
|
||||
FirebasePhoneAuthUI: d84be4a096ddc19f9aace4a6ebcf80fe334f466b
|
||||
FirebaseStorage: 815410224b548172c578f02554a86bbc8f817f50
|
||||
FirebaseStorageUI: 9f5b32264e77dc073dec45f00c5b3a77e5ca901e
|
||||
FirebaseUI: b04b32ead3a6dcd5a50829e14b8f3f6d044d5d62
|
||||
GoogleDataTransport: 629c20a4d363167143f30ea78320d5a7eb8bd940
|
||||
GoogleSignIn: fd381840dbe7c1137aa6dc30849a5c3e070c034a
|
||||
GoogleUtilities: 684ee790a24f73ebb2d1d966e9711c203f2a4237
|
||||
"gRPC-C++": 13d8ccef97d5c3c441b7e3c529ef28ebee86fad2
|
||||
gRPC-Core: 4afa11bfbedf7cdecd04de535a9e046893404ed5
|
||||
GTMAppAuth: ad5c2b70b9a8689e1a04033c9369c4915bfcbe89
|
||||
GTMSessionFetcher: 43748f93435c2aa068b1cbe39655aaf600652e91
|
||||
leveldb-library: 50c7b45cbd7bf543c81a468fe557a16ae3db8729
|
||||
nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
|
||||
PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58
|
||||
SDWebImage: 4dc3e42d9ec0c1028b960a33ac6b637bb432207b
|
||||
|
||||
PODFILE CHECKSUM: bbdaea187a5e0664961604388e9845b5f79f44b4
|
||||
|
||||
COCOAPODS: 1.11.2
|
||||
Generated
-202
@@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Generated
-574
@@ -1,574 +0,0 @@
|
||||

|
||||
[](https://travis-ci.org/openid/AppAuth-iOS)
|
||||
[](https://github.com/Carthage/Carthage)
|
||||
|
||||
AppAuth for iOS and macOS is a client SDK for communicating with
|
||||
[OAuth 2.0](https://tools.ietf.org/html/rfc6749) and
|
||||
[OpenID Connect](http://openid.net/specs/openid-connect-core-1_0.html) providers.
|
||||
It strives to
|
||||
directly map the requests and responses of those specifications, while following
|
||||
the idiomatic style of the implementation language. In addition to mapping the
|
||||
raw protocol flows, convenience methods are available to assist with common
|
||||
tasks like performing an action with fresh tokens.
|
||||
|
||||
It follows the best practices set out in
|
||||
[RFC 8252 - OAuth 2.0 for Native Apps](https://tools.ietf.org/html/rfc8252)
|
||||
including using `SFAuthenticationSession` and `SFSafariViewController` on iOS
|
||||
for the auth request. `UIWebView` and `WKWebView` are explicitly *not*
|
||||
supported due to the security and usability reasons explained in
|
||||
[Section 8.12 of RFC 8252](https://tools.ietf.org/html/rfc8252#section-8.12).
|
||||
|
||||
It also supports the [PKCE](https://tools.ietf.org/html/rfc7636) extension to
|
||||
OAuth, which was created to secure authorization codes in public clients when
|
||||
custom URI scheme redirects are used. The library is friendly to other
|
||||
extensions (standard or otherwise), with the ability to handle additional params
|
||||
in all protocol requests and responses.
|
||||
|
||||
## Specification
|
||||
|
||||
### iOS
|
||||
|
||||
#### Supported Versions
|
||||
|
||||
AppAuth supports iOS 7 and above.
|
||||
|
||||
iOS 9+ uses the in-app browser tab pattern
|
||||
(via `SFSafariViewController`), and falls back to the system browser (mobile
|
||||
Safari) on earlier versions.
|
||||
|
||||
#### Authorization Server Requirements
|
||||
|
||||
Both Custom URI Schemes (all supported versions of iOS) and Universal Links
|
||||
(iOS 9+) can be used with the library.
|
||||
|
||||
In general, AppAuth can work with any authorization server that supports
|
||||
native apps, as documented in [RFC 8252](https://tools.ietf.org/html/rfc8252),
|
||||
either through custom URI scheme redirects, or universal links.
|
||||
Authorization servers that assume all clients are web-based, or require clients to maintain
|
||||
confidentiality of the client secrets may not work well.
|
||||
|
||||
### macOS
|
||||
|
||||
#### Supported Versions
|
||||
|
||||
AppAuth supports macOS (OS X) 10.9 and above.
|
||||
|
||||
#### Authorization Server Requirements
|
||||
|
||||
AppAuth for macOS supports both custom schemes; a loopback HTTP redirects
|
||||
via a small embedded server.
|
||||
|
||||
In general, AppAuth can work with any authorization server that supports
|
||||
native apps, as documented in [RFC 8252](https://tools.ietf.org/html/rfc8252);
|
||||
either through custom URI schemes, or loopback HTTP redirects.
|
||||
Authorization servers that assume all clients are web-based, or require clients to maintain
|
||||
confidentiality of the client secrets may not work well.
|
||||
|
||||
## Try
|
||||
|
||||
Want to try out AppAuth? Just run:
|
||||
|
||||
pod try AppAuth
|
||||
|
||||
Follow the instructions in [Examples/README.md](Examples/README.md) to configure
|
||||
with your own OAuth client (you need to update three configuration points with your
|
||||
client info to try the demo).
|
||||
|
||||
## Setup
|
||||
|
||||
AppAuth supports four options for dependency management.
|
||||
|
||||
### Swift Package Manager
|
||||
|
||||
With [Swift Package Manager](https://swift.org/package-manager),
|
||||
add the following `dependency` to your `Package.swift`:
|
||||
|
||||
```swift
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/openid/AppAuth-iOS.git", .upToNextMajor(from: "1.3.0"))
|
||||
]
|
||||
```
|
||||
|
||||
### CocoaPods
|
||||
|
||||
With [CocoaPods](https://guides.cocoapods.org/using/getting-started.html),
|
||||
add the following line to your `Podfile`:
|
||||
|
||||
pod 'AppAuth'
|
||||
|
||||
Then, run `pod install`.
|
||||
|
||||
### Carthage
|
||||
|
||||
With [Carthage](https://github.com/Carthage/Carthage), add the following
|
||||
line to your `Cartfile`:
|
||||
|
||||
github "openid/AppAuth-iOS" "master"
|
||||
|
||||
Then, run `carthage bootstrap`.
|
||||
|
||||
### Static Library
|
||||
|
||||
You can also use AppAuth as a static library. This requires linking the library
|
||||
and your project, and including the headers. Here is a suggested configuration:
|
||||
|
||||
1. Create an Xcode Workspace.
|
||||
2. Add `AppAuth.xcodeproj` to your Workspace.
|
||||
3. Include libAppAuth as a linked library for your target (in the "General ->
|
||||
Linked Framework and Libraries" section of your target).
|
||||
4. Add `AppAuth-iOS/Source` to your search paths of your target ("Build Settings ->
|
||||
"Header Search Paths").
|
||||
|
||||
## Auth Flow
|
||||
|
||||
AppAuth supports both manual interaction with the authorization server
|
||||
where you need to perform your own token exchanges, as well as convenience
|
||||
methods that perform some of this logic for you. This example uses the
|
||||
convenience method, which returns either an `OIDAuthState` object, or an error.
|
||||
|
||||
`OIDAuthState` is a class that keeps track of the authorization and token
|
||||
requests and responses, and provides a convenience method to call an API with
|
||||
fresh tokens. This is the only object that you need to serialize to retain the
|
||||
authorization state of the session.
|
||||
|
||||
### Configuration
|
||||
|
||||
You can configure AppAuth by specifying the endpoints directly:
|
||||
|
||||
<sub>Objective-C</sub>
|
||||
```objc
|
||||
NSURL *authorizationEndpoint =
|
||||
[NSURL URLWithString:@"https://accounts.google.com/o/oauth2/v2/auth"];
|
||||
NSURL *tokenEndpoint =
|
||||
[NSURL URLWithString:@"https://www.googleapis.com/oauth2/v4/token"];
|
||||
|
||||
OIDServiceConfiguration *configuration =
|
||||
[[OIDServiceConfiguration alloc]
|
||||
initWithAuthorizationEndpoint:authorizationEndpoint
|
||||
tokenEndpoint:tokenEndpoint];
|
||||
|
||||
// perform the auth request...
|
||||
```
|
||||
|
||||
<sub>Swift</sub>
|
||||
```swift
|
||||
let authorizationEndpoint = URL(string: "https://accounts.google.com/o/oauth2/v2/auth")!
|
||||
let tokenEndpoint = URL(string: "https://www.googleapis.com/oauth2/v4/token")!
|
||||
let configuration = OIDServiceConfiguration(authorizationEndpoint: authorizationEndpoint,
|
||||
tokenEndpoint: tokenEndpoint)
|
||||
|
||||
// perform the auth request...
|
||||
```
|
||||
|
||||
Or through discovery:
|
||||
|
||||
<sub>Objective-C</sub>
|
||||
```objc
|
||||
NSURL *issuer = [NSURL URLWithString:@"https://accounts.google.com"];
|
||||
|
||||
[OIDAuthorizationService discoverServiceConfigurationForIssuer:issuer
|
||||
completion:^(OIDServiceConfiguration *_Nullable configuration,
|
||||
NSError *_Nullable error) {
|
||||
|
||||
if (!configuration) {
|
||||
NSLog(@"Error retrieving discovery document: %@",
|
||||
[error localizedDescription]);
|
||||
return;
|
||||
}
|
||||
|
||||
// perform the auth request...
|
||||
}];
|
||||
```
|
||||
|
||||
<sub>Swift</sub>
|
||||
```swift
|
||||
let issuer = URL(string: "https://accounts.google.com")!
|
||||
|
||||
// discovers endpoints
|
||||
OIDAuthorizationService.discoverConfiguration(forIssuer: issuer) { configuration, error in
|
||||
guard let config = configuration else {
|
||||
print("Error retrieving discovery document: \(error?.localizedDescription ?? "Unknown error")")
|
||||
return
|
||||
}
|
||||
|
||||
// perform the auth request...
|
||||
}
|
||||
```
|
||||
|
||||
### Authorizing – iOS
|
||||
|
||||
First, you need to have a property in your `UIApplicationDelegate`
|
||||
implementation to hold the session, in order to continue the authorization flow
|
||||
from the redirect. In this example, the implementation of this delegate is
|
||||
a class named `AppDelegate`, if your app's application delegate has a different
|
||||
name, please update the class name in samples below accordingly.
|
||||
|
||||
<sub>Objective-C</sub>
|
||||
```objc
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
// property of the app's AppDelegate
|
||||
@property(nonatomic, strong, nullable) id<OIDExternalUserAgentSession> currentAuthorizationFlow;
|
||||
@end
|
||||
```
|
||||
|
||||
<sub>Swift</sub>
|
||||
```swift
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
// property of the app's AppDelegate
|
||||
var currentAuthorizationFlow: OIDExternalUserAgentSession?
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
And your main class, a property to store the auth state:
|
||||
|
||||
<sub>Objective-C</sub>
|
||||
```objc
|
||||
// property of the containing class
|
||||
@property(nonatomic, strong, nullable) OIDAuthState *authState;
|
||||
```
|
||||
<sub>Swift</sub>
|
||||
```swift
|
||||
// property of the containing class
|
||||
private var authState: OIDAuthState?
|
||||
```
|
||||
|
||||
|
||||
Then, initiate the authorization request. By using the
|
||||
`authStateByPresentingAuthorizationRequest` convenience method, the token
|
||||
exchange will be performed automatically, and everything will be protected with
|
||||
PKCE (if the server supports it). AppAuth also lets you perform these
|
||||
requests manually. See the `authNoCodeExchange` method in the included Example
|
||||
app for a demonstration:
|
||||
|
||||
<sub>Objective-C</sub>
|
||||
```objc
|
||||
// builds authentication request
|
||||
OIDAuthorizationRequest *request =
|
||||
[[OIDAuthorizationRequest alloc] initWithConfiguration:configuration
|
||||
clientId:kClientID
|
||||
scopes:@[OIDScopeOpenID,
|
||||
OIDScopeProfile]
|
||||
redirectURL:kRedirectURI
|
||||
responseType:OIDResponseTypeCode
|
||||
additionalParameters:nil];
|
||||
|
||||
// performs authentication request
|
||||
AppDelegate *appDelegate =
|
||||
(AppDelegate *)[UIApplication sharedApplication].delegate;
|
||||
appDelegate.currentAuthorizationFlow =
|
||||
[OIDAuthState authStateByPresentingAuthorizationRequest:request
|
||||
presentingViewController:self
|
||||
callback:^(OIDAuthState *_Nullable authState,
|
||||
NSError *_Nullable error) {
|
||||
if (authState) {
|
||||
NSLog(@"Got authorization tokens. Access token: %@",
|
||||
authState.lastTokenResponse.accessToken);
|
||||
[self setAuthState:authState];
|
||||
} else {
|
||||
NSLog(@"Authorization error: %@", [error localizedDescription]);
|
||||
[self setAuthState:nil];
|
||||
}
|
||||
}];
|
||||
```
|
||||
|
||||
<sub>Swift</sub>
|
||||
```swift
|
||||
// builds authentication request
|
||||
let request = OIDAuthorizationRequest(configuration: configuration,
|
||||
clientId: clientID,
|
||||
clientSecret: clientSecret,
|
||||
scopes: [OIDScopeOpenID, OIDScopeProfile],
|
||||
redirectURL: redirectURI,
|
||||
responseType: OIDResponseTypeCode,
|
||||
additionalParameters: nil)
|
||||
|
||||
// performs authentication request
|
||||
print("Initiating authorization request with scope: \(request.scope ?? "nil")")
|
||||
|
||||
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
||||
|
||||
appDelegate.currentAuthorizationFlow =
|
||||
OIDAuthState.authState(byPresenting: request, presenting: self) { authState, error in
|
||||
if let authState = authState {
|
||||
self.setAuthState(authState)
|
||||
print("Got authorization tokens. Access token: " +
|
||||
"\(authState.lastTokenResponse?.accessToken ?? "nil")")
|
||||
} else {
|
||||
print("Authorization error: \(error?.localizedDescription ?? "Unknown error")")
|
||||
self.setAuthState(nil)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
*Handling the Redirect*
|
||||
|
||||
The authorization response URL is returned to the app via the iOS openURL
|
||||
app delegate method, so you need to pipe this through to the current
|
||||
authorization session (created in the previous session):
|
||||
|
||||
<sub>Objective-C</sub>
|
||||
```objc
|
||||
- (BOOL)application:(UIApplication *)app
|
||||
openURL:(NSURL *)url
|
||||
options:(NSDictionary<NSString *, id> *)options {
|
||||
// Sends the URL to the current authorization flow (if any) which will
|
||||
// process it if it relates to an authorization response.
|
||||
if ([_currentAuthorizationFlow resumeExternalUserAgentFlowWithURL:url]) {
|
||||
_currentAuthorizationFlow = nil;
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Your additional URL handling (if any) goes here.
|
||||
|
||||
return NO;
|
||||
}
|
||||
```
|
||||
|
||||
<sub>Swift</sub>
|
||||
```swift
|
||||
func application(_ app: UIApplication,
|
||||
open url: URL,
|
||||
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
|
||||
// Sends the URL to the current authorization flow (if any) which will
|
||||
// process it if it relates to an authorization response.
|
||||
if let authorizationFlow = self.currentAuthorizationFlow,
|
||||
authorizationFlow.resumeExternalUserAgentFlow(with: url) {
|
||||
self.currentAuthorizationFlow = nil
|
||||
return true
|
||||
}
|
||||
|
||||
// Your additional URL handling (if any)
|
||||
|
||||
return false
|
||||
}
|
||||
```
|
||||
|
||||
### Authorizing – MacOS
|
||||
|
||||
On macOS, the most popular way to get the authorization response redirect is to
|
||||
start a local HTTP server on the loopback interface (limited to incoming
|
||||
requests from the user's machine only). When the authorization is complete, the
|
||||
user is redirected to that local server, and the authorization response can be
|
||||
processed by the app. AppAuth takes care of managing the local HTTP server
|
||||
lifecycle for you.
|
||||
|
||||
> #### :bulb: Alternative: Custom URI Schemes
|
||||
> Custom URI schemes are also supported on macOS, but some browsers display
|
||||
> an interstitial, which reduces the usability. For an example on using custom
|
||||
> URI schemes with macOS, See `Example-Mac`.
|
||||
|
||||
To receive the authorization response using a local HTTP server, first you need
|
||||
to have an instance variable in your main class to retain the HTTP redirect
|
||||
handler:
|
||||
|
||||
<sub>Objective-C</sub>
|
||||
```objc
|
||||
OIDRedirectHTTPHandler *_redirectHTTPHandler;
|
||||
```
|
||||
|
||||
Then, as the port used by the local HTTP server varies, you need to start it
|
||||
before building the authorization request, in order to get the exact redirect
|
||||
URI to use:
|
||||
|
||||
<sub>Objective-C</sub>
|
||||
```objc
|
||||
static NSString *const kSuccessURLString =
|
||||
@"http://openid.github.io/AppAuth-iOS/redirect/";
|
||||
NSURL *successURL = [NSURL URLWithString:kSuccessURLString];
|
||||
|
||||
// Starts a loopback HTTP redirect listener to receive the code. This needs to be started first,
|
||||
// as the exact redirect URI (including port) must be passed in the authorization request.
|
||||
_redirectHTTPHandler = [[OIDRedirectHTTPHandler alloc] initWithSuccessURL:successURL];
|
||||
NSURL *redirectURI = [_redirectHTTPHandler startHTTPListener:nil];
|
||||
```
|
||||
|
||||
Then, initiate the authorization request. By using the
|
||||
`authStateByPresentingAuthorizationRequest` convenience method, the token
|
||||
exchange will be performed automatically, and everything will be protected with
|
||||
PKCE (if the server supports it). By assigning the return value to the
|
||||
`OIDRedirectHTTPHandler`'s `currentAuthorizationFlow`, the authorization will
|
||||
continue automatically once the user makes their choice:
|
||||
|
||||
```objc
|
||||
// builds authentication request
|
||||
OIDAuthorizationRequest *request =
|
||||
[[OIDAuthorizationRequest alloc] initWithConfiguration:configuration
|
||||
clientId:kClientID
|
||||
clientSecret:kClientSecret
|
||||
scopes:@[ OIDScopeOpenID ]
|
||||
redirectURL:redirectURI
|
||||
responseType:OIDResponseTypeCode
|
||||
additionalParameters:nil];
|
||||
// performs authentication request
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
_redirectHTTPHandler.currentAuthorizationFlow =
|
||||
[OIDAuthState authStateByPresentingAuthorizationRequest:request
|
||||
callback:^(OIDAuthState *_Nullable authState,
|
||||
NSError *_Nullable error) {
|
||||
// Brings this app to the foreground.
|
||||
[[NSRunningApplication currentApplication]
|
||||
activateWithOptions:(NSApplicationActivateAllWindows |
|
||||
NSApplicationActivateIgnoringOtherApps)];
|
||||
|
||||
// Processes the authorization response.
|
||||
if (authState) {
|
||||
NSLog(@"Got authorization tokens. Access token: %@",
|
||||
authState.lastTokenResponse.accessToken);
|
||||
} else {
|
||||
NSLog(@"Authorization error: %@", error.localizedDescription);
|
||||
}
|
||||
[weakSelf setAuthState:authState];
|
||||
}];
|
||||
```
|
||||
|
||||
### Making API Calls
|
||||
|
||||
AppAuth gives you the raw token information, if you need it. However, we
|
||||
recommend that users of the `OIDAuthState` convenience wrapper use the provided
|
||||
`performActionWithFreshTokens:` method to perform their API calls to avoid
|
||||
needing to worry about token freshness:
|
||||
|
||||
<sub>Objective-C</sub>
|
||||
```objc
|
||||
[_authState performActionWithFreshTokens:^(NSString *_Nonnull accessToken,
|
||||
NSString *_Nonnull idToken,
|
||||
NSError *_Nullable error) {
|
||||
if (error) {
|
||||
NSLog(@"Error fetching fresh tokens: %@", [error localizedDescription]);
|
||||
return;
|
||||
}
|
||||
|
||||
// perform your API request using the tokens
|
||||
}];
|
||||
```
|
||||
|
||||
<sub>Swift</sub>
|
||||
```swift
|
||||
let userinfoEndpoint = URL(string:"https://openidconnect.googleapis.com/v1/userinfo")!
|
||||
self.authState?.performAction() { (accessToken, idToken, error) in
|
||||
|
||||
if error != nil {
|
||||
print("Error fetching fresh tokens: \(error?.localizedDescription ?? "Unknown error")")
|
||||
return
|
||||
}
|
||||
guard let accessToken = accessToken else {
|
||||
return
|
||||
}
|
||||
|
||||
// Add Bearer token to request
|
||||
var urlRequest = URLRequest(url: userinfoEndpoint)
|
||||
urlRequest.allHTTPHeaderFields = ["Authorization": "Bearer \(accessToken)"]
|
||||
|
||||
// Perform request...
|
||||
}
|
||||
```
|
||||
|
||||
### Custom User-Agents
|
||||
|
||||
Each OAuth flow involves presenting an external user-agent to the user, that
|
||||
allows them to interact with the OAuth authorization server. Typical examples
|
||||
of a user-agent are the user's browser, or an in-app browser tab incarnation
|
||||
like `ASWebAuthenticationSession` on iOS.
|
||||
|
||||
AppAuth ships with several implementations of an external user-agent out of the
|
||||
box, including defaults for iOS and macOS suitable for most cases. The default
|
||||
user-agents typically share persistent cookies with the system default browser,
|
||||
to improve the chance that the user doesn't need to sign-in all over again.
|
||||
|
||||
It is possible to change the user-agent that AppAuth uses, and even write your
|
||||
own - all without needing to fork the library.
|
||||
|
||||
All implementations of the external user-agent, be they included or created by
|
||||
you need to conform to the
|
||||
[`OIDExternalUserAgent`](http://openid.github.io/AppAuth-iOS/docs/latest/protocol_o_i_d_external_user_agent-p.html)
|
||||
protocol.
|
||||
|
||||
Instances of the `OIDExternalUserAgent`are passed into
|
||||
[`OIDAuthState.authStateByPresentingAuthorizationRequest:externalUserAgent:callback`](http://openid.github.io/AppAuth-iOS/docs/latest/interface_o_i_d_auth_state.html#ac762fe2bf95c116f0b437419be211fa1)
|
||||
and/or
|
||||
[`OIDAuthorizationService.presentAuthorizationRequest:externalUserAgent:callback:`](http://openid.github.io/AppAuth-iOS/docs/latest/interface_o_i_d_authorization_service.html#ae551f8e6887366a46e49b09b37389b8f)
|
||||
rather than using the platform-specific convenience methods (which use the
|
||||
default user-agents for their respective platforms), like
|
||||
[`OIDAuthState.authStateByPresentingAuthorizationRequest:presentingViewController:callback:`](http://openid.github.io/AppAuth-iOS/docs/latest/category_o_i_d_auth_state_07_i_o_s_08.html#ae32fd0732cd3192cd5219f2655a4c85c).
|
||||
|
||||
Popular use-cases for writing your own user-agent implementation include needing
|
||||
to style the user-agent in ways not supported by AppAuth, and implementing a
|
||||
fully custom flow with your own business logic. You can take one of the existing
|
||||
implementations as a starting point to copy, rename, and customize to your
|
||||
needs.
|
||||
|
||||
#### Custom Browser User-Agent
|
||||
|
||||
AppAuth for iOS includes a few extra user-agent implementations which you can
|
||||
try, or use as a reference for your own implementation. One of them,
|
||||
[`OIDExternalUserAgentIOSCustomBrowser`](http://openid.github.io/AppAuth-iOS/docs/latest/interface_o_i_d_external_user_agent_i_o_s_custom_browser.html)
|
||||
enables you to use a different browser for authentication, like Chrome for iOS
|
||||
or Firefox for iOS.
|
||||
|
||||
Here's how to configure AppAuth to use a custom browser using the
|
||||
`OIDExternalUserAgentIOSCustomBrowser` user agent:
|
||||
|
||||
First, add the following array to your
|
||||
[Info.plist](https://github.com/openid/AppAuth-iOS/blob/135f99d2cb4e9d18d310ac2588b905e612461561/Examples/Example-iOS_ObjC/Source/Info.plist#L34)
|
||||
(in XCode, right click -> Open As -> Source Code)
|
||||
|
||||
```
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>googlechromes</string>
|
||||
<string>opera-https</string>
|
||||
<string>firefox</string>
|
||||
</array>
|
||||
```
|
||||
|
||||
This is required so that AppAuth can test for the browser and open the app store
|
||||
if it's not installed (the default behavior of this user-agent). You only need
|
||||
to include the URL scheme of the actual browser you intend to use.
|
||||
|
||||
<sub>Objective-C</sub>
|
||||
```objc
|
||||
// performs authentication request
|
||||
AppDelegate *appDelegate =
|
||||
(AppDelegate *)[UIApplication sharedApplication].delegate;
|
||||
id<OIDExternalUserAgent> userAgent =
|
||||
[OIDExternalUserAgentIOSCustomBrowser CustomBrowserChrome];
|
||||
appDelegate.currentAuthorizationFlow =
|
||||
[OIDAuthState authStateByPresentingAuthorizationRequest:request
|
||||
externalUserAgent:self
|
||||
callback:^(OIDAuthState *_Nullable authState,
|
||||
NSError *_Nullable error) {
|
||||
if (authState) {
|
||||
NSLog(@"Got authorization tokens. Access token: %@",
|
||||
authState.lastTokenResponse.accessToken);
|
||||
[self setAuthState:authState];
|
||||
} else {
|
||||
NSLog(@"Authorization error: %@", [error localizedDescription]);
|
||||
[self setAuthState:nil];
|
||||
}
|
||||
}];
|
||||
```
|
||||
|
||||
That's it! With those two changes (which you can try on the included sample),
|
||||
AppAuth will use Chrome iOS for the authorization request (and open Chrome in
|
||||
the App Store if it's not installed).
|
||||
|
||||
⚠️**Note: the `OIDExternalUserAgentIOSCustomBrowser` user-agent is not intended for consumer apps**. It is designed for
|
||||
advanced enterprise use-cases where the app developers have greater control over
|
||||
the operating environment and have special requirements that require a custom
|
||||
browser like Chrome.
|
||||
|
||||
You don't need to stop with the included external user agents either! Since the
|
||||
[`OIDExternalUserAgent`](http://openid.github.io/AppAuth-iOS/docs/latest/protocol_o_i_d_external_user_agent-p.html)
|
||||
protocol is part of AppAuth's public API, you can implement your own versions of
|
||||
it. In the above example,
|
||||
`userAgent = [OIDExternalUserAgentIOSCustomBrowser CustomBrowserChrome]` would
|
||||
be replaced with an instantiation of your user-agent implementation.
|
||||
|
||||
## API Documentation
|
||||
|
||||
Browse the [API documentation](http://openid.github.io/AppAuth-iOS/docs/latest/annotated.html).
|
||||
|
||||
## Included Samples
|
||||
|
||||
Sample apps that explore core AppAuth features are available for iOS and macOS; follow the instructions in [Examples/README.md](Examples/README.md) to get started.
|
||||
Generated
-92
@@ -1,92 +0,0 @@
|
||||
/*! @file AppAuth.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDAuthState.h"
|
||||
#import "OIDAuthStateChangeDelegate.h"
|
||||
#import "OIDAuthStateErrorDelegate.h"
|
||||
#import "OIDAuthorizationRequest.h"
|
||||
#import "OIDAuthorizationResponse.h"
|
||||
#import "OIDAuthorizationService.h"
|
||||
#import "OIDError.h"
|
||||
#import "OIDErrorUtilities.h"
|
||||
#import "OIDExternalUserAgent.h"
|
||||
#import "OIDExternalUserAgentRequest.h"
|
||||
#import "OIDExternalUserAgentSession.h"
|
||||
#import "OIDGrantTypes.h"
|
||||
#import "OIDIDToken.h"
|
||||
#import "OIDRegistrationRequest.h"
|
||||
#import "OIDRegistrationResponse.h"
|
||||
#import "OIDResponseTypes.h"
|
||||
#import "OIDScopes.h"
|
||||
#import "OIDScopeUtilities.h"
|
||||
#import "OIDServiceConfiguration.h"
|
||||
#import "OIDServiceDiscovery.h"
|
||||
#import "OIDTokenRequest.h"
|
||||
#import "OIDTokenResponse.h"
|
||||
#import "OIDTokenUtilities.h"
|
||||
#import "OIDURLSessionProvider.h"
|
||||
#import "OIDEndSessionRequest.h"
|
||||
#import "OIDEndSessionResponse.h"
|
||||
|
||||
#if TARGET_OS_TV
|
||||
#elif TARGET_OS_WATCH
|
||||
#elif TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
#import "OIDAuthState+IOS.h"
|
||||
#import "OIDAuthorizationService+IOS.h"
|
||||
#import "OIDExternalUserAgentIOS.h"
|
||||
#import "OIDExternalUserAgentIOSCustomBrowser.h"
|
||||
#import "OIDExternalUserAgentCatalyst.h"
|
||||
#elif TARGET_OS_MAC
|
||||
#import "OIDAuthState+Mac.h"
|
||||
#import "OIDAuthorizationService+Mac.h"
|
||||
#import "OIDExternalUserAgentMac.h"
|
||||
#import "OIDRedirectHTTPHandler.h"
|
||||
#else
|
||||
#error "Platform Undefined"
|
||||
#endif
|
||||
|
||||
/*! @mainpage AppAuth for iOS and macOS
|
||||
|
||||
@section introduction Introduction
|
||||
|
||||
AppAuth for iOS and macOS is a client SDK for communicating with [OAuth 2.0]
|
||||
(https://tools.ietf.org/html/rfc6749) and [OpenID Connect]
|
||||
(http://openid.net/specs/openid-connect-core-1_0.html) providers. It strives to
|
||||
directly map the requests and responses of those specifications, while following
|
||||
the idiomatic style of the implementation language. In addition to mapping the
|
||||
raw protocol flows, convenience methods are available to assist with common
|
||||
tasks like performing an action with fresh tokens.
|
||||
|
||||
It follows the best practices set out in
|
||||
[RFC 8252 - OAuth 2.0 for Native Apps](https://tools.ietf.org/html/rfc8252)
|
||||
including using `SFAuthenticationSession` and `SFSafariViewController` on iOS
|
||||
for the auth request. Web view and `WKWebView` are explicitly *not*
|
||||
supported due to the security and usability reasons explained in
|
||||
[Section 8.12 of RFC 8252](https://tools.ietf.org/html/rfc8252#section-8.12).
|
||||
|
||||
It also supports the [PKCE](https://tools.ietf.org/html/rfc7636) extension to
|
||||
OAuth which was created to secure authorization codes in public clients when
|
||||
custom URI scheme redirects are used. The library is friendly to other
|
||||
extensions (standard or otherwise) with the ability to handle additional params
|
||||
in all protocol requests and responses.
|
||||
|
||||
<b>Homepage</b>: http://openid.github.io/AppAuth-iOS/ <br>
|
||||
<b>API Documentation</b>: http://openid.github.io/AppAuth-iOS/docs/latest <br>
|
||||
<b>Git Repository</b>: https://github.com/openid/AppAuth-iOS <br>
|
||||
|
||||
*/
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
/*! @file OIDAuthState+IOS.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "OIDAuthState.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief iOS specific convenience methods for @c OIDAuthState.
|
||||
*/
|
||||
@interface OIDAuthState (IOS)
|
||||
|
||||
/*! @brief Convenience method to create a @c OIDAuthState by presenting an authorization request
|
||||
and performing the authorization code exchange in the case of code flow requests. For
|
||||
the hybrid flow, the caller should validate the id_token and c_hash, then perform the token
|
||||
request (@c OIDAuthorizationService.performTokenRequest:callback:)
|
||||
and update the OIDAuthState with the results (@c
|
||||
OIDAuthState.updateWithTokenResponse:error:).
|
||||
@param authorizationRequest The authorization request to present.
|
||||
@param presentingViewController The view controller from which to present the
|
||||
@c SFSafariViewController. On iOS 13, the window of this UIViewController
|
||||
is used as the ASPresentationAnchor.
|
||||
@param callback The method called when the request has completed or failed.
|
||||
@return A @c OIDExternalUserAgentSession instance which will terminate when it
|
||||
receives a @c OIDExternalUserAgentSession.cancel message, or after processing a
|
||||
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message.
|
||||
*/
|
||||
+ (id<OIDExternalUserAgentSession>)
|
||||
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
|
||||
presentingViewController:(UIViewController *)presentingViewController
|
||||
callback:(OIDAuthStateAuthorizationCallback)callback;
|
||||
|
||||
+ (id<OIDExternalUserAgentSession>)
|
||||
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
|
||||
callback:(OIDAuthStateAuthorizationCallback)callback API_AVAILABLE(ios(11)) API_UNAVAILABLE(macCatalyst)
|
||||
__deprecated_msg("This method will not work on iOS 13. Use "
|
||||
"authStateByPresentingAuthorizationRequest:presentingViewController:callback:");
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
/*! @file OIDAuthState+IOS.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
|
||||
#import "OIDAuthState+IOS.h"
|
||||
#import "OIDExternalUserAgentIOS.h"
|
||||
#import "OIDExternalUserAgentCatalyst.h"
|
||||
|
||||
@implementation OIDAuthState (IOS)
|
||||
|
||||
+ (id<OIDExternalUserAgentSession>)
|
||||
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
|
||||
presentingViewController:(UIViewController *)presentingViewController
|
||||
callback:(OIDAuthStateAuthorizationCallback)callback {
|
||||
id<OIDExternalUserAgent> externalUserAgent;
|
||||
#if TARGET_OS_MACCATALYST
|
||||
externalUserAgent = [[OIDExternalUserAgentCatalyst alloc]
|
||||
initWithPresentingViewController:presentingViewController];
|
||||
#else // TARGET_OS_MACCATALYST
|
||||
externalUserAgent = [[OIDExternalUserAgentIOS alloc] initWithPresentingViewController:presentingViewController];
|
||||
#endif // TARGET_OS_MACCATALYST
|
||||
return [self authStateByPresentingAuthorizationRequest:authorizationRequest
|
||||
externalUserAgent:externalUserAgent
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
#if !TARGET_OS_MACCATALYST
|
||||
+ (id<OIDExternalUserAgentSession>)
|
||||
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
|
||||
callback:(OIDAuthStateAuthorizationCallback)callback {
|
||||
OIDExternalUserAgentIOS *externalUserAgent = [[OIDExternalUserAgentIOS alloc] init];
|
||||
return [self authStateByPresentingAuthorizationRequest:authorizationRequest
|
||||
externalUserAgent:externalUserAgent
|
||||
callback:callback];
|
||||
}
|
||||
#endif // !TARGET_OS_MACCATALYST
|
||||
|
||||
@end
|
||||
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
@@ -1,50 +0,0 @@
|
||||
/*! @file OIDAuthorizationService+IOS.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "OIDAuthorizationService.h"
|
||||
#import "OIDExternalUserAgentSession.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Provides iOS specific authorization request handling.
|
||||
*/
|
||||
@interface OIDAuthorizationService (IOS)
|
||||
|
||||
/*! @brief Perform an authorization flow using \SFSafariViewController.
|
||||
@param request The authorization request.
|
||||
@param presentingViewController The view controller from which to present the
|
||||
\SFSafariViewController.
|
||||
@param callback The method called when the request has completed or failed.
|
||||
@return A @c OIDExternalUserAgentSession instance which will terminate when it
|
||||
receives a @c OIDExternalUserAgentSession.cancel message, or after processing a
|
||||
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message.
|
||||
*/
|
||||
+ (id<OIDExternalUserAgentSession>) presentAuthorizationRequest:(OIDAuthorizationRequest *)request
|
||||
presentingViewController:(UIViewController *)presentingViewController
|
||||
callback:(OIDAuthorizationCallback)callback;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
@@ -1,48 +0,0 @@
|
||||
/*! @file OIDAuthorizationService+IOS.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
|
||||
#import "OIDAuthorizationService+IOS.h"
|
||||
#import "OIDExternalUserAgentIOS.h"
|
||||
#import "OIDExternalUserAgentCatalyst.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation OIDAuthorizationService (IOS)
|
||||
|
||||
+ (id<OIDExternalUserAgentSession>) presentAuthorizationRequest:(OIDAuthorizationRequest *)request
|
||||
presentingViewController:(UIViewController *)presentingViewController
|
||||
callback:(OIDAuthorizationCallback)callback {
|
||||
id<OIDExternalUserAgent> externalUserAgent;
|
||||
#if TARGET_OS_MACCATALYST
|
||||
externalUserAgent = [[OIDExternalUserAgentCatalyst alloc]
|
||||
initWithPresentingViewController:presentingViewController];
|
||||
#else // TARGET_OS_MACCATALYST
|
||||
externalUserAgent = [[OIDExternalUserAgentIOS alloc] initWithPresentingViewController:presentingViewController];
|
||||
#endif // TARGET_OS_MACCATALYST
|
||||
return [self presentAuthorizationRequest:request externalUserAgent:externalUserAgent callback:callback];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
@@ -1,52 +0,0 @@
|
||||
/*! @file OIDExternalUserAgentCatalyst.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2019 The AppAuth Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "OIDExternalUserAgent.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief A Catalyst specific external user-agent that uses `ASWebAuthenticationSession` to
|
||||
present the request.
|
||||
*/
|
||||
API_AVAILABLE(macCatalyst(13)) API_UNAVAILABLE(ios)
|
||||
@interface OIDExternalUserAgentCatalyst : NSObject<OIDExternalUserAgent>
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use @c initWithPresentingViewController:
|
||||
*/
|
||||
- (nonnull instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief The designated initializer.
|
||||
@param presentingViewController The view controller from which to present the
|
||||
\SFSafariViewController.
|
||||
*/
|
||||
- (nullable instancetype)initWithPresentingViewController:
|
||||
(UIViewController *)presentingViewController
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
@@ -1,145 +0,0 @@
|
||||
/*! @file OIDExternalUserAgentCatalyst.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2019 The AppAuth Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
|
||||
#import "OIDExternalUserAgentCatalyst.h"
|
||||
|
||||
#import <SafariServices/SafariServices.h>
|
||||
#import <AuthenticationServices/AuthenticationServices.h>
|
||||
|
||||
#import "OIDErrorUtilities.h"
|
||||
#import "OIDExternalUserAgentSession.h"
|
||||
#import "OIDExternalUserAgentRequest.h"
|
||||
|
||||
#if TARGET_OS_MACCATALYST
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OIDExternalUserAgentCatalyst ()<ASWebAuthenticationPresentationContextProviding>
|
||||
@end
|
||||
|
||||
@implementation OIDExternalUserAgentCatalyst {
|
||||
UIViewController *_presentingViewController;
|
||||
|
||||
BOOL _externalUserAgentFlowInProgress;
|
||||
__weak id<OIDExternalUserAgentSession> _session;
|
||||
ASWebAuthenticationSession *_webAuthenticationVC;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithPresentingViewController:
|
||||
(UIViewController *)presentingViewController {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_presentingViewController = presentingViewController;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)presentExternalUserAgentRequest:(id<OIDExternalUserAgentRequest>)request
|
||||
session:(id<OIDExternalUserAgentSession>)session {
|
||||
if (_externalUserAgentFlowInProgress) {
|
||||
// TODO: Handle errors as authorization is already in progress.
|
||||
return NO;
|
||||
}
|
||||
|
||||
_externalUserAgentFlowInProgress = YES;
|
||||
_session = session;
|
||||
BOOL openedUserAgent = NO;
|
||||
NSURL *requestURL = [request externalUserAgentRequestURL];
|
||||
|
||||
__weak OIDExternalUserAgentCatalyst *weakSelf = self;
|
||||
NSString *redirectScheme = request.redirectScheme;
|
||||
ASWebAuthenticationSession *authenticationVC =
|
||||
[[ASWebAuthenticationSession alloc] initWithURL:requestURL
|
||||
callbackURLScheme:redirectScheme
|
||||
completionHandler:^(NSURL * _Nullable callbackURL,
|
||||
NSError * _Nullable error) {
|
||||
__strong OIDExternalUserAgentCatalyst *strongSelf = weakSelf;
|
||||
if (!strongSelf) {
|
||||
return;
|
||||
}
|
||||
strongSelf->_webAuthenticationVC = nil;
|
||||
if (callbackURL) {
|
||||
[strongSelf->_session resumeExternalUserAgentFlowWithURL:callbackURL];
|
||||
} else {
|
||||
NSError *safariError =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
|
||||
underlyingError:error
|
||||
description:nil];
|
||||
[strongSelf->_session failExternalUserAgentFlowWithError:safariError];
|
||||
}
|
||||
}];
|
||||
|
||||
authenticationVC.presentationContextProvider = self;
|
||||
_webAuthenticationVC = authenticationVC;
|
||||
openedUserAgent = [authenticationVC start];
|
||||
|
||||
if (!openedUserAgent) {
|
||||
[self cleanUp];
|
||||
NSError *safariError = [OIDErrorUtilities errorWithCode:OIDErrorCodeSafariOpenError
|
||||
underlyingError:nil
|
||||
description:@"Unable to open ASWebAuthenticationSession view controller."];
|
||||
[session failExternalUserAgentFlowWithError:safariError];
|
||||
}
|
||||
return openedUserAgent;
|
||||
}
|
||||
|
||||
- (void)dismissExternalUserAgentAnimated:(BOOL)animated completion:(void (^)(void))completion {
|
||||
if (!_externalUserAgentFlowInProgress) {
|
||||
// Ignore this call if there is no authorization flow in progress.
|
||||
if (completion) completion();
|
||||
return;
|
||||
}
|
||||
|
||||
ASWebAuthenticationSession *webAuthenticationVC = _webAuthenticationVC;
|
||||
|
||||
[self cleanUp];
|
||||
|
||||
if (webAuthenticationVC) {
|
||||
// dismiss the ASWebAuthenticationSession
|
||||
[webAuthenticationVC cancel];
|
||||
if (completion) completion();
|
||||
} else {
|
||||
if (completion) completion();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cleanUp {
|
||||
// The weak reference to |_session| is set to nil to avoid accidentally using
|
||||
// it while not in an authorization flow.
|
||||
_webAuthenticationVC = nil;
|
||||
_session = nil;
|
||||
_externalUserAgentFlowInProgress = NO;
|
||||
}
|
||||
|
||||
#pragma mark - ASWebAuthenticationPresentationContextProviding
|
||||
|
||||
- (ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session {
|
||||
return _presentingViewController.view.window;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // TARGET_OS_MACCATALYST
|
||||
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
@@ -1,53 +0,0 @@
|
||||
/*! @file OIDExternalUserAgentIOS.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "OIDExternalUserAgent.h"
|
||||
|
||||
@class SFSafariViewController;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief An iOS specific external user-agent that uses the best possible user-agent available
|
||||
depending on the version of iOS to present the request.
|
||||
*/
|
||||
API_UNAVAILABLE(macCatalyst)
|
||||
@interface OIDExternalUserAgentIOS : NSObject<OIDExternalUserAgent>
|
||||
|
||||
- (nullable instancetype)init API_AVAILABLE(ios(11))
|
||||
__deprecated_msg("This method will not work on iOS 13, use "
|
||||
"initWithPresentingViewController:presentingViewController");
|
||||
|
||||
/*! @brief The designated initializer.
|
||||
@param presentingViewController The view controller from which to present the
|
||||
\SFSafariViewController.
|
||||
*/
|
||||
- (nullable instancetype)initWithPresentingViewController:
|
||||
(UIViewController *)presentingViewController
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
@@ -1,256 +0,0 @@
|
||||
/*! @file OIDExternalUserAgentIOS.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
|
||||
#import "OIDExternalUserAgentIOS.h"
|
||||
|
||||
#import <SafariServices/SafariServices.h>
|
||||
#import <AuthenticationServices/AuthenticationServices.h>
|
||||
|
||||
#import "OIDErrorUtilities.h"
|
||||
#import "OIDExternalUserAgentSession.h"
|
||||
#import "OIDExternalUserAgentRequest.h"
|
||||
|
||||
#if !TARGET_OS_MACCATALYST
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
|
||||
@interface OIDExternalUserAgentIOS ()<SFSafariViewControllerDelegate, ASWebAuthenticationPresentationContextProviding>
|
||||
@end
|
||||
#else
|
||||
@interface OIDExternalUserAgentIOS ()<SFSafariViewControllerDelegate>
|
||||
@end
|
||||
#endif
|
||||
|
||||
@implementation OIDExternalUserAgentIOS {
|
||||
UIViewController *_presentingViewController;
|
||||
|
||||
BOOL _externalUserAgentFlowInProgress;
|
||||
__weak id<OIDExternalUserAgentSession> _session;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
__weak SFSafariViewController *_safariVC;
|
||||
SFAuthenticationSession *_authenticationVC;
|
||||
ASWebAuthenticationSession *_webAuthenticationVC;
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
- (nullable instancetype)init {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnonnull"
|
||||
return [self initWithPresentingViewController:nil];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithPresentingViewController:
|
||||
(UIViewController *)presentingViewController {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
|
||||
NSAssert(presentingViewController != nil,
|
||||
@"presentingViewController cannot be nil on iOS 13");
|
||||
#endif // __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
|
||||
|
||||
_presentingViewController = presentingViewController;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)presentExternalUserAgentRequest:(id<OIDExternalUserAgentRequest>)request
|
||||
session:(id<OIDExternalUserAgentSession>)session {
|
||||
if (_externalUserAgentFlowInProgress) {
|
||||
// TODO: Handle errors as authorization is already in progress.
|
||||
return NO;
|
||||
}
|
||||
|
||||
_externalUserAgentFlowInProgress = YES;
|
||||
_session = session;
|
||||
BOOL openedUserAgent = NO;
|
||||
NSURL *requestURL = [request externalUserAgentRequestURL];
|
||||
|
||||
// iOS 12 and later, use ASWebAuthenticationSession
|
||||
if (@available(iOS 12.0, *)) {
|
||||
// ASWebAuthenticationSession doesn't work with guided access (rdar://40809553)
|
||||
if (!UIAccessibilityIsGuidedAccessEnabled()) {
|
||||
__weak OIDExternalUserAgentIOS *weakSelf = self;
|
||||
NSString *redirectScheme = request.redirectScheme;
|
||||
ASWebAuthenticationSession *authenticationVC =
|
||||
[[ASWebAuthenticationSession alloc] initWithURL:requestURL
|
||||
callbackURLScheme:redirectScheme
|
||||
completionHandler:^(NSURL * _Nullable callbackURL,
|
||||
NSError * _Nullable error) {
|
||||
__strong OIDExternalUserAgentIOS *strongSelf = weakSelf;
|
||||
if (!strongSelf) {
|
||||
return;
|
||||
}
|
||||
strongSelf->_webAuthenticationVC = nil;
|
||||
if (callbackURL) {
|
||||
[strongSelf->_session resumeExternalUserAgentFlowWithURL:callbackURL];
|
||||
} else {
|
||||
NSError *safariError =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
|
||||
underlyingError:error
|
||||
description:nil];
|
||||
[strongSelf->_session failExternalUserAgentFlowWithError:safariError];
|
||||
}
|
||||
}];
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
|
||||
if (@available(iOS 13.0, *)) {
|
||||
authenticationVC.presentationContextProvider = self;
|
||||
}
|
||||
#endif
|
||||
_webAuthenticationVC = authenticationVC;
|
||||
openedUserAgent = [authenticationVC start];
|
||||
}
|
||||
}
|
||||
// iOS 11, use SFAuthenticationSession
|
||||
if (@available(iOS 11.0, *)) {
|
||||
// SFAuthenticationSession doesn't work with guided access (rdar://40809553)
|
||||
if (!openedUserAgent && !UIAccessibilityIsGuidedAccessEnabled()) {
|
||||
__weak OIDExternalUserAgentIOS *weakSelf = self;
|
||||
NSString *redirectScheme = request.redirectScheme;
|
||||
SFAuthenticationSession *authenticationVC =
|
||||
[[SFAuthenticationSession alloc] initWithURL:requestURL
|
||||
callbackURLScheme:redirectScheme
|
||||
completionHandler:^(NSURL * _Nullable callbackURL,
|
||||
NSError * _Nullable error) {
|
||||
__strong OIDExternalUserAgentIOS *strongSelf = weakSelf;
|
||||
if (!strongSelf) {
|
||||
return;
|
||||
}
|
||||
strongSelf->_authenticationVC = nil;
|
||||
if (callbackURL) {
|
||||
[strongSelf->_session resumeExternalUserAgentFlowWithURL:callbackURL];
|
||||
} else {
|
||||
NSError *safariError =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
|
||||
underlyingError:error
|
||||
description:@"User cancelled."];
|
||||
[strongSelf->_session failExternalUserAgentFlowWithError:safariError];
|
||||
}
|
||||
}];
|
||||
_authenticationVC = authenticationVC;
|
||||
openedUserAgent = [authenticationVC start];
|
||||
}
|
||||
}
|
||||
// iOS 9 and 10, use SFSafariViewController
|
||||
if (@available(iOS 9.0, *)) {
|
||||
if (!openedUserAgent && _presentingViewController) {
|
||||
SFSafariViewController *safariVC =
|
||||
[[SFSafariViewController alloc] initWithURL:requestURL];
|
||||
safariVC.delegate = self;
|
||||
_safariVC = safariVC;
|
||||
[_presentingViewController presentViewController:safariVC animated:YES completion:nil];
|
||||
openedUserAgent = YES;
|
||||
}
|
||||
}
|
||||
// iOS 8 and earlier, use mobile Safari
|
||||
if (!openedUserAgent){
|
||||
openedUserAgent = [[UIApplication sharedApplication] openURL:requestURL];
|
||||
}
|
||||
|
||||
if (!openedUserAgent) {
|
||||
[self cleanUp];
|
||||
NSError *safariError = [OIDErrorUtilities errorWithCode:OIDErrorCodeSafariOpenError
|
||||
underlyingError:nil
|
||||
description:@"Unable to open Safari."];
|
||||
[session failExternalUserAgentFlowWithError:safariError];
|
||||
}
|
||||
return openedUserAgent;
|
||||
}
|
||||
|
||||
- (void)dismissExternalUserAgentAnimated:(BOOL)animated completion:(void (^)(void))completion {
|
||||
if (!_externalUserAgentFlowInProgress) {
|
||||
// Ignore this call if there is no authorization flow in progress.
|
||||
if (completion) completion();
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpartial-availability"
|
||||
SFSafariViewController *safariVC = _safariVC;
|
||||
SFAuthenticationSession *authenticationVC = _authenticationVC;
|
||||
ASWebAuthenticationSession *webAuthenticationVC = _webAuthenticationVC;
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
[self cleanUp];
|
||||
|
||||
if (webAuthenticationVC) {
|
||||
// dismiss the ASWebAuthenticationSession
|
||||
[webAuthenticationVC cancel];
|
||||
if (completion) completion();
|
||||
} else if (authenticationVC) {
|
||||
// dismiss the SFAuthenticationSession
|
||||
[authenticationVC cancel];
|
||||
if (completion) completion();
|
||||
} else if (safariVC) {
|
||||
// dismiss the SFSafariViewController
|
||||
[safariVC dismissViewControllerAnimated:YES completion:completion];
|
||||
} else {
|
||||
if (completion) completion();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cleanUp {
|
||||
// The weak references to |_safariVC| and |_session| are set to nil to avoid accidentally using
|
||||
// them while not in an authorization flow.
|
||||
_safariVC = nil;
|
||||
_authenticationVC = nil;
|
||||
_webAuthenticationVC = nil;
|
||||
_session = nil;
|
||||
_externalUserAgentFlowInProgress = NO;
|
||||
}
|
||||
|
||||
#pragma mark - SFSafariViewControllerDelegate
|
||||
|
||||
- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller NS_AVAILABLE_IOS(9.0) {
|
||||
if (controller != _safariVC) {
|
||||
// Ignore this call if the safari view controller do not match.
|
||||
return;
|
||||
}
|
||||
if (!_externalUserAgentFlowInProgress) {
|
||||
// Ignore this call if there is no authorization flow in progress.
|
||||
return;
|
||||
}
|
||||
id<OIDExternalUserAgentSession> session = _session;
|
||||
[self cleanUp];
|
||||
NSError *error = [OIDErrorUtilities errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
|
||||
underlyingError:nil
|
||||
description:@"No external user agent flow in progress."];
|
||||
[session failExternalUserAgentFlowWithError:error];
|
||||
}
|
||||
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
|
||||
#pragma mark - ASWebAuthenticationPresentationContextProviding
|
||||
|
||||
- (ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session API_AVAILABLE(ios(13.0)){
|
||||
return _presentingViewController.view.window;
|
||||
}
|
||||
#endif // __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // !TARGET_OS_MACCATALYST
|
||||
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
@@ -1,113 +0,0 @@
|
||||
/*! @file OIDExternalUserAgentIOSCustomBrowser.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2018 Google LLC
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "OIDExternalUserAgent.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief A block that transforms a regular http/https URL into one that will open in an
|
||||
alternative browser.
|
||||
@param requestURL the http/https request URL to be transformed.
|
||||
@return transformed URL.
|
||||
*/
|
||||
typedef NSURL *_Nullable (^OIDCustomBrowserURLTransformation)(NSURL *_Nullable requestURL);
|
||||
|
||||
/*! @brief An implementation of the OIDExternalUserAgent protocol for iOS that uses
|
||||
a custom browser (i.e. not Safari) for external requests. It is suitable for browsers that
|
||||
offer a custom url scheme that simply replaces the "https" scheme. It is not designed
|
||||
for browsers that require other modifications to the URL. If the browser is not installed
|
||||
the user will be prompted to install it.
|
||||
*/
|
||||
API_UNAVAILABLE(macCatalyst)
|
||||
@interface OIDExternalUserAgentIOSCustomBrowser : NSObject<OIDExternalUserAgent>
|
||||
|
||||
/*! @brief URL transformation block for the browser.
|
||||
*/
|
||||
@property(nonatomic, readonly) OIDCustomBrowserURLTransformation URLTransformation;
|
||||
|
||||
/*! @brief URL Scheme used to test for whether the browser is installed.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *canOpenURLScheme;
|
||||
|
||||
/*! @brief URL of the browser's App Store listing.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *appStoreURL;
|
||||
|
||||
/*! @brief An instance of @c OIDExternalUserAgentIOSCustomBrowser for Chrome.
|
||||
*/
|
||||
+ (instancetype)CustomBrowserChrome;
|
||||
|
||||
/*! @brief An instance of @c OIDExternalUserAgentIOSCustomBrowser for Firefox.
|
||||
*/
|
||||
+ (instancetype)CustomBrowserFirefox;
|
||||
|
||||
/*! @brief An instance of @c OIDExternalUserAgentIOSCustomBrowser for Opera.
|
||||
*/
|
||||
+ (instancetype)CustomBrowserOpera;
|
||||
|
||||
/*! @brief An instance of @c OIDExternalUserAgentIOSCustomBrowser for Safari.
|
||||
*/
|
||||
+ (instancetype)CustomBrowserSafari;
|
||||
|
||||
/*! @brief Creates a @c OIDCustomBrowserURLTransformation using the scheme substitution method used
|
||||
iOS browsers like Chrome and Firefox.
|
||||
*/
|
||||
+ (OIDCustomBrowserURLTransformation)
|
||||
URLTransformationSchemeSubstitutionHTTPS:(NSString *)browserSchemeHTTPS
|
||||
HTTP:(nullable NSString *)browserSchemeHTTP;
|
||||
|
||||
/*! @brief Creates a @c OIDCustomBrowserURLTransformation with the URL prefix method used by
|
||||
iOS browsers like Firefox.
|
||||
*/
|
||||
+ (OIDCustomBrowserURLTransformation) URLTransformationSchemeConcatPrefix:(NSString*)URLprefix;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use @c initWithURLTransformation:canOpenURLScheme:appStoreURL:
|
||||
*/
|
||||
- (nonnull instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief OIDExternalUserAgent for a custom browser. @c presentExternalUserAgentRequest:session method
|
||||
will return NO if the browser isn't installed.
|
||||
*/
|
||||
- (nullable instancetype)initWithURLTransformation:(OIDCustomBrowserURLTransformation)URLTransformation;
|
||||
|
||||
/*! @brief The designated initializer.
|
||||
@param URLTransformation the transformation block to translate the URL into one that will open
|
||||
in the desired custom browser.
|
||||
@param canOpenURLScheme any scheme supported by the browser used to check if the browser is
|
||||
installed.
|
||||
@param appStoreURL URL of the browser in the app store. When this and @c canOpenURLScheme
|
||||
are non-nil, @c presentExternalUserAgentRequest:session will redirect the user to the app store
|
||||
if the browser is not installed.
|
||||
*/
|
||||
- (nullable instancetype)initWithURLTransformation:(OIDCustomBrowserURLTransformation)URLTransformation
|
||||
canOpenURLScheme:(nullable NSString *)canOpenURLScheme
|
||||
appStoreURL:(nullable NSURL *)appStoreURL
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
@@ -1,171 +0,0 @@
|
||||
/*! @file OIDExternalUserAgentIOSCustomBrowser.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2018 Google LLC
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
|
||||
#import "OIDExternalUserAgentIOSCustomBrowser.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "OIDAuthorizationRequest.h"
|
||||
#import "OIDAuthorizationService.h"
|
||||
#import "OIDErrorUtilities.h"
|
||||
#import "OIDURLQueryComponent.h"
|
||||
|
||||
#if !TARGET_OS_MACCATALYST
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation OIDExternalUserAgentIOSCustomBrowser
|
||||
|
||||
+ (instancetype)CustomBrowserChrome {
|
||||
// Chrome iOS documentation: https://developer.chrome.com/multidevice/ios/links
|
||||
OIDCustomBrowserURLTransformation transform = [[self class] URLTransformationSchemeSubstitutionHTTPS:@"googlechromes" HTTP:@"googlechrome"];
|
||||
NSURL *appStoreURL =
|
||||
[NSURL URLWithString:@"itms-apps://itunes.apple.com/us/app/chrome/id535886823"];
|
||||
return [[[self class] alloc] initWithURLTransformation:transform
|
||||
canOpenURLScheme:@"googlechromes"
|
||||
appStoreURL:appStoreURL];
|
||||
}
|
||||
|
||||
+ (instancetype)CustomBrowserFirefox {
|
||||
// Firefox iOS documentation: https://github.com/mozilla-mobile/firefox-ios-open-in-client
|
||||
OIDCustomBrowserURLTransformation transform =
|
||||
[[self class] URLTransformationSchemeConcatPrefix:@"firefox://open-url?url="];
|
||||
NSURL *appStoreURL =
|
||||
[NSURL URLWithString:@"itms-apps://itunes.apple.com/us/app/firefox-web-browser/id989804926"];
|
||||
return [[[self class] alloc] initWithURLTransformation:transform
|
||||
canOpenURLScheme:@"firefox"
|
||||
appStoreURL:appStoreURL];
|
||||
}
|
||||
|
||||
+ (instancetype)CustomBrowserOpera {
|
||||
OIDCustomBrowserURLTransformation transform =
|
||||
[[self class] URLTransformationSchemeSubstitutionHTTPS:@"opera-https" HTTP:@"opera-http"];
|
||||
NSURL *appStoreURL =
|
||||
[NSURL URLWithString:@"itms-apps://itunes.apple.com/us/app/opera-mini-web-browser/id363729560"];
|
||||
return [[[self class] alloc] initWithURLTransformation:transform
|
||||
canOpenURLScheme:@"opera-https"
|
||||
appStoreURL:appStoreURL];
|
||||
}
|
||||
|
||||
+ (instancetype)CustomBrowserSafari {
|
||||
OIDCustomBrowserURLTransformation transformNOP = ^NSURL *(NSURL *requestURL) {
|
||||
return requestURL;
|
||||
};
|
||||
OIDExternalUserAgentIOSCustomBrowser *transform =
|
||||
[[[self class] alloc] initWithURLTransformation:transformNOP];
|
||||
return transform;
|
||||
}
|
||||
|
||||
+ (OIDCustomBrowserURLTransformation)
|
||||
URLTransformationSchemeSubstitutionHTTPS:(NSString *)browserSchemeHTTPS
|
||||
HTTP:(nullable NSString *)browserSchemeHTTP {
|
||||
OIDCustomBrowserURLTransformation transform = ^NSURL *(NSURL *requestURL) {
|
||||
// Replace the URL Scheme with the Chrome equivalent.
|
||||
NSString *newScheme = nil;
|
||||
if ([requestURL.scheme isEqualToString:@"https"]) {
|
||||
newScheme = browserSchemeHTTPS;
|
||||
} else if ([requestURL.scheme isEqualToString:@"http"]) {
|
||||
if (!browserSchemeHTTP) {
|
||||
NSAssert(false, @"No HTTP scheme registered for browser");
|
||||
return nil;
|
||||
}
|
||||
newScheme = browserSchemeHTTP;
|
||||
}
|
||||
|
||||
// Replaces the URI scheme with the custom scheme
|
||||
NSURLComponents *components = [NSURLComponents componentsWithURL:requestURL
|
||||
resolvingAgainstBaseURL:YES];
|
||||
components.scheme = newScheme;
|
||||
return components.URL;
|
||||
};
|
||||
return transform;
|
||||
}
|
||||
|
||||
+ (OIDCustomBrowserURLTransformation)URLTransformationSchemeConcatPrefix:(NSString *)URLprefix {
|
||||
OIDCustomBrowserURLTransformation transform = ^NSURL *(NSURL *requestURL) {
|
||||
NSString *requestURLString = [requestURL absoluteString];
|
||||
NSMutableCharacterSet *allowedParamCharacters =
|
||||
[OIDURLQueryComponent URLParamValueAllowedCharacters];
|
||||
NSString *encodedUrl = [requestURLString stringByAddingPercentEncodingWithAllowedCharacters:allowedParamCharacters];
|
||||
NSString *newURL = [NSString stringWithFormat:@"%@%@", URLprefix, encodedUrl];
|
||||
return [NSURL URLWithString:newURL];
|
||||
};
|
||||
return transform;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithURLTransformation:
|
||||
(OIDCustomBrowserURLTransformation)URLTransformation {
|
||||
return [self initWithURLTransformation:URLTransformation canOpenURLScheme:nil appStoreURL:nil];
|
||||
}
|
||||
|
||||
- (nullable instancetype)
|
||||
initWithURLTransformation:(OIDCustomBrowserURLTransformation)URLTransformation
|
||||
canOpenURLScheme:(nullable NSString *)canOpenURLScheme
|
||||
appStoreURL:(nullable NSURL *)appStoreURL {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_URLTransformation = URLTransformation;
|
||||
_canOpenURLScheme = canOpenURLScheme;
|
||||
_appStoreURL = appStoreURL;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)presentExternalUserAgentRequest:(nonnull id<OIDExternalUserAgentRequest>)request
|
||||
session:(nonnull id<OIDExternalUserAgentSession>)session {
|
||||
// If the app store URL is set, checks if the app is installed and if not opens the app store.
|
||||
if (_appStoreURL && _canOpenURLScheme) {
|
||||
// Verifies existence of LSApplicationQueriesSchemes Info.plist key.
|
||||
NSArray __unused* canOpenURLs =
|
||||
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"LSApplicationQueriesSchemes"];
|
||||
NSAssert(canOpenURLs, @"plist missing LSApplicationQueriesSchemes key");
|
||||
NSAssert1([canOpenURLs containsObject:_canOpenURLScheme],
|
||||
@"plist missing LSApplicationQueriesSchemes entry for '%@'", _canOpenURLScheme);
|
||||
|
||||
// Opens AppStore if app isn't installed
|
||||
NSString *testURLString = [NSString stringWithFormat:@"%@://example.com", _canOpenURLScheme];
|
||||
NSURL *testURL = [NSURL URLWithString:testURLString];
|
||||
if (![[UIApplication sharedApplication] canOpenURL:testURL]) {
|
||||
[[UIApplication sharedApplication] openURL:_appStoreURL];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
// Transforms the request URL and opens it.
|
||||
NSURL *requestURL = [request externalUserAgentRequestURL];
|
||||
requestURL = _URLTransformation(requestURL);
|
||||
BOOL openedInBrowser = [[UIApplication sharedApplication] openURL:requestURL];
|
||||
return openedInBrowser;
|
||||
}
|
||||
|
||||
- (void)dismissExternalUserAgentAnimated:(BOOL)animated
|
||||
completion:(nonnull void (^)(void))completion {
|
||||
completion();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif // !TARGET_OS_MACCATALYST
|
||||
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST
|
||||
Generated
-44
@@ -1,44 +0,0 @@
|
||||
/*! @file AppAuthCore.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDAuthState.h"
|
||||
#import "OIDAuthStateChangeDelegate.h"
|
||||
#import "OIDAuthStateErrorDelegate.h"
|
||||
#import "OIDAuthorizationRequest.h"
|
||||
#import "OIDAuthorizationResponse.h"
|
||||
#import "OIDAuthorizationService.h"
|
||||
#import "OIDError.h"
|
||||
#import "OIDErrorUtilities.h"
|
||||
#import "OIDExternalUserAgent.h"
|
||||
#import "OIDExternalUserAgentRequest.h"
|
||||
#import "OIDExternalUserAgentSession.h"
|
||||
#import "OIDGrantTypes.h"
|
||||
#import "OIDIDToken.h"
|
||||
#import "OIDRegistrationRequest.h"
|
||||
#import "OIDRegistrationResponse.h"
|
||||
#import "OIDResponseTypes.h"
|
||||
#import "OIDScopes.h"
|
||||
#import "OIDScopeUtilities.h"
|
||||
#import "OIDServiceConfiguration.h"
|
||||
#import "OIDServiceDiscovery.h"
|
||||
#import "OIDTokenRequest.h"
|
||||
#import "OIDTokenResponse.h"
|
||||
#import "OIDTokenUtilities.h"
|
||||
#import "OIDURLSessionProvider.h"
|
||||
#import "OIDEndSessionRequest.h"
|
||||
#import "OIDEndSessionResponse.h"
|
||||
-272
@@ -1,272 +0,0 @@
|
||||
/*! @file OIDAuthState.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class OIDAuthorizationRequest;
|
||||
@class OIDAuthorizationResponse;
|
||||
@class OIDAuthState;
|
||||
@class OIDRegistrationResponse;
|
||||
@class OIDTokenResponse;
|
||||
@class OIDTokenRequest;
|
||||
@protocol OIDAuthStateChangeDelegate;
|
||||
@protocol OIDAuthStateErrorDelegate;
|
||||
@protocol OIDExternalUserAgent;
|
||||
@protocol OIDExternalUserAgentSession;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Represents a block used to call an action with a fresh access token.
|
||||
@param accessToken A valid access token if available.
|
||||
@param idToken A valid ID token if available.
|
||||
@param error The error if an error occurred.
|
||||
*/
|
||||
typedef void (^OIDAuthStateAction)(NSString *_Nullable accessToken,
|
||||
NSString *_Nullable idToken,
|
||||
NSError *_Nullable error);
|
||||
|
||||
/*! @brief The method called when the @c
|
||||
OIDAuthState.authStateByPresentingAuthorizationRequest:presentingViewController:callback:
|
||||
method has completed or failed.
|
||||
@param authState The auth state, if the authorization request succeeded.
|
||||
@param error The error if an error occurred.
|
||||
*/
|
||||
typedef void (^OIDAuthStateAuthorizationCallback)(OIDAuthState *_Nullable authState,
|
||||
NSError *_Nullable error);
|
||||
|
||||
/*! @brief A convenience class that retains the auth state between @c OIDAuthorizationResponse%s
|
||||
and @c OIDTokenResponse%s.
|
||||
*/
|
||||
@interface OIDAuthState : NSObject <NSSecureCoding>
|
||||
|
||||
/*! @brief The most recent refresh token received from the server.
|
||||
@discussion Rather than using this property directly, you should call
|
||||
@c OIDAuthState.performActionWithFreshTokens:.
|
||||
@remarks refresh_token
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *refreshToken;
|
||||
|
||||
/*! @brief The scope of the current authorization grant.
|
||||
@discussion This represents the latest scope returned by the server and may be a subset of the
|
||||
scope that was initially granted.
|
||||
@remarks scope
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *scope;
|
||||
|
||||
/*! @brief The most recent authorization response used to update the authorization state. For the
|
||||
implicit flow, this will contain the latest access token.
|
||||
*/
|
||||
@property(nonatomic, readonly) OIDAuthorizationResponse *lastAuthorizationResponse;
|
||||
|
||||
/*! @brief The most recent token response used to update this authorization state. This will
|
||||
contain the latest access token.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) OIDTokenResponse *lastTokenResponse;
|
||||
|
||||
/*! @brief The most recent registration response used to update this authorization state. This will
|
||||
contain the latest client credentials.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) OIDRegistrationResponse *lastRegistrationResponse;
|
||||
|
||||
/*! @brief The authorization error that invalidated this @c OIDAuthState.
|
||||
@discussion The authorization error encountered by @c OIDAuthState or set by the user via
|
||||
@c OIDAuthState.updateWithAuthorizationError: that invalidated this @c OIDAuthState.
|
||||
Authorization errors from @c OIDAuthState will always have a domain of
|
||||
@c ::OIDOAuthAuthorizationErrorDomain or @c ::OIDOAuthTokenErrorDomain. Note: that after
|
||||
unarchiving the @c OIDAuthState object, the \NSError_userInfo property of this error will
|
||||
be nil.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSError *authorizationError;
|
||||
|
||||
/*! @brief Returns YES if the authorization state is not known to be invalid.
|
||||
@discussion Returns YES if no OAuth errors have been received, and the last call resulted in a
|
||||
successful access token or id token. This does not mean that the access is fresh - just
|
||||
that it was valid the last time it was used. Note that network and other transient errors
|
||||
do not invalidate the authorized state. If NO, you should authenticate the user again,
|
||||
using a fresh authorization request. Invalid @c OIDAuthState objects may still be useful in
|
||||
that case, to hint at the previously authorized user and streamline the re-authentication
|
||||
experience.
|
||||
*/
|
||||
@property(nonatomic, readonly) BOOL isAuthorized;
|
||||
|
||||
/*! @brief The @c OIDAuthStateChangeDelegate delegate.
|
||||
@discussion Use the delegate to observe state changes (and update storage) as well as error
|
||||
states.
|
||||
*/
|
||||
@property(nonatomic, weak, nullable) id<OIDAuthStateChangeDelegate> stateChangeDelegate;
|
||||
|
||||
/*! @brief The @c OIDAuthStateErrorDelegate delegate.
|
||||
@discussion Use the delegate to observe state changes (and update storage) as well as error
|
||||
states.
|
||||
*/
|
||||
@property(nonatomic, weak, nullable) id<OIDAuthStateErrorDelegate> errorDelegate;
|
||||
|
||||
/*! @brief Convenience method to create a @c OIDAuthState by presenting an authorization request
|
||||
and performing the authorization code exchange in the case of code flow requests. For
|
||||
the hybrid flow, the caller should validate the id_token and c_hash, then perform the token
|
||||
request (@c OIDAuthorizationService.performTokenRequest:callback:)
|
||||
and update the OIDAuthState with the results (@c
|
||||
OIDAuthState.updateWithTokenResponse:error:).
|
||||
@param authorizationRequest The authorization request to present.
|
||||
@param externalUserAgent A external user agent that can present an external user-agent request.
|
||||
@param callback The method called when the request has completed or failed.
|
||||
@return A @c OIDExternalUserAgentSession instance which will terminate when it
|
||||
receives a @c OIDExternalUserAgentSession.cancel message, or after processing a
|
||||
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message.
|
||||
*/
|
||||
+ (id<OIDExternalUserAgentSession>)
|
||||
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
|
||||
externalUserAgent:(id<OIDExternalUserAgent>)externalUserAgent
|
||||
callback:(OIDAuthStateAuthorizationCallback)callback;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use @c initWithAuthorizationResponse:.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Creates an auth state from an authorization response.
|
||||
@param authorizationResponse The authorization response.
|
||||
*/
|
||||
- (instancetype)initWithAuthorizationResponse:(OIDAuthorizationResponse *)authorizationResponse;
|
||||
|
||||
/*! @brief Creates an auth state from an authorization and token response.
|
||||
@param authorizationResponse The authorization response.
|
||||
@param tokenResponse The token response.
|
||||
*/
|
||||
- (instancetype)initWithAuthorizationResponse:(OIDAuthorizationResponse *)authorizationResponse
|
||||
tokenResponse:(nullable OIDTokenResponse *)tokenResponse;
|
||||
|
||||
/*! @brief Creates an auth state from an registration response.
|
||||
@param registrationResponse The registration response.
|
||||
*/
|
||||
- (instancetype)initWithRegistrationResponse:(OIDRegistrationResponse *)registrationResponse;
|
||||
|
||||
/*! @brief Creates an auth state from an authorization, token and registration response.
|
||||
@param authorizationResponse The authorization response.
|
||||
@param tokenResponse The token response.
|
||||
@param registrationResponse The registration response.
|
||||
*/
|
||||
- (instancetype)initWithAuthorizationResponse:
|
||||
(nullable OIDAuthorizationResponse *)authorizationResponse
|
||||
tokenResponse:(nullable OIDTokenResponse *)tokenResponse
|
||||
registrationResponse:(nullable OIDRegistrationResponse *)registrationResponse
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/*! @brief Updates the authorization state based on a new authorization response.
|
||||
@param authorizationResponse The new authorization response to update the state with.
|
||||
@param error Any error encountered when performing the authorization request. Errors in the
|
||||
domain @c ::OIDOAuthAuthorizationErrorDomain are reflected in the auth state, other errors
|
||||
are assumed to be transient, and ignored.
|
||||
@discussion Typically called with the response from an incremental authorization request,
|
||||
or if using the implicit flow. Will clear the @c #lastTokenResponse property.
|
||||
*/
|
||||
- (void)updateWithAuthorizationResponse:(nullable OIDAuthorizationResponse *)authorizationResponse
|
||||
error:(nullable NSError *)error;
|
||||
|
||||
/*! @brief Updates the authorization state based on a new token response.
|
||||
@param tokenResponse The new token response to update the state from.
|
||||
@param error Any error encountered when performing the authorization request. Errors in the
|
||||
domain @c ::OIDOAuthTokenErrorDomain are reflected in the auth state, other errors
|
||||
are assumed to be transient, and ignored.
|
||||
@discussion Typically called with the response from an authorization code exchange, or a token
|
||||
refresh.
|
||||
*/
|
||||
- (void)updateWithTokenResponse:(nullable OIDTokenResponse *)tokenResponse
|
||||
error:(nullable NSError *)error;
|
||||
|
||||
/*! @brief Updates the authorization state based on a new registration response.
|
||||
@param registrationResponse The new registration response to update the state with.
|
||||
@discussion Typically called with the response from a successful client registration
|
||||
request. Will reset the auth state.
|
||||
*/
|
||||
- (void)updateWithRegistrationResponse:(nullable OIDRegistrationResponse *)registrationResponse;
|
||||
|
||||
/*! @brief Updates the authorization state based on an authorization error.
|
||||
@param authorizationError The authorization error.
|
||||
@discussion Call this method if you receive an authorization error during an API call to
|
||||
invalidate the authentication state of this @c OIDAuthState. Don't call with errors
|
||||
unrelated to authorization, such as transient network errors.
|
||||
The OIDAuthStateErrorDelegate.authState:didEncounterAuthorizationError: method of
|
||||
@c #errorDelegate will be called with the error.
|
||||
You may optionally use the convenience method
|
||||
OIDErrorUtilities.resourceServerAuthorizationErrorWithCode:errorResponse:underlyingError:
|
||||
to create \NSError objects for use here.
|
||||
The latest error received is stored in @c #authorizationError. Note: that after unarchiving
|
||||
this object, the \NSError_userInfo property of this error will be nil.
|
||||
*/
|
||||
- (void)updateWithAuthorizationError:(NSError *)authorizationError;
|
||||
|
||||
/*! @brief Calls the block with a valid access token (refreshing it first, if needed), or if a
|
||||
refresh was needed and failed, with the error that caused it to fail.
|
||||
@param action The block to execute with a fresh token. This block will be executed on the main
|
||||
thread.
|
||||
*/
|
||||
- (void)performActionWithFreshTokens:(OIDAuthStateAction)action;
|
||||
|
||||
/*! @brief Calls the block with a valid access token (refreshing it first, if needed), or if a
|
||||
refresh was needed and failed, with the error that caused it to fail.
|
||||
@param action The block to execute with a fresh token. This block will be executed on the main
|
||||
thread.
|
||||
@param additionalParameters Additional parameters for the token request if token is
|
||||
refreshed.
|
||||
*/
|
||||
- (void)performActionWithFreshTokens:(OIDAuthStateAction)action
|
||||
additionalRefreshParameters:
|
||||
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;
|
||||
|
||||
/*! @brief Calls the block with a valid access token (refreshing it first, if needed), or if a
|
||||
refresh was needed and failed, with the error that caused it to fail.
|
||||
@param action The block to execute with a fresh token. This block will be executed on the main
|
||||
thread.
|
||||
@param additionalParameters Additional parameters for the token request if token is
|
||||
refreshed.
|
||||
@param dispatchQueue The dispatchQueue on which to dispatch the action block.
|
||||
*/
|
||||
- (void)performActionWithFreshTokens:(OIDAuthStateAction)action
|
||||
additionalRefreshParameters:
|
||||
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
|
||||
dispatchQueue:(dispatch_queue_t)dispatchQueue;
|
||||
|
||||
/*! @brief Forces a token refresh the next time @c OIDAuthState.performActionWithFreshTokens: is
|
||||
called, even if the current tokens are considered valid.
|
||||
*/
|
||||
- (void)setNeedsTokenRefresh;
|
||||
|
||||
/*! @brief Creates a token request suitable for refreshing an access token.
|
||||
@return A @c OIDTokenRequest suitable for using a refresh token to obtain a new access token.
|
||||
@discussion After performing the refresh, call @c OIDAuthState.updateWithTokenResponse:error:
|
||||
to update the authorization state based on the response. Rather than doing the token refresh
|
||||
yourself, you should use @c OIDAuthState.performActionWithFreshTokens:.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-1.5
|
||||
*/
|
||||
- (nullable OIDTokenRequest *)tokenRefreshRequest;
|
||||
|
||||
/*! @brief Creates a token request suitable for refreshing an access token.
|
||||
@param additionalParameters Additional parameters for the token request.
|
||||
@return A @c OIDTokenRequest suitable for using a refresh token to obtain a new access token.
|
||||
@discussion After performing the refresh, call @c OIDAuthState.updateWithTokenResponse:error:
|
||||
to update the authorization state based on the response. Rather than doing the token refresh
|
||||
yourself, you should use @c OIDAuthState.performActionWithFreshTokens:.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-1.5
|
||||
*/
|
||||
- (nullable OIDTokenRequest *)tokenRefreshRequestWithAdditionalParameters:
|
||||
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-570
@@ -1,570 +0,0 @@
|
||||
/*! @file OIDAuthState.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDAuthState.h"
|
||||
|
||||
#import "OIDAuthStateChangeDelegate.h"
|
||||
#import "OIDAuthStateErrorDelegate.h"
|
||||
#import "OIDAuthorizationRequest.h"
|
||||
#import "OIDAuthorizationResponse.h"
|
||||
#import "OIDAuthorizationService.h"
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDError.h"
|
||||
#import "OIDErrorUtilities.h"
|
||||
#import "OIDRegistrationResponse.h"
|
||||
#import "OIDTokenRequest.h"
|
||||
#import "OIDTokenResponse.h"
|
||||
#import "OIDTokenUtilities.h"
|
||||
|
||||
/*! @brief Key used to encode the @c refreshToken property for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kRefreshTokenKey = @"refreshToken";
|
||||
|
||||
/*! @brief Key used to encode the @c needsTokenRefresh property for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kNeedsTokenRefreshKey = @"needsTokenRefresh";
|
||||
|
||||
/*! @brief Key used to encode the @c scope property for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kScopeKey = @"scope";
|
||||
|
||||
/*! @brief Key used to encode the @c lastAuthorizationResponse property for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kLastAuthorizationResponseKey = @"lastAuthorizationResponse";
|
||||
|
||||
/*! @brief Key used to encode the @c lastTokenResponse property for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kLastTokenResponseKey = @"lastTokenResponse";
|
||||
|
||||
/*! @brief Key used to encode the @c lastOAuthError property for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kAuthorizationErrorKey = @"authorizationError";
|
||||
|
||||
/*! @brief The exception thrown when a developer tries to create a refresh request from an
|
||||
authorization request with no authorization code.
|
||||
*/
|
||||
static NSString *const kRefreshTokenRequestException =
|
||||
@"Attempted to create a token refresh request from a token response with no refresh token.";
|
||||
|
||||
/*! @brief Number of seconds the access token is refreshed before it actually expires.
|
||||
*/
|
||||
static const NSUInteger kExpiryTimeTolerance = 60;
|
||||
|
||||
/*! @brief Object to hold OIDAuthState pending actions.
|
||||
*/
|
||||
@interface OIDAuthStatePendingAction : NSObject
|
||||
@property(nonatomic, readonly, nullable) OIDAuthStateAction action;
|
||||
@property(nonatomic, readonly, nullable) dispatch_queue_t dispatchQueue;
|
||||
@end
|
||||
@implementation OIDAuthStatePendingAction
|
||||
- (id)initWithAction:(OIDAuthStateAction)action andDispatchQueue:(dispatch_queue_t)dispatchQueue {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_action = action;
|
||||
_dispatchQueue = dispatchQueue;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface OIDAuthState ()
|
||||
|
||||
/*! @brief The access token generated by the authorization server.
|
||||
@discussion Rather than using this property directly, you should call
|
||||
@c OIDAuthState.withFreshTokenPerformAction:.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *accessToken;
|
||||
|
||||
/*! @brief The approximate expiration date & time of the access token.
|
||||
@discussion Rather than using this property directly, you should call
|
||||
@c OIDAuthState.withFreshTokenPerformAction:.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSDate *accessTokenExpirationDate;
|
||||
|
||||
/*! @brief ID Token value associated with the authenticated session.
|
||||
@discussion Rather than using this property directly, you should call
|
||||
OIDAuthState.withFreshTokenPerformAction:.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *idToken;
|
||||
|
||||
/*! @brief Private method, called when the internal state changes.
|
||||
*/
|
||||
- (void)didChangeState;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OIDAuthState {
|
||||
/*! @brief Array of pending actions (use @c _pendingActionsSyncObject to synchronize access).
|
||||
*/
|
||||
NSMutableArray *_pendingActions;
|
||||
|
||||
/*! @brief Object for synchronizing access to @c pendingActions.
|
||||
*/
|
||||
id _pendingActionsSyncObject;
|
||||
|
||||
/*! @brief If YES, tokens will be refreshed on the next API call regardless of expiry.
|
||||
*/
|
||||
BOOL _needsTokenRefresh;
|
||||
}
|
||||
|
||||
#pragma mark - Convenience initializers
|
||||
|
||||
+ (id<OIDExternalUserAgentSession>)
|
||||
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
|
||||
externalUserAgent:(id<OIDExternalUserAgent>)externalUserAgent
|
||||
callback:(OIDAuthStateAuthorizationCallback)callback {
|
||||
// presents the authorization request
|
||||
id<OIDExternalUserAgentSession> authFlowSession = [OIDAuthorizationService
|
||||
presentAuthorizationRequest:authorizationRequest
|
||||
externalUserAgent:externalUserAgent
|
||||
callback:^(OIDAuthorizationResponse *_Nullable authorizationResponse,
|
||||
NSError *_Nullable authorizationError) {
|
||||
// inspects response and processes further if needed (e.g. authorization
|
||||
// code exchange)
|
||||
if (authorizationResponse) {
|
||||
if ([authorizationRequest.responseType
|
||||
isEqualToString:OIDResponseTypeCode]) {
|
||||
// if the request is for the code flow (NB. not hybrid), assumes the
|
||||
// code is intended for this client, and performs the authorization
|
||||
// code exchange
|
||||
OIDTokenRequest *tokenExchangeRequest =
|
||||
[authorizationResponse tokenExchangeRequest];
|
||||
[OIDAuthorizationService performTokenRequest:tokenExchangeRequest
|
||||
originalAuthorizationResponse:authorizationResponse
|
||||
callback:^(OIDTokenResponse *_Nullable tokenResponse,
|
||||
NSError *_Nullable tokenError) {
|
||||
OIDAuthState *authState;
|
||||
if (tokenResponse) {
|
||||
authState = [[OIDAuthState alloc]
|
||||
initWithAuthorizationResponse:
|
||||
authorizationResponse
|
||||
tokenResponse:tokenResponse];
|
||||
}
|
||||
callback(authState, tokenError);
|
||||
}];
|
||||
} else {
|
||||
// hybrid flow (code id_token). Two possible cases:
|
||||
// 1. The code is not for this client, ie. will be sent to a
|
||||
// webservice that performs the id token verification and token
|
||||
// exchange
|
||||
// 2. The code is for this client and, for security reasons, the
|
||||
// application developer must verify the id_token signature and
|
||||
// c_hash before calling the token endpoint
|
||||
OIDAuthState *authState = [[OIDAuthState alloc]
|
||||
initWithAuthorizationResponse:authorizationResponse];
|
||||
callback(authState, authorizationError);
|
||||
}
|
||||
} else {
|
||||
callback(nil, authorizationError);
|
||||
}
|
||||
}];
|
||||
return authFlowSession;
|
||||
}
|
||||
|
||||
#pragma mark - Initializers
|
||||
|
||||
- (nonnull instancetype)init
|
||||
OID_UNAVAILABLE_USE_INITIALIZER(@selector(initWithAuthorizationResponse:tokenResponse:))
|
||||
|
||||
/*! @brief Creates an auth state from an authorization response.
|
||||
@param authorizationResponse The authorization response.
|
||||
*/
|
||||
- (instancetype)initWithAuthorizationResponse:(OIDAuthorizationResponse *)authorizationResponse {
|
||||
return [self initWithAuthorizationResponse:authorizationResponse tokenResponse:nil];
|
||||
}
|
||||
|
||||
|
||||
/*! @brief Designated initializer.
|
||||
@param authorizationResponse The authorization response.
|
||||
@discussion Creates an auth state from an authorization response and token response.
|
||||
*/
|
||||
- (instancetype)initWithAuthorizationResponse:(OIDAuthorizationResponse *)authorizationResponse
|
||||
tokenResponse:(nullable OIDTokenResponse *)tokenResponse {
|
||||
return [self initWithAuthorizationResponse:authorizationResponse
|
||||
tokenResponse:tokenResponse
|
||||
registrationResponse:nil];
|
||||
}
|
||||
|
||||
/*! @brief Creates an auth state from an registration response.
|
||||
@param registrationResponse The registration response.
|
||||
*/
|
||||
- (instancetype)initWithRegistrationResponse:(OIDRegistrationResponse *)registrationResponse {
|
||||
return [self initWithAuthorizationResponse:nil
|
||||
tokenResponse:nil
|
||||
registrationResponse:registrationResponse];
|
||||
}
|
||||
|
||||
- (instancetype)initWithAuthorizationResponse:
|
||||
(nullable OIDAuthorizationResponse *)authorizationResponse
|
||||
tokenResponse:(nullable OIDTokenResponse *)tokenResponse
|
||||
registrationResponse:(nullable OIDRegistrationResponse *)registrationResponse {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_pendingActionsSyncObject = [[NSObject alloc] init];
|
||||
|
||||
if (registrationResponse) {
|
||||
[self updateWithRegistrationResponse:registrationResponse];
|
||||
}
|
||||
|
||||
if (authorizationResponse) {
|
||||
[self updateWithAuthorizationResponse:authorizationResponse error:nil];
|
||||
}
|
||||
|
||||
if (tokenResponse) {
|
||||
[self updateWithTokenResponse:tokenResponse error:nil];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSObject overrides
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, isAuthorized: %@, refreshToken: \"%@\", "
|
||||
"scope: \"%@\", accessToken: \"%@\", "
|
||||
"accessTokenExpirationDate: %@, idToken: \"%@\", "
|
||||
"lastAuthorizationResponse: %@, lastTokenResponse: %@, "
|
||||
"lastRegistrationResponse: %@, authorizationError: %@>",
|
||||
NSStringFromClass([self class]),
|
||||
(void *)self,
|
||||
(self.isAuthorized) ? @"YES" : @"NO",
|
||||
[OIDTokenUtilities redact:_refreshToken],
|
||||
_scope,
|
||||
[OIDTokenUtilities redact:self.accessToken],
|
||||
self.accessTokenExpirationDate,
|
||||
[OIDTokenUtilities redact:self.idToken],
|
||||
_lastAuthorizationResponse,
|
||||
_lastTokenResponse,
|
||||
_lastRegistrationResponse,
|
||||
_authorizationError];
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
_lastAuthorizationResponse = [aDecoder decodeObjectOfClass:[OIDAuthorizationResponse class]
|
||||
forKey:kLastAuthorizationResponseKey];
|
||||
_lastTokenResponse = [aDecoder decodeObjectOfClass:[OIDTokenResponse class]
|
||||
forKey:kLastTokenResponseKey];
|
||||
self = [self initWithAuthorizationResponse:_lastAuthorizationResponse
|
||||
tokenResponse:_lastTokenResponse];
|
||||
if (self) {
|
||||
_authorizationError =
|
||||
[aDecoder decodeObjectOfClass:[NSError class] forKey:kAuthorizationErrorKey];
|
||||
_scope = [aDecoder decodeObjectOfClass:[NSString class] forKey:kScopeKey];
|
||||
_refreshToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:kRefreshTokenKey];
|
||||
_needsTokenRefresh = [aDecoder decodeBoolForKey:kNeedsTokenRefreshKey];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[aCoder encodeObject:_lastAuthorizationResponse forKey:kLastAuthorizationResponseKey];
|
||||
[aCoder encodeObject:_lastTokenResponse forKey:kLastTokenResponseKey];
|
||||
if (_authorizationError) {
|
||||
NSError *codingSafeAuthorizationError = [NSError errorWithDomain:_authorizationError.domain
|
||||
code:_authorizationError.code
|
||||
userInfo:nil];
|
||||
[aCoder encodeObject:codingSafeAuthorizationError forKey:kAuthorizationErrorKey];
|
||||
}
|
||||
[aCoder encodeObject:_scope forKey:kScopeKey];
|
||||
[aCoder encodeObject:_refreshToken forKey:kRefreshTokenKey];
|
||||
[aCoder encodeBool:_needsTokenRefresh forKey:kNeedsTokenRefreshKey];
|
||||
}
|
||||
|
||||
#pragma mark - Private convenience getters
|
||||
|
||||
- (NSString *)accessToken {
|
||||
if (_authorizationError) {
|
||||
return nil;
|
||||
}
|
||||
return _lastTokenResponse ? _lastTokenResponse.accessToken
|
||||
: _lastAuthorizationResponse.accessToken;
|
||||
}
|
||||
|
||||
- (NSString *)tokenType {
|
||||
if (_authorizationError) {
|
||||
return nil;
|
||||
}
|
||||
return _lastTokenResponse ? _lastTokenResponse.tokenType
|
||||
: _lastAuthorizationResponse.tokenType;
|
||||
}
|
||||
|
||||
- (NSDate *)accessTokenExpirationDate {
|
||||
if (_authorizationError) {
|
||||
return nil;
|
||||
}
|
||||
return _lastTokenResponse ? _lastTokenResponse.accessTokenExpirationDate
|
||||
: _lastAuthorizationResponse.accessTokenExpirationDate;
|
||||
}
|
||||
|
||||
- (NSString *)idToken {
|
||||
if (_authorizationError) {
|
||||
return nil;
|
||||
}
|
||||
return _lastTokenResponse ? _lastTokenResponse.idToken
|
||||
: _lastAuthorizationResponse.idToken;
|
||||
}
|
||||
|
||||
#pragma mark - Getters
|
||||
|
||||
- (BOOL)isAuthorized {
|
||||
return !self.authorizationError && (self.accessToken || self.idToken || self.refreshToken);
|
||||
}
|
||||
|
||||
#pragma mark - Updating the state
|
||||
|
||||
- (void)updateWithRegistrationResponse:(OIDRegistrationResponse *)registrationResponse {
|
||||
_lastRegistrationResponse = registrationResponse;
|
||||
_refreshToken = nil;
|
||||
_scope = nil;
|
||||
_lastAuthorizationResponse = nil;
|
||||
_lastTokenResponse = nil;
|
||||
_authorizationError = nil;
|
||||
[self didChangeState];
|
||||
}
|
||||
|
||||
- (void)updateWithAuthorizationResponse:(nullable OIDAuthorizationResponse *)authorizationResponse
|
||||
error:(nullable NSError *)error {
|
||||
// If the error is an OAuth authorization error, updates the state. Other errors are ignored.
|
||||
if (error.domain == OIDOAuthAuthorizationErrorDomain) {
|
||||
[self updateWithAuthorizationError:error];
|
||||
return;
|
||||
}
|
||||
if (!authorizationResponse) {
|
||||
return;
|
||||
}
|
||||
|
||||
_lastAuthorizationResponse = authorizationResponse;
|
||||
|
||||
// clears the last token response and refresh token as these now relate to an old authorization
|
||||
// that is no longer relevant
|
||||
_lastTokenResponse = nil;
|
||||
_refreshToken = nil;
|
||||
_authorizationError = nil;
|
||||
|
||||
// if the response's scope is nil, it means that it equals that of the request
|
||||
// see: https://tools.ietf.org/html/rfc6749#section-5.1
|
||||
_scope = (authorizationResponse.scope) ? authorizationResponse.scope
|
||||
: authorizationResponse.request.scope;
|
||||
|
||||
[self didChangeState];
|
||||
}
|
||||
|
||||
- (void)updateWithTokenResponse:(nullable OIDTokenResponse *)tokenResponse
|
||||
error:(nullable NSError *)error {
|
||||
if (_authorizationError) {
|
||||
// Calling updateWithTokenResponse while in an error state probably means the developer obtained
|
||||
// a new token and did the exchange without also calling updateWithAuthorizationResponse.
|
||||
// Attempts to handle gracefully, but warns the developer that this is unexpected.
|
||||
NSLog(@"OIDAuthState:updateWithTokenResponse should not be called in an error state [%@] call"
|
||||
"updateWithAuthorizationResponse with the result of the fresh authorization response"
|
||||
"first",
|
||||
_authorizationError);
|
||||
|
||||
_authorizationError = nil;
|
||||
}
|
||||
|
||||
// If the error is an OAuth authorization error, updates the state. Other errors are ignored.
|
||||
if (error.domain == OIDOAuthTokenErrorDomain) {
|
||||
[self updateWithAuthorizationError:error];
|
||||
return;
|
||||
}
|
||||
if (!tokenResponse) {
|
||||
return;
|
||||
}
|
||||
|
||||
_lastTokenResponse = tokenResponse;
|
||||
|
||||
// updates the scope and refresh token if they are present on the TokenResponse.
|
||||
// according to the spec, these may be changed by the server, including when refreshing the
|
||||
// access token. See: https://tools.ietf.org/html/rfc6749#section-5.1 and
|
||||
// https://tools.ietf.org/html/rfc6749#section-6
|
||||
if (tokenResponse.scope) {
|
||||
_scope = tokenResponse.scope;
|
||||
}
|
||||
if (tokenResponse.refreshToken) {
|
||||
_refreshToken = tokenResponse.refreshToken;
|
||||
}
|
||||
|
||||
[self didChangeState];
|
||||
}
|
||||
|
||||
- (void)updateWithAuthorizationError:(NSError *)oauthError {
|
||||
_authorizationError = oauthError;
|
||||
|
||||
[self didChangeState];
|
||||
|
||||
[_errorDelegate authState:self didEncounterAuthorizationError:oauthError];
|
||||
}
|
||||
|
||||
#pragma mark - OAuth Requests
|
||||
|
||||
- (OIDTokenRequest *)tokenRefreshRequest {
|
||||
return [self tokenRefreshRequestWithAdditionalParameters:nil];
|
||||
}
|
||||
|
||||
- (OIDTokenRequest *)tokenRefreshRequestWithAdditionalParameters:
|
||||
(NSDictionary<NSString *, NSString *> *)additionalParameters {
|
||||
|
||||
// TODO: Add unit test to confirm exception is thrown when expected
|
||||
|
||||
if (!_refreshToken) {
|
||||
[OIDErrorUtilities raiseException:kRefreshTokenRequestException];
|
||||
}
|
||||
return [[OIDTokenRequest alloc]
|
||||
initWithConfiguration:_lastAuthorizationResponse.request.configuration
|
||||
grantType:OIDGrantTypeRefreshToken
|
||||
authorizationCode:nil
|
||||
redirectURL:nil
|
||||
clientID:_lastAuthorizationResponse.request.clientID
|
||||
clientSecret:_lastAuthorizationResponse.request.clientSecret
|
||||
scope:nil
|
||||
refreshToken:_refreshToken
|
||||
codeVerifier:nil
|
||||
additionalParameters:additionalParameters];
|
||||
}
|
||||
|
||||
#pragma mark - Stateful Actions
|
||||
|
||||
- (void)didChangeState {
|
||||
[_stateChangeDelegate didChangeState:self];
|
||||
}
|
||||
|
||||
- (void)setNeedsTokenRefresh {
|
||||
_needsTokenRefresh = YES;
|
||||
}
|
||||
|
||||
- (void)performActionWithFreshTokens:(OIDAuthStateAction)action {
|
||||
[self performActionWithFreshTokens:action additionalRefreshParameters:nil];
|
||||
}
|
||||
|
||||
- (void)performActionWithFreshTokens:(OIDAuthStateAction)action
|
||||
additionalRefreshParameters:
|
||||
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters {
|
||||
[self performActionWithFreshTokens:action
|
||||
additionalRefreshParameters:additionalParameters
|
||||
dispatchQueue:dispatch_get_main_queue()];
|
||||
}
|
||||
|
||||
- (void)performActionWithFreshTokens:(OIDAuthStateAction)action
|
||||
additionalRefreshParameters:
|
||||
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
|
||||
dispatchQueue:(dispatch_queue_t)dispatchQueue {
|
||||
|
||||
if ([self isTokenFresh]) {
|
||||
// access token is valid within tolerance levels, perform action
|
||||
dispatch_async(dispatchQueue, ^{
|
||||
action(self.accessToken, self.idToken, nil);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_refreshToken) {
|
||||
// no refresh token available and token has expired
|
||||
NSError *tokenRefreshError = [
|
||||
OIDErrorUtilities errorWithCode:OIDErrorCodeTokenRefreshError
|
||||
underlyingError:nil
|
||||
description:@"Unable to refresh expired token without a refresh token."];
|
||||
dispatch_async(dispatchQueue, ^{
|
||||
action(nil, nil, tokenRefreshError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// access token is expired, first refresh the token, then perform action
|
||||
NSAssert(_pendingActionsSyncObject, @"_pendingActionsSyncObject cannot be nil", @"");
|
||||
OIDAuthStatePendingAction* pendingAction =
|
||||
[[OIDAuthStatePendingAction alloc] initWithAction:action andDispatchQueue:dispatchQueue];
|
||||
@synchronized(_pendingActionsSyncObject) {
|
||||
// if a token is already in the process of being refreshed, adds to pending actions
|
||||
if (_pendingActions) {
|
||||
[_pendingActions addObject:pendingAction];
|
||||
return;
|
||||
}
|
||||
|
||||
// creates a list of pending actions, starting with this one
|
||||
_pendingActions = [NSMutableArray arrayWithObject:pendingAction];
|
||||
}
|
||||
|
||||
// refresh the tokens
|
||||
OIDTokenRequest *tokenRefreshRequest =
|
||||
[self tokenRefreshRequestWithAdditionalParameters:additionalParameters];
|
||||
[OIDAuthorizationService performTokenRequest:tokenRefreshRequest
|
||||
originalAuthorizationResponse:_lastAuthorizationResponse
|
||||
callback:^(OIDTokenResponse *_Nullable response,
|
||||
NSError *_Nullable error) {
|
||||
// update OIDAuthState based on response
|
||||
if (response) {
|
||||
self->_needsTokenRefresh = NO;
|
||||
[self updateWithTokenResponse:response error:nil];
|
||||
} else {
|
||||
if (error.domain == OIDOAuthTokenErrorDomain) {
|
||||
self->_needsTokenRefresh = NO;
|
||||
[self updateWithAuthorizationError:error];
|
||||
} else {
|
||||
if ([self->_errorDelegate respondsToSelector:
|
||||
@selector(authState:didEncounterTransientError:)]) {
|
||||
[self->_errorDelegate authState:self didEncounterTransientError:error];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nil the pending queue and process everything that was queued up
|
||||
NSArray *actionsToProcess;
|
||||
@synchronized(self->_pendingActionsSyncObject) {
|
||||
actionsToProcess = self->_pendingActions;
|
||||
self->_pendingActions = nil;
|
||||
}
|
||||
for (OIDAuthStatePendingAction* actionToProcess in actionsToProcess) {
|
||||
dispatch_async(actionToProcess.dispatchQueue, ^{
|
||||
actionToProcess.action(self.accessToken, self.idToken, error);
|
||||
});
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/*! @fn isTokenFresh
|
||||
@brief Determines whether a token refresh request must be made to refresh the tokens.
|
||||
*/
|
||||
- (BOOL)isTokenFresh {
|
||||
if (_needsTokenRefresh) {
|
||||
// forced refresh
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (!self.accessTokenExpirationDate) {
|
||||
// if there is no expiration time but we have an access token, it is assumed to never expire
|
||||
return !!self.accessToken;
|
||||
}
|
||||
|
||||
// has the token expired?
|
||||
BOOL tokenFresh = [self.accessTokenExpirationDate timeIntervalSinceNow] > kExpiryTimeTolerance;
|
||||
return tokenFresh;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*! @file OIDAuthStateChangeDelegate.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class OIDAuthState;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @protocol OIDAuthStateChangeDelegate
|
||||
@brief Delegate of the OIDAuthState used to monitor various changes in state.
|
||||
*/
|
||||
@protocol OIDAuthStateChangeDelegate <NSObject>
|
||||
|
||||
/*! @brief Called when the authorization state changes and any backing storage needs to be updated.
|
||||
@param state The @c OIDAuthState that changed.
|
||||
@discussion If you are storing the authorization state, you should update the storage when the
|
||||
state changes.
|
||||
*/
|
||||
- (void)didChangeState:(OIDAuthState *)state;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,62 +0,0 @@
|
||||
/*! @file OIDAuthStateErrorDelegate.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class OIDAuthState;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @protocol OIDAuthStateErrorDelegate
|
||||
@brief Delegate of the OIDAuthState used to monitor errors.
|
||||
*/
|
||||
@protocol OIDAuthStateErrorDelegate <NSObject>
|
||||
|
||||
/*! @brief Called when an authentication occurs, which indicates the auth session is invalid.
|
||||
@param state The @c OIDAuthState on which the error occurred.
|
||||
@param error The authorization error.
|
||||
@discussion This is a hard error (not a transient network issue) that indicates a problem with
|
||||
the authorization. You should stop using the @c OIDAuthState when such an error is
|
||||
encountered. If the \NSError_code is @c ::OIDErrorCodeOAuthInvalidGrant then
|
||||
the session may be recoverable with user interaction (i.e. re-authentication). In all cases
|
||||
you should consider the user unauthorized, and remove locally cached resources that require
|
||||
that authorization. @c OIDAuthState will call this method automatically if it encounters
|
||||
an OAuth error (that is, an HTTP 400 response with a valid OAuth error response) during
|
||||
authorization or token refresh (such as performed automatically when using
|
||||
@c OIDAuthState.performActionWithFreshTokens:). You can signal authorization errors with
|
||||
@c OIDAuthState.updateWithAuthorizationError:.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
- (void)authState:(OIDAuthState *)state didEncounterAuthorizationError:(NSError *)error;
|
||||
|
||||
@optional
|
||||
|
||||
/*! @brief Called when a network or other transient error occurs.
|
||||
@param state The @c OIDAuthState on which the error occurred.
|
||||
@param error The transient error.
|
||||
@discussion This is a soft error, typically network related. The @c OIDAuthState is likely
|
||||
still valid, and should not be discarded. Retry the request using an incremental backoff
|
||||
strategy. This is only called when using the @c OIDAuthState convenience methods such as
|
||||
@c OIDAuthState.performActionWithFreshTokens:. If you are refreshing the tokens yourself
|
||||
outside of @c OIDAuthState class, it will never be called.
|
||||
*/
|
||||
- (void)authState:(OIDAuthState *)state didEncounterTransientError:(NSError *)error;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,250 +0,0 @@
|
||||
/*! @file OIDAuthorizationRequest.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// These files only declare string constants useful for constructing a @c OIDAuthorizationRequest,
|
||||
// so they are imported here for convenience.
|
||||
#import "OIDExternalUserAgentRequest.h"
|
||||
#import "OIDResponseTypes.h"
|
||||
#import "OIDScopes.h"
|
||||
|
||||
@class OIDServiceConfiguration;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief The @c code_challenge_method value for the S256 code challenge.
|
||||
@see https://tools.ietf.org/html/rfc7636#section-4.3
|
||||
*/
|
||||
extern NSString *const OIDOAuthorizationRequestCodeChallengeMethodS256;
|
||||
|
||||
|
||||
/*! @brief Represents an authorization request.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.1
|
||||
*/
|
||||
@interface OIDAuthorizationRequest :
|
||||
NSObject<NSCopying, NSSecureCoding, OIDExternalUserAgentRequest>
|
||||
|
||||
/*! @brief The service's configuration.
|
||||
@remarks This configuration specifies how to connect to a particular OAuth provider.
|
||||
Configurations may be created manually, or via an OpenID Connect Discovery Document.
|
||||
*/
|
||||
@property(nonatomic, readonly) OIDServiceConfiguration *configuration;
|
||||
|
||||
/*! @brief The expected response type.
|
||||
@remarks response_type
|
||||
@discussion Generally 'code' if pure OAuth, otherwise a space-delimited list of of response
|
||||
types including 'code', 'token', and 'id_token' for OpenID Connect.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.1.1
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString *responseType;
|
||||
|
||||
/*! @brief The client identifier.
|
||||
@remarks client_id
|
||||
@see https://tools.ietf.org/html/rfc6749#section-2.2
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString *clientID;
|
||||
|
||||
/*! @brief The client secret.
|
||||
@remarks client_secret
|
||||
@discussion The client secret is used to prove that identity of the client when exchaning an
|
||||
authorization code for an access token.
|
||||
The client secret is not passed in the authorizationRequestURL. It is only used when
|
||||
exchanging the authorization code for an access token.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-2.3.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *clientSecret;
|
||||
|
||||
/*! @brief The value of the scope parameter is expressed as a list of space-delimited,
|
||||
case-sensitive strings.
|
||||
@remarks scope
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.3
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *scope;
|
||||
|
||||
/*! @brief The client's redirect URI.
|
||||
@remarks redirect_uri
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.1.2
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *redirectURL;
|
||||
|
||||
/*! @brief An opaque value used by the client to maintain state between the request and callback.
|
||||
@remarks state
|
||||
@discussion If this value is not explicitly set, this library will automatically add state and
|
||||
perform appropriate validation of the state in the authorization response. It is recommended
|
||||
that the default implementation of this parameter be used wherever possible. Typically used
|
||||
to prevent CSRF attacks, as recommended in RFC6819 Section 5.3.5.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.1
|
||||
@see https://tools.ietf.org/html/rfc6819#section-5.3.5
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *state;
|
||||
|
||||
/*! @brief String value used to associate a Client session with an ID Token, and to mitigate replay
|
||||
attacks. The value is passed through unmodified from the Authentication Request to the ID
|
||||
Token. Sufficient entropy MUST be present in the nonce values used to prevent attackers from
|
||||
guessing values.
|
||||
@remarks nonce
|
||||
@discussion If this value is not explicitly set, this library will automatically add nonce and
|
||||
perform appropriate validation of the nonce in the ID Token.
|
||||
@see https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *nonce;
|
||||
|
||||
/*! @brief The PKCE code verifier.
|
||||
@remarks code_verifier
|
||||
@discussion The code verifier itself is not included in the authorization request that is sent
|
||||
on the wire, but needs to be in the token exchange request.
|
||||
@c OIDAuthorizationResponse.tokenExchangeRequest will create a @c OIDTokenRequest that
|
||||
includes this parameter automatically.
|
||||
@see https://tools.ietf.org/html/rfc7636#section-4.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *codeVerifier;
|
||||
|
||||
/*! @brief The PKCE code challenge, derived from #codeVerifier.
|
||||
@remarks code_challenge
|
||||
@see https://tools.ietf.org/html/rfc7636#section-4.2
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *codeChallenge;
|
||||
|
||||
/*! @brief The method used to compute the @c #codeChallenge
|
||||
@remarks code_challenge_method
|
||||
@see https://tools.ietf.org/html/rfc7636#section-4.3
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *codeChallengeMethod;
|
||||
|
||||
/*! @brief The client's additional authorization parameters.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSDictionary<NSString *, NSString *> *additionalParameters;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use
|
||||
@c initWithConfiguration:clientId:scopes:redirectURL:responseType:additionalParameters:.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Creates an authorization request with opinionated defaults (a secure @c state, and
|
||||
PKCE with S256 as the @c code_challenge_method).
|
||||
@param configuration The service's configuration.
|
||||
@param clientID The client identifier.
|
||||
@param scopes An array of scopes to combine into a single scope string per the OAuth2 spec.
|
||||
@param redirectURL The client's redirect URI.
|
||||
@param responseType The expected response type.
|
||||
@param additionalParameters The client's additional authorization parameters.
|
||||
@remarks This convenience initializer generates a state parameter and PKCE challenges
|
||||
automatically.
|
||||
*/
|
||||
- (instancetype)
|
||||
initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
clientId:(NSString *)clientID
|
||||
scopes:(nullable NSArray<NSString *> *)scopes
|
||||
redirectURL:(NSURL *)redirectURL
|
||||
responseType:(NSString *)responseType
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;
|
||||
|
||||
/*! @brief Creates an authorization request with opinionated defaults (a secure @c state, @c nonce,
|
||||
and PKCE with S256 as the @c code_challenge_method).
|
||||
@param configuration The service's configuration.
|
||||
@param clientID The client identifier.
|
||||
@param clientSecret The client secret.
|
||||
@param scopes An array of scopes to combine into a single scope string per the OAuth2 spec.
|
||||
@param redirectURL The client's redirect URI.
|
||||
@param responseType The expected response type.
|
||||
@param additionalParameters The client's additional authorization parameters.
|
||||
@remarks This convenience initializer generates a state parameter and PKCE challenges
|
||||
automatically.
|
||||
*/
|
||||
- (instancetype)
|
||||
initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
clientId:(NSString *)clientID
|
||||
clientSecret:(nullable NSString *)clientSecret
|
||||
scopes:(nullable NSArray<NSString *> *)scopes
|
||||
redirectURL:(NSURL *)redirectURL
|
||||
responseType:(NSString *)responseType
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;
|
||||
|
||||
/*! @brief Designated initializer.
|
||||
@param configuration The service's configuration.
|
||||
@param clientID The client identifier.
|
||||
@param scope A scope string per the OAuth2 spec (a space-delimited set of scopes).
|
||||
@param redirectURL The client's redirect URI.
|
||||
@param responseType The expected response type.
|
||||
@param state An opaque value used by the client to maintain state between the request and
|
||||
callback.
|
||||
@param nonce String value used to associate a Client session with an ID Token. Can be set to nil
|
||||
if not using OpenID Connect, although pure OAuth servers should ignore params they don't
|
||||
understand anyway.
|
||||
@param codeVerifier The PKCE code verifier. See @c OIDAuthorizationRequest.generateCodeVerifier.
|
||||
@param codeChallenge The PKCE code challenge, calculated from the code verifier such as with
|
||||
@c OIDAuthorizationRequest.codeChallengeS256ForVerifier:.
|
||||
@param codeChallengeMethod The PKCE code challenge method.
|
||||
::OIDOAuthorizationRequestCodeChallengeMethodS256 when
|
||||
@c OIDAuthorizationRequest.codeChallengeS256ForVerifier: is used to create the code
|
||||
challenge.
|
||||
@param additionalParameters The client's additional authorization parameters.
|
||||
*/
|
||||
- (instancetype)
|
||||
initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
clientId:(NSString *)clientID
|
||||
clientSecret:(nullable NSString *)clientSecret
|
||||
scope:(nullable NSString *)scope
|
||||
redirectURL:(nullable NSURL *)redirectURL
|
||||
responseType:(NSString *)responseType
|
||||
state:(nullable NSString *)state
|
||||
nonce:(nullable NSString *)nonce
|
||||
codeVerifier:(nullable NSString *)codeVerifier
|
||||
codeChallenge:(nullable NSString *)codeChallenge
|
||||
codeChallengeMethod:(nullable NSString *)codeChallengeMethod
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/*! @brief Constructs the request URI by adding the request parameters to the query component of the
|
||||
authorization endpoint URI using the "application/x-www-form-urlencoded" format.
|
||||
@return A URL representing the authorization request.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.1
|
||||
*/
|
||||
- (NSURL *)authorizationRequestURL;
|
||||
|
||||
/*! @brief Generates an OAuth state param using a random source.
|
||||
@return The generated state.
|
||||
@see https://tools.ietf.org/html/rfc6819#section-5.3.5
|
||||
*/
|
||||
+ (nullable NSString *)generateState;
|
||||
|
||||
/*! @brief Constructs a PKCE-compliant code verifier.
|
||||
@return The generated code verifier.
|
||||
@see https://tools.ietf.org/html/rfc7636#section-4.1
|
||||
*/
|
||||
+ (nullable NSString *)generateCodeVerifier;
|
||||
|
||||
/*! @brief Creates a PKCE S256 codeChallenge from the codeVerifier.
|
||||
@param codeVerifier The code verifier from which the code challenge will be derived.
|
||||
@return The generated code challenge.
|
||||
@details Generate a secure code verifier to pass into this method with
|
||||
@c OIDAuthorizationRequest.generateCodeVerifier. The matching @c #codeChallengeMethod for
|
||||
@c #codeChallenge%s created by this method is
|
||||
::OIDOAuthorizationRequestCodeChallengeMethodS256.
|
||||
@see https://tools.ietf.org/html/rfc7636#section-4.1
|
||||
*/
|
||||
+ (nullable NSString *)codeChallengeS256ForVerifier:(nullable NSString *)codeVerifier;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,351 +0,0 @@
|
||||
/*! @file OIDAuthorizationRequest.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDAuthorizationRequest.h"
|
||||
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDScopeUtilities.h"
|
||||
#import "OIDServiceConfiguration.h"
|
||||
#import "OIDTokenUtilities.h"
|
||||
#import "OIDURLQueryComponent.h"
|
||||
|
||||
/*! @brief The key for the @c configuration property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kConfigurationKey = @"configuration";
|
||||
|
||||
/*! @brief Key used to encode the @c responseType property for @c NSSecureCoding, and on the URL
|
||||
request.
|
||||
*/
|
||||
static NSString *const kResponseTypeKey = @"response_type";
|
||||
|
||||
/*! @brief Key used to encode the @c clientID property for @c NSSecureCoding, and on the URL
|
||||
request.
|
||||
*/
|
||||
static NSString *const kClientIDKey = @"client_id";
|
||||
|
||||
/*! @brief Key used to encode the @c clientSecret property for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kClientSecretKey = @"client_secret";
|
||||
|
||||
/*! @brief Key used to encode the @c scope property for @c NSSecureCoding, and on the URL request.
|
||||
*/
|
||||
static NSString *const kScopeKey = @"scope";
|
||||
|
||||
/*! @brief Key used to encode the @c redirectURL property for @c NSSecureCoding, and on the URL
|
||||
request.
|
||||
*/
|
||||
static NSString *const kRedirectURLKey = @"redirect_uri";
|
||||
|
||||
/*! @brief Key used to encode the @c state property for @c NSSecureCoding, and on the URL request.
|
||||
*/
|
||||
static NSString *const kStateKey = @"state";
|
||||
|
||||
/*! @brief Key used to encode the @c nonce property for @c NSSecureCoding, and on the URL request.
|
||||
*/
|
||||
static NSString *const kNonceKey = @"nonce";
|
||||
|
||||
/*! @brief Key used to encode the @c codeVerifier property for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kCodeVerifierKey = @"code_verifier";
|
||||
|
||||
/*! @brief Key used to send the @c codeChallenge on the URL request.
|
||||
*/
|
||||
static NSString *const kCodeChallengeKey = @"code_challenge";
|
||||
|
||||
/*! @brief Key used to send the @c codeChallengeMethod on the URL request.
|
||||
*/
|
||||
static NSString *const kCodeChallengeMethodKey = @"code_challenge_method";
|
||||
|
||||
/*! @brief Key used to encode the @c additionalParameters property for
|
||||
@c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kAdditionalParametersKey = @"additionalParameters";
|
||||
|
||||
/*! @brief Number of random bytes generated for the @ state.
|
||||
*/
|
||||
static NSUInteger const kStateSizeBytes = 32;
|
||||
|
||||
/*! @brief Number of random bytes generated for the @ codeVerifier.
|
||||
*/
|
||||
static NSUInteger const kCodeVerifierBytes = 32;
|
||||
|
||||
/*! @brief Assertion text for unsupported response types.
|
||||
*/
|
||||
static NSString *const OIDOAuthUnsupportedResponseTypeMessage =
|
||||
@"The response_type \"%@\" isn't supported. AppAuth only supports the \"code\" or \"code id_token\" response_type.";
|
||||
|
||||
/*! @brief Code challenge request method.
|
||||
*/
|
||||
NSString *const OIDOAuthorizationRequestCodeChallengeMethodS256 = @"S256";
|
||||
|
||||
@implementation OIDAuthorizationRequest
|
||||
|
||||
- (instancetype)init
|
||||
OID_UNAVAILABLE_USE_INITIALIZER(
|
||||
@selector(initWithConfiguration:
|
||||
clientId:
|
||||
scopes:
|
||||
redirectURL:
|
||||
responseType:
|
||||
additionalParameters:)
|
||||
)
|
||||
|
||||
/*! @brief Check if the response type is one AppAuth supports
|
||||
@remarks AppAuth only supports the `code` and `code id_token` response types.
|
||||
@see https://github.com/openid/AppAuth-iOS/issues/98
|
||||
@see https://github.com/openid/AppAuth-iOS/issues/292
|
||||
*/
|
||||
+ (BOOL)isSupportedResponseType:(NSString *)responseType
|
||||
{
|
||||
NSString *codeIdToken = [@[OIDResponseTypeCode, OIDResponseTypeIDToken]
|
||||
componentsJoinedByString:@" "];
|
||||
NSString *idTokenCode = [@[OIDResponseTypeIDToken, OIDResponseTypeCode]
|
||||
componentsJoinedByString:@" "];
|
||||
|
||||
return [responseType isEqualToString:OIDResponseTypeCode]
|
||||
|| [responseType isEqualToString:codeIdToken]
|
||||
|| [responseType isEqualToString:idTokenCode];
|
||||
}
|
||||
|
||||
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
clientId:(NSString *)clientID
|
||||
clientSecret:(nullable NSString *)clientSecret
|
||||
scope:(nullable NSString *)scope
|
||||
redirectURL:(NSURL *)redirectURL
|
||||
responseType:(NSString *)responseType
|
||||
state:(nullable NSString *)state
|
||||
nonce:(nullable NSString *)nonce
|
||||
codeVerifier:(nullable NSString *)codeVerifier
|
||||
codeChallenge:(nullable NSString *)codeChallenge
|
||||
codeChallengeMethod:(nullable NSString *)codeChallengeMethod
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_configuration = [configuration copy];
|
||||
_clientID = [clientID copy];
|
||||
_clientSecret = [clientSecret copy];
|
||||
_scope = [scope copy];
|
||||
_redirectURL = [redirectURL copy];
|
||||
_responseType = [responseType copy];
|
||||
if (![[self class] isSupportedResponseType:_responseType]) {
|
||||
NSAssert(NO, OIDOAuthUnsupportedResponseTypeMessage, _responseType);
|
||||
return nil;
|
||||
}
|
||||
_state = [state copy];
|
||||
_nonce = [nonce copy];
|
||||
_codeVerifier = [codeVerifier copy];
|
||||
_codeChallenge = [codeChallenge copy];
|
||||
_codeChallengeMethod = [codeChallengeMethod copy];
|
||||
|
||||
_additionalParameters =
|
||||
[[NSDictionary alloc] initWithDictionary:additionalParameters copyItems:YES];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)
|
||||
initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
clientId:(NSString *)clientID
|
||||
clientSecret:(NSString *)clientSecret
|
||||
scopes:(nullable NSArray<NSString *> *)scopes
|
||||
redirectURL:(NSURL *)redirectURL
|
||||
responseType:(NSString *)responseType
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters {
|
||||
|
||||
// generates PKCE code verifier and challenge
|
||||
NSString *codeVerifier = [[self class] generateCodeVerifier];
|
||||
NSString *codeChallenge = [[self class] codeChallengeS256ForVerifier:codeVerifier];
|
||||
|
||||
return [self initWithConfiguration:configuration
|
||||
clientId:clientID
|
||||
clientSecret:clientSecret
|
||||
scope:[OIDScopeUtilities scopesWithArray:scopes]
|
||||
redirectURL:redirectURL
|
||||
responseType:responseType
|
||||
state:[[self class] generateState]
|
||||
nonce:[[self class] generateState]
|
||||
codeVerifier:codeVerifier
|
||||
codeChallenge:codeChallenge
|
||||
codeChallengeMethod:OIDOAuthorizationRequestCodeChallengeMethodS256
|
||||
additionalParameters:additionalParameters];
|
||||
}
|
||||
|
||||
- (instancetype)
|
||||
initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
clientId:(NSString *)clientID
|
||||
scopes:(nullable NSArray<NSString *> *)scopes
|
||||
redirectURL:(NSURL *)redirectURL
|
||||
responseType:(NSString *)responseType
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters {
|
||||
return [self initWithConfiguration:configuration
|
||||
clientId:clientID
|
||||
clientSecret:nil
|
||||
scopes:scopes
|
||||
redirectURL:redirectURL
|
||||
responseType:responseType
|
||||
additionalParameters:additionalParameters];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
// The documentation for NSCopying specifically advises us to return a reference to the original
|
||||
// instance in the case where instances are immutable (as ours is):
|
||||
// "Implement NSCopying by retaining the original instead of creating a new copy when the class
|
||||
// and its contents are immutable."
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
OIDServiceConfiguration *configuration =
|
||||
[aDecoder decodeObjectOfClass:[OIDServiceConfiguration class]
|
||||
forKey:kConfigurationKey];
|
||||
NSString *responseType = [aDecoder decodeObjectOfClass:[NSString class] forKey:kResponseTypeKey];
|
||||
NSString *clientID = [aDecoder decodeObjectOfClass:[NSString class] forKey:kClientIDKey];
|
||||
NSString *clientSecret = [aDecoder decodeObjectOfClass:[NSString class] forKey:kClientSecretKey];
|
||||
NSString *scope = [aDecoder decodeObjectOfClass:[NSString class] forKey:kScopeKey];
|
||||
NSURL *redirectURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:kRedirectURLKey];
|
||||
NSString *state = [aDecoder decodeObjectOfClass:[NSString class] forKey:kStateKey];
|
||||
NSString *nonce = [aDecoder decodeObjectOfClass:[NSString class] forKey:kNonceKey];
|
||||
NSString *codeVerifier = [aDecoder decodeObjectOfClass:[NSString class] forKey:kCodeVerifierKey];
|
||||
NSString *codeChallenge =
|
||||
[aDecoder decodeObjectOfClass:[NSString class] forKey:kCodeChallengeKey];
|
||||
NSString *codeChallengeMethod =
|
||||
[aDecoder decodeObjectOfClass:[NSString class] forKey:kCodeChallengeMethodKey];
|
||||
NSSet *additionalParameterCodingClasses = [NSSet setWithArray:@[
|
||||
[NSDictionary class],
|
||||
[NSString class]
|
||||
]];
|
||||
NSDictionary *additionalParameters =
|
||||
[aDecoder decodeObjectOfClasses:additionalParameterCodingClasses
|
||||
forKey:kAdditionalParametersKey];
|
||||
|
||||
self = [self initWithConfiguration:configuration
|
||||
clientId:clientID
|
||||
clientSecret:clientSecret
|
||||
scope:scope
|
||||
redirectURL:redirectURL
|
||||
responseType:responseType
|
||||
state:state
|
||||
nonce:nonce
|
||||
codeVerifier:codeVerifier
|
||||
codeChallenge:codeChallenge
|
||||
codeChallengeMethod:codeChallengeMethod
|
||||
additionalParameters:additionalParameters];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[aCoder encodeObject:_configuration forKey:kConfigurationKey];
|
||||
[aCoder encodeObject:_responseType forKey:kResponseTypeKey];
|
||||
[aCoder encodeObject:_clientID forKey:kClientIDKey];
|
||||
[aCoder encodeObject:_clientSecret forKey:kClientSecretKey];
|
||||
[aCoder encodeObject:_scope forKey:kScopeKey];
|
||||
[aCoder encodeObject:_redirectURL forKey:kRedirectURLKey];
|
||||
[aCoder encodeObject:_state forKey:kStateKey];
|
||||
[aCoder encodeObject:_nonce forKey:kNonceKey];
|
||||
[aCoder encodeObject:_codeVerifier forKey:kCodeVerifierKey];
|
||||
[aCoder encodeObject:_codeChallenge forKey:kCodeChallengeKey];
|
||||
[aCoder encodeObject:_codeChallengeMethod forKey:kCodeChallengeMethodKey];
|
||||
[aCoder encodeObject:_additionalParameters forKey:kAdditionalParametersKey];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject overrides
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, request: %@>",
|
||||
NSStringFromClass([self class]),
|
||||
(void *)self,
|
||||
self.authorizationRequestURL];
|
||||
}
|
||||
|
||||
#pragma mark - State and PKCE verifier/challenge generation Methods
|
||||
|
||||
+ (nullable NSString *)generateCodeVerifier {
|
||||
return [OIDTokenUtilities randomURLSafeStringWithSize:kCodeVerifierBytes];
|
||||
}
|
||||
|
||||
+ (nullable NSString *)generateState {
|
||||
return [OIDTokenUtilities randomURLSafeStringWithSize:kStateSizeBytes];
|
||||
}
|
||||
|
||||
+ (nullable NSString *)codeChallengeS256ForVerifier:(NSString *)codeVerifier {
|
||||
if (!codeVerifier) {
|
||||
return nil;
|
||||
}
|
||||
// generates the code_challenge per spec https://tools.ietf.org/html/rfc7636#section-4.2
|
||||
// code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
|
||||
// NB. the ASCII conversion on the code_verifier entropy was done at time of generation.
|
||||
NSData *sha256Verifier = [OIDTokenUtilities sha256:codeVerifier];
|
||||
return [OIDTokenUtilities encodeBase64urlNoPadding:sha256Verifier];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSURL *)authorizationRequestURL {
|
||||
OIDURLQueryComponent *query = [[OIDURLQueryComponent alloc] init];
|
||||
|
||||
// Required parameters.
|
||||
[query addParameter:kResponseTypeKey value:_responseType];
|
||||
[query addParameter:kClientIDKey value:_clientID];
|
||||
|
||||
// Add any additional parameters the client has specified.
|
||||
[query addParameters:_additionalParameters];
|
||||
|
||||
// Add optional parameters, as applicable.
|
||||
if (_redirectURL) {
|
||||
[query addParameter:kRedirectURLKey value:_redirectURL.absoluteString];
|
||||
}
|
||||
if (_scope) {
|
||||
[query addParameter:kScopeKey value:_scope];
|
||||
}
|
||||
if (_state) {
|
||||
[query addParameter:kStateKey value:_state];
|
||||
}
|
||||
if (_nonce) {
|
||||
[query addParameter:kNonceKey value:_nonce];
|
||||
}
|
||||
if (_codeChallenge) {
|
||||
[query addParameter:kCodeChallengeKey value:_codeChallenge];
|
||||
}
|
||||
if (_codeChallengeMethod) {
|
||||
[query addParameter:kCodeChallengeMethodKey value:_codeChallengeMethod];
|
||||
}
|
||||
|
||||
// Construct the URL:
|
||||
return [query URLByReplacingQueryInURL:_configuration.authorizationEndpoint];
|
||||
}
|
||||
|
||||
#pragma mark - OIDExternalUserAgentRequest
|
||||
|
||||
- (NSURL *)externalUserAgentRequestURL {
|
||||
return [self authorizationRequestURL];
|
||||
}
|
||||
|
||||
- (NSString *)redirectScheme {
|
||||
return [[self redirectURL] scheme];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,128 +0,0 @@
|
||||
/*! @file OIDAuthorizationResponse.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class OIDAuthorizationRequest;
|
||||
@class OIDTokenRequest;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Represents the response to an authorization request.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.1
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthResponse
|
||||
*/
|
||||
@interface OIDAuthorizationResponse : NSObject <NSCopying, NSSecureCoding>
|
||||
|
||||
/*! @brief The request which was serviced.
|
||||
*/
|
||||
@property(nonatomic, readonly) OIDAuthorizationRequest *request;
|
||||
|
||||
/*! @brief The authorization code generated by the authorization server.
|
||||
@discussion Set when the response_type requested includes 'code'.
|
||||
@remarks code
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *authorizationCode;
|
||||
|
||||
/*! @brief REQUIRED if the "state" parameter was present in the client authorization request. The
|
||||
exact value received from the client.
|
||||
@remarks state
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *state;
|
||||
|
||||
/*! @brief The access token generated by the authorization server.
|
||||
@discussion Set when the response_type requested includes 'token'.
|
||||
@remarks access_token
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthResponse
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *accessToken;
|
||||
|
||||
/*! @brief The approximate expiration date & time of the access token.
|
||||
@discussion Set when the response_type requested includes 'token'.
|
||||
@remarks expires_in
|
||||
@seealso OIDAuthorizationResponse.accessToken
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthResponse
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSDate *accessTokenExpirationDate;
|
||||
|
||||
/*! @brief Typically "Bearer" when present. Otherwise, another token_type value that the Client has
|
||||
negotiated with the Authorization Server.
|
||||
@discussion Set when the response_type requested includes 'token'.
|
||||
@remarks token_type
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthResponse
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *tokenType;
|
||||
|
||||
/*! @brief ID Token value associated with the authenticated session.
|
||||
@discussion Set when the response_type requested includes 'id_token'.
|
||||
@remarks id_token
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthResponse
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *idToken;
|
||||
|
||||
/*! @brief The scope of the access token. OPTIONAL, if identical to the scopes requested, otherwise,
|
||||
REQUIRED.
|
||||
@remarks scope
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *scope;
|
||||
|
||||
/*! @brief Additional parameters returned from the authorization server.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSDictionary<NSString *, NSObject<NSCopying> *> *additionalParameters;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use initWithRequest:parameters:.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Designated initializer.
|
||||
@param request The serviced request.
|
||||
@param parameters The decoded parameters returned from the Authorization Server.
|
||||
@remarks Known parameters are extracted from the @c parameters parameter and the normative
|
||||
properties are populated. Non-normative parameters are placed in the
|
||||
@c #additionalParameters dictionary.
|
||||
*/
|
||||
- (instancetype)initWithRequest:(OIDAuthorizationRequest *)request
|
||||
parameters:(NSDictionary<NSString *, NSObject<NSCopying> *> *)parameters
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/*! @brief Creates a token request suitable for exchanging an authorization code for an access
|
||||
token.
|
||||
@return A @c OIDTokenRequest suitable for exchanging an authorization code for an access
|
||||
token.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
*/
|
||||
- (nullable OIDTokenRequest *)tokenExchangeRequest;
|
||||
|
||||
/*! @brief Creates a token request suitable for exchanging an authorization code for an access
|
||||
token.
|
||||
@param additionalParameters Additional parameters for the token request.
|
||||
@return A @c OIDTokenRequest suitable for exchanging an authorization code for an access
|
||||
token.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
*/
|
||||
- (nullable OIDTokenRequest *)tokenExchangeRequestWithAdditionalParameters:
|
||||
(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,210 +0,0 @@
|
||||
/*! @file OIDAuthorizationResponse.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDAuthorizationResponse.h"
|
||||
|
||||
#import "OIDAuthorizationRequest.h"
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDError.h"
|
||||
#import "OIDFieldMapping.h"
|
||||
#import "OIDTokenRequest.h"
|
||||
#import "OIDTokenUtilities.h"
|
||||
|
||||
/*! @brief The key for the @c authorizationCode property in the incoming parameters and for
|
||||
@c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kAuthorizationCodeKey = @"code";
|
||||
|
||||
/*! @brief The key for the @c state property in the incoming parameters and for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kStateKey = @"state";
|
||||
|
||||
/*! @brief The key for the @c accessToken property in the incoming parameters and for
|
||||
@c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kAccessTokenKey = @"access_token";
|
||||
|
||||
/*! @brief The key for the @c accessTokenExpirationDate property in the incoming parameters and for
|
||||
@c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kExpiresInKey = @"expires_in";
|
||||
|
||||
/*! @brief The key for the @c tokenType property in the incoming parameters and for
|
||||
@c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kTokenTypeKey = @"token_type";
|
||||
|
||||
/*! @brief The key for the @c idToken property in the incoming parameters and for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kIDTokenKey = @"id_token";
|
||||
|
||||
/*! @brief The key for the @c scope property in the incoming parameters and for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kScopeKey = @"scope";
|
||||
|
||||
/*! @brief Key used to encode the @c additionalParameters property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kAdditionalParametersKey = @"additionalParameters";
|
||||
|
||||
/*! @brief Key used to encode the @c request property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kRequestKey = @"request";
|
||||
|
||||
/*! @brief The exception thrown when a developer tries to create a token exchange request from an
|
||||
authorization request with no authorization code.
|
||||
*/
|
||||
static NSString *const kTokenExchangeRequestException =
|
||||
@"Attempted to create a token exchange request from an authorization response with no "
|
||||
"authorization code.";
|
||||
|
||||
@implementation OIDAuthorizationResponse
|
||||
|
||||
/*! @brief Returns a mapping of incoming parameters to instance variables.
|
||||
@return A mapping of incoming parameters to instance variables.
|
||||
*/
|
||||
+ (NSDictionary<NSString *, OIDFieldMapping *> *)fieldMap {
|
||||
static NSMutableDictionary<NSString *, OIDFieldMapping *> *fieldMap;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
fieldMap = [NSMutableDictionary dictionary];
|
||||
fieldMap[kStateKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_state" type:[NSString class]];
|
||||
fieldMap[kAuthorizationCodeKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_authorizationCode" type:[NSString class]];
|
||||
fieldMap[kAccessTokenKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_accessToken" type:[NSString class]];
|
||||
fieldMap[kExpiresInKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_accessTokenExpirationDate"
|
||||
type:[NSDate class]
|
||||
conversion:^id _Nullable(NSObject *_Nullable value) {
|
||||
if (![value isKindOfClass:[NSNumber class]]) {
|
||||
return value;
|
||||
}
|
||||
NSNumber *valueAsNumber = (NSNumber *)value;
|
||||
return [NSDate dateWithTimeIntervalSinceNow:[valueAsNumber longLongValue]];
|
||||
}];
|
||||
fieldMap[kTokenTypeKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_tokenType" type:[NSString class]];
|
||||
fieldMap[kIDTokenKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_idToken" type:[NSString class]];
|
||||
fieldMap[kScopeKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_scope" type:[NSString class]];
|
||||
});
|
||||
return fieldMap;
|
||||
}
|
||||
|
||||
#pragma mark - Initializers
|
||||
|
||||
- (instancetype)init
|
||||
OID_UNAVAILABLE_USE_INITIALIZER(@selector(initWithRequest:parameters:))
|
||||
|
||||
- (instancetype)initWithRequest:(OIDAuthorizationRequest *)request
|
||||
parameters:(NSDictionary<NSString *, NSObject<NSCopying> *> *)parameters {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_request = [request copy];
|
||||
NSDictionary<NSString *, NSObject<NSCopying> *> *additionalParameters =
|
||||
[OIDFieldMapping remainingParametersWithMap:[[self class] fieldMap]
|
||||
parameters:parameters
|
||||
instance:self];
|
||||
_additionalParameters = additionalParameters;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
// The documentation for NSCopying specifically advises us to return a reference to the original
|
||||
// instance in the case where instances are immutable (as ours is):
|
||||
// "Implement NSCopying by retaining the original instead of creating a new copy when the class
|
||||
// and its contents are immutable."
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
OIDAuthorizationRequest *request =
|
||||
[aDecoder decodeObjectOfClass:[OIDAuthorizationRequest class] forKey:kRequestKey];
|
||||
self = [self initWithRequest:request parameters:@{ }];
|
||||
if (self) {
|
||||
[OIDFieldMapping decodeWithCoder:aDecoder map:[[self class] fieldMap] instance:self];
|
||||
_additionalParameters = [aDecoder decodeObjectOfClasses:[OIDFieldMapping JSONTypes]
|
||||
forKey:kAdditionalParametersKey];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[aCoder encodeObject:_request forKey:kRequestKey];
|
||||
[OIDFieldMapping encodeWithCoder:aCoder map:[[self class] fieldMap] instance:self];
|
||||
[aCoder encodeObject:_additionalParameters forKey:kAdditionalParametersKey];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject overrides
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, authorizationCode: %@, state: \"%@\", accessToken: "
|
||||
"\"%@\", accessTokenExpirationDate: %@, tokenType: %@, "
|
||||
"idToken: \"%@\", scope: \"%@\", additionalParameters: %@, "
|
||||
"request: %@>",
|
||||
NSStringFromClass([self class]),
|
||||
(void *)self,
|
||||
_authorizationCode,
|
||||
_state,
|
||||
[OIDTokenUtilities redact:_accessToken],
|
||||
_accessTokenExpirationDate,
|
||||
_tokenType,
|
||||
[OIDTokenUtilities redact:_idToken],
|
||||
_scope,
|
||||
_additionalParameters,
|
||||
_request];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (OIDTokenRequest *)tokenExchangeRequest {
|
||||
return [self tokenExchangeRequestWithAdditionalParameters:nil];
|
||||
}
|
||||
|
||||
- (OIDTokenRequest *)tokenExchangeRequestWithAdditionalParameters:
|
||||
(NSDictionary<NSString *, NSString *> *)additionalParameters {
|
||||
// TODO: add a unit test to confirm exception is thrown when expected and the request is created
|
||||
// with the correct parameters.
|
||||
if (!_authorizationCode) {
|
||||
[NSException raise:kTokenExchangeRequestException
|
||||
format:kTokenExchangeRequestException];
|
||||
}
|
||||
return [[OIDTokenRequest alloc] initWithConfiguration:_request.configuration
|
||||
grantType:OIDGrantTypeAuthorizationCode
|
||||
authorizationCode:_authorizationCode
|
||||
redirectURL:_request.redirectURL
|
||||
clientID:_request.clientID
|
||||
clientSecret:_request.clientSecret
|
||||
scope:nil
|
||||
refreshToken:nil
|
||||
codeVerifier:_request.codeVerifier
|
||||
additionalParameters:additionalParameters];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,170 +0,0 @@
|
||||
/*! @file OIDAuthorizationService.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class OIDAuthorization;
|
||||
@class OIDAuthorizationRequest;
|
||||
@class OIDAuthorizationResponse;
|
||||
@class OIDEndSessionRequest;
|
||||
@class OIDEndSessionResponse;
|
||||
@class OIDRegistrationRequest;
|
||||
@class OIDRegistrationResponse;
|
||||
@class OIDServiceConfiguration;
|
||||
@class OIDTokenRequest;
|
||||
@class OIDTokenResponse;
|
||||
@protocol OIDExternalUserAgent;
|
||||
@protocol OIDExternalUserAgentSession;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Represents the type of block used as a callback for creating a service configuration from
|
||||
a remote OpenID Connect Discovery document.
|
||||
@param configuration The service configuration, if available.
|
||||
@param error The error if an error occurred.
|
||||
*/
|
||||
typedef void (^OIDDiscoveryCallback)(OIDServiceConfiguration *_Nullable configuration,
|
||||
NSError *_Nullable error);
|
||||
|
||||
/*! @brief Represents the type of block used as a callback for various methods of
|
||||
@c OIDAuthorizationService.
|
||||
@param authorizationResponse The authorization response, if available.
|
||||
@param error The error if an error occurred.
|
||||
*/
|
||||
typedef void (^OIDAuthorizationCallback)(OIDAuthorizationResponse *_Nullable authorizationResponse,
|
||||
NSError *_Nullable error);
|
||||
|
||||
/*! @brief Block used as a callback for the end-session request of @c OIDAuthorizationService.
|
||||
@param endSessionResponse The end-session response, if available.
|
||||
@param error The error if an error occurred.
|
||||
*/
|
||||
typedef void (^OIDEndSessionCallback)(OIDEndSessionResponse *_Nullable endSessionResponse,
|
||||
NSError *_Nullable error);
|
||||
|
||||
/*! @brief Represents the type of block used as a callback for various methods of
|
||||
@c OIDAuthorizationService.
|
||||
@param tokenResponse The token response, if available.
|
||||
@param error The error if an error occurred.
|
||||
*/
|
||||
typedef void (^OIDTokenCallback)(OIDTokenResponse *_Nullable tokenResponse,
|
||||
NSError *_Nullable error);
|
||||
|
||||
/*! @brief Represents the type of dictionary used to specify additional querystring parameters
|
||||
when making authorization or token endpoint requests.
|
||||
*/
|
||||
typedef NSDictionary<NSString *, NSString *> *_Nullable OIDTokenEndpointParameters;
|
||||
|
||||
/*! @brief Represents the type of block used as a callback for various methods of
|
||||
@c OIDAuthorizationService.
|
||||
@param registrationResponse The registration response, if available.
|
||||
@param error The error if an error occurred.
|
||||
*/
|
||||
typedef void (^OIDRegistrationCompletion)(OIDRegistrationResponse *_Nullable registrationResponse,
|
||||
NSError *_Nullable error);
|
||||
|
||||
/*! @brief Performs various OAuth and OpenID Connect related calls via the user agent or
|
||||
\NSURLSession.
|
||||
*/
|
||||
@interface OIDAuthorizationService : NSObject
|
||||
|
||||
/*! @brief The service's configuration.
|
||||
@remarks Each authorization service is initialized with a configuration. This configuration
|
||||
specifies how to connect to a particular OAuth provider. Clients should use separate
|
||||
authorization service instances for each provider they wish to integrate with.
|
||||
Configurations may be created manually, or via an OpenID Connect Discovery Document.
|
||||
*/
|
||||
@property(nonatomic, readonly) OIDServiceConfiguration *configuration;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. This class should not be initialized.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Convenience method for creating an authorization service configuration from an OpenID
|
||||
Connect compliant issuer URL.
|
||||
@param issuerURL The service provider's OpenID Connect issuer.
|
||||
@param completion A block which will be invoked when the authorization service configuration has
|
||||
been created, or when an error has occurred.
|
||||
@see https://openid.net/specs/openid-connect-discovery-1_0.html
|
||||
*/
|
||||
+ (void)discoverServiceConfigurationForIssuer:(NSURL *)issuerURL
|
||||
completion:(OIDDiscoveryCallback)completion;
|
||||
|
||||
|
||||
/*! @brief Convenience method for creating an authorization service configuration from an OpenID
|
||||
Connect compliant identity provider's discovery document.
|
||||
@param discoveryURL The URL of the service provider's OpenID Connect discovery document.
|
||||
@param completion A block which will be invoked when the authorization service configuration has
|
||||
been created, or when an error has occurred.
|
||||
@see https://openid.net/specs/openid-connect-discovery-1_0.html
|
||||
*/
|
||||
+ (void)discoverServiceConfigurationForDiscoveryURL:(NSURL *)discoveryURL
|
||||
completion:(OIDDiscoveryCallback)completion;
|
||||
|
||||
/*! @brief Perform an authorization flow using a generic flow shim.
|
||||
@param request The authorization request.
|
||||
@param externalUserAgent Generic external user-agent that can present an authorization
|
||||
request.
|
||||
@param callback The method called when the request has completed or failed.
|
||||
@return A @c OIDExternalUserAgentSession instance which will terminate when it
|
||||
receives a @c OIDExternalUserAgentSession.cancel message, or after processing a
|
||||
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message.
|
||||
*/
|
||||
+ (id<OIDExternalUserAgentSession>) presentAuthorizationRequest:(OIDAuthorizationRequest *)request
|
||||
externalUserAgent:(id<OIDExternalUserAgent>)externalUserAgent
|
||||
callback:(OIDAuthorizationCallback)callback;
|
||||
|
||||
/*! @brief Perform a logout request.
|
||||
@param request The end-session logout request.
|
||||
@param externalUserAgent Generic external user-agent that can present user-agent requests.
|
||||
@param callback The method called when the request has completed or failed.
|
||||
@return A @c OIDExternalUserAgentSession instance which will terminate when it
|
||||
receives a @c OIDExternalUserAgentSession.cancel message, or after processing a
|
||||
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message.
|
||||
@see http://openid.net/specs/openid-connect-session-1_0.html#RPLogout
|
||||
*/
|
||||
+ (id<OIDExternalUserAgentSession>)
|
||||
presentEndSessionRequest:(OIDEndSessionRequest *)request
|
||||
externalUserAgent:(id<OIDExternalUserAgent>)externalUserAgent
|
||||
callback:(OIDEndSessionCallback)callback;
|
||||
|
||||
/*! @brief Performs a token request.
|
||||
@param request The token request.
|
||||
@param callback The method called when the request has completed or failed.
|
||||
*/
|
||||
+ (void)performTokenRequest:(OIDTokenRequest *)request callback:(OIDTokenCallback)callback;
|
||||
|
||||
/*! @brief Performs a token request.
|
||||
@param request The token request.
|
||||
@param authorizationResponse The original authorization response related to this token request.
|
||||
@param callback The method called when the request has completed or failed.
|
||||
*/
|
||||
+ (void)performTokenRequest:(OIDTokenRequest *)request
|
||||
originalAuthorizationResponse:(OIDAuthorizationResponse *_Nullable)authorizationResponse
|
||||
callback:(OIDTokenCallback)callback;
|
||||
|
||||
/*! @brief Performs a registration request.
|
||||
@param request The registration request.
|
||||
@param completion The method called when the request has completed or failed.
|
||||
*/
|
||||
+ (void)performRegistrationRequest:(OIDRegistrationRequest *)request
|
||||
completion:(OIDRegistrationCompletion)completion;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,790 +0,0 @@
|
||||
/*! @file OIDAuthorizationService.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDAuthorizationService.h"
|
||||
|
||||
#import "OIDAuthorizationRequest.h"
|
||||
#import "OIDAuthorizationResponse.h"
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDEndSessionRequest.h"
|
||||
#import "OIDEndSessionResponse.h"
|
||||
#import "OIDErrorUtilities.h"
|
||||
#import "OIDExternalUserAgent.h"
|
||||
#import "OIDExternalUserAgentSession.h"
|
||||
#import "OIDIDToken.h"
|
||||
#import "OIDRegistrationRequest.h"
|
||||
#import "OIDRegistrationResponse.h"
|
||||
#import "OIDServiceConfiguration.h"
|
||||
#import "OIDServiceDiscovery.h"
|
||||
#import "OIDTokenRequest.h"
|
||||
#import "OIDTokenResponse.h"
|
||||
#import "OIDURLQueryComponent.h"
|
||||
#import "OIDURLSessionProvider.h"
|
||||
|
||||
/*! @brief Path appended to an OpenID Connect issuer for discovery
|
||||
@see https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
|
||||
*/
|
||||
static NSString *const kOpenIDConfigurationWellKnownPath = @".well-known/openid-configuration";
|
||||
|
||||
/*! @brief Max allowable iat (Issued At) time skew
|
||||
@see https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
|
||||
*/
|
||||
static int const kOIDAuthorizationSessionIATMaxSkew = 600;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OIDAuthorizationSession : NSObject<OIDExternalUserAgentSession>
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithRequest:(OIDAuthorizationRequest *)request
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OIDAuthorizationSession {
|
||||
OIDAuthorizationRequest *_request;
|
||||
id<OIDExternalUserAgent> _externalUserAgent;
|
||||
OIDAuthorizationCallback _pendingauthorizationFlowCallback;
|
||||
}
|
||||
|
||||
- (instancetype)initWithRequest:(OIDAuthorizationRequest *)request {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_request = [request copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)presentAuthorizationWithExternalUserAgent:(id<OIDExternalUserAgent>)externalUserAgent
|
||||
callback:(OIDAuthorizationCallback)authorizationFlowCallback {
|
||||
_externalUserAgent = externalUserAgent;
|
||||
_pendingauthorizationFlowCallback = authorizationFlowCallback;
|
||||
BOOL authorizationFlowStarted =
|
||||
[_externalUserAgent presentExternalUserAgentRequest:_request session:self];
|
||||
if (!authorizationFlowStarted) {
|
||||
NSError *safariError = [OIDErrorUtilities errorWithCode:OIDErrorCodeSafariOpenError
|
||||
underlyingError:nil
|
||||
description:@"Unable to open Safari."];
|
||||
[self didFinishWithResponse:nil error:safariError];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancel {
|
||||
[self cancelWithCompletion:nil];
|
||||
}
|
||||
|
||||
- (void)cancelWithCompletion:(nullable void (^)(void))completion {
|
||||
[_externalUserAgent dismissExternalUserAgentAnimated:YES completion:^{
|
||||
NSError *error = [OIDErrorUtilities errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
|
||||
underlyingError:nil
|
||||
description:@"Authorization flow was cancelled."];
|
||||
[self didFinishWithResponse:nil error:error];
|
||||
if (completion) completion();
|
||||
}];
|
||||
}
|
||||
|
||||
/*! @brief Does the redirection URL equal another URL down to the path component?
|
||||
@param URL The first redirect URI to compare.
|
||||
@param redirectionURL The second redirect URI to compare.
|
||||
@return YES if the URLs match down to the path level (query params are ignored).
|
||||
*/
|
||||
+ (BOOL)URL:(NSURL *)URL matchesRedirectionURL:(NSURL *)redirectionURL {
|
||||
NSURL *standardizedURL = [URL standardizedURL];
|
||||
NSURL *standardizedRedirectURL = [redirectionURL standardizedURL];
|
||||
|
||||
return [standardizedURL.scheme caseInsensitiveCompare:standardizedRedirectURL.scheme] == NSOrderedSame
|
||||
&& OIDIsEqualIncludingNil(standardizedURL.user, standardizedRedirectURL.user)
|
||||
&& OIDIsEqualIncludingNil(standardizedURL.password, standardizedRedirectURL.password)
|
||||
&& OIDIsEqualIncludingNil(standardizedURL.host, standardizedRedirectURL.host)
|
||||
&& OIDIsEqualIncludingNil(standardizedURL.port, standardizedRedirectURL.port)
|
||||
&& OIDIsEqualIncludingNil(standardizedURL.path, standardizedRedirectURL.path);
|
||||
}
|
||||
|
||||
- (BOOL)shouldHandleURL:(NSURL *)URL {
|
||||
return [[self class] URL:URL matchesRedirectionURL:_request.redirectURL];
|
||||
}
|
||||
|
||||
- (BOOL)resumeExternalUserAgentFlowWithURL:(NSURL *)URL {
|
||||
// rejects URLs that don't match redirect (these may be completely unrelated to the authorization)
|
||||
if (![self shouldHandleURL:URL]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
AppAuthRequestTrace(@"Authorization Response: %@", URL);
|
||||
|
||||
// checks for an invalid state
|
||||
if (!_pendingauthorizationFlowCallback) {
|
||||
[NSException raise:OIDOAuthExceptionInvalidAuthorizationFlow
|
||||
format:@"%@", OIDOAuthExceptionInvalidAuthorizationFlow, nil];
|
||||
}
|
||||
|
||||
OIDURLQueryComponent *query = [[OIDURLQueryComponent alloc] initWithURL:URL];
|
||||
|
||||
NSError *error;
|
||||
OIDAuthorizationResponse *response = nil;
|
||||
|
||||
// checks for an OAuth error response as per RFC6749 Section 4.1.2.1
|
||||
if (query.dictionaryValue[OIDOAuthErrorFieldError]) {
|
||||
error = [OIDErrorUtilities OAuthErrorWithDomain:OIDOAuthAuthorizationErrorDomain
|
||||
OAuthResponse:query.dictionaryValue
|
||||
underlyingError:nil];
|
||||
}
|
||||
|
||||
// no error, should be a valid OAuth 2.0 response
|
||||
if (!error) {
|
||||
response = [[OIDAuthorizationResponse alloc] initWithRequest:_request
|
||||
parameters:query.dictionaryValue];
|
||||
|
||||
// verifies that the state in the response matches the state in the request, or both are nil
|
||||
if (!OIDIsEqualIncludingNil(_request.state, response.state)) {
|
||||
NSMutableDictionary *userInfo = [query.dictionaryValue mutableCopy];
|
||||
userInfo[NSLocalizedDescriptionKey] =
|
||||
[NSString stringWithFormat:@"State mismatch, expecting %@ but got %@ in authorization "
|
||||
"response %@",
|
||||
_request.state,
|
||||
response.state,
|
||||
response];
|
||||
response = nil;
|
||||
error = [NSError errorWithDomain:OIDOAuthAuthorizationErrorDomain
|
||||
code:OIDErrorCodeOAuthAuthorizationClientError
|
||||
userInfo:userInfo];
|
||||
}
|
||||
}
|
||||
|
||||
[_externalUserAgent dismissExternalUserAgentAnimated:YES completion:^{
|
||||
[self didFinishWithResponse:response error:error];
|
||||
}];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)failExternalUserAgentFlowWithError:(NSError *)error {
|
||||
[self didFinishWithResponse:nil error:error];
|
||||
}
|
||||
|
||||
/*! @brief Invokes the pending callback and performs cleanup.
|
||||
@param response The authorization response, if any to return to the callback.
|
||||
@param error The error, if any, to return to the callback.
|
||||
*/
|
||||
- (void)didFinishWithResponse:(nullable OIDAuthorizationResponse *)response
|
||||
error:(nullable NSError *)error {
|
||||
OIDAuthorizationCallback callback = _pendingauthorizationFlowCallback;
|
||||
_pendingauthorizationFlowCallback = nil;
|
||||
_externalUserAgent = nil;
|
||||
if (callback) {
|
||||
callback(response, error);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface OIDEndSessionImplementation : NSObject<OIDExternalUserAgentSession> {
|
||||
// private variables
|
||||
OIDEndSessionRequest *_request;
|
||||
id<OIDExternalUserAgent> _externalUserAgent;
|
||||
OIDEndSessionCallback _pendingEndSessionCallback;
|
||||
}
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithRequest:(OIDEndSessionRequest *)request
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
@end
|
||||
|
||||
|
||||
@implementation OIDEndSessionImplementation
|
||||
|
||||
- (instancetype)initWithRequest:(OIDEndSessionRequest *)request {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_request = [request copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)presentAuthorizationWithExternalUserAgent:(id<OIDExternalUserAgent>)externalUserAgent
|
||||
callback:(OIDEndSessionCallback)authorizationFlowCallback {
|
||||
_externalUserAgent = externalUserAgent;
|
||||
_pendingEndSessionCallback = authorizationFlowCallback;
|
||||
BOOL authorizationFlowStarted =
|
||||
[_externalUserAgent presentExternalUserAgentRequest:_request session:self];
|
||||
if (!authorizationFlowStarted) {
|
||||
NSError *safariError = [OIDErrorUtilities errorWithCode:OIDErrorCodeSafariOpenError
|
||||
underlyingError:nil
|
||||
description:@"Unable to open Safari."];
|
||||
[self didFinishWithResponse:nil error:safariError];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancel {
|
||||
[self cancelWithCompletion:nil];
|
||||
}
|
||||
|
||||
- (void)cancelWithCompletion:(nullable void (^)(void))completion {
|
||||
[_externalUserAgent dismissExternalUserAgentAnimated:YES completion:^{
|
||||
NSError *error = [OIDErrorUtilities
|
||||
errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
|
||||
underlyingError:nil
|
||||
description:nil];
|
||||
[self didFinishWithResponse:nil error:error];
|
||||
if (completion) completion();
|
||||
}];
|
||||
}
|
||||
|
||||
- (BOOL)shouldHandleURL:(NSURL *)URL {
|
||||
// The logic of when to handle the URL is the same as for authorization requests: should match
|
||||
// down to the path component.
|
||||
return [[OIDAuthorizationSession class] URL:URL
|
||||
matchesRedirectionURL:_request.postLogoutRedirectURL];
|
||||
}
|
||||
|
||||
- (BOOL)resumeExternalUserAgentFlowWithURL:(NSURL *)URL {
|
||||
// rejects URLs that don't match redirect (these may be completely unrelated to the authorization)
|
||||
if (![self shouldHandleURL:URL]) {
|
||||
return NO;
|
||||
}
|
||||
// checks for an invalid state
|
||||
if (!_pendingEndSessionCallback) {
|
||||
[NSException raise:OIDOAuthExceptionInvalidAuthorizationFlow
|
||||
format:@"%@", OIDOAuthExceptionInvalidAuthorizationFlow, nil];
|
||||
}
|
||||
|
||||
|
||||
NSError *error;
|
||||
OIDEndSessionResponse *response = nil;
|
||||
|
||||
OIDURLQueryComponent *query = [[OIDURLQueryComponent alloc] initWithURL:URL];
|
||||
response = [[OIDEndSessionResponse alloc] initWithRequest:_request
|
||||
parameters:query.dictionaryValue];
|
||||
|
||||
// verifies that the state in the response matches the state in the request, or both are nil
|
||||
if (!OIDIsEqualIncludingNil(_request.state, response.state)) {
|
||||
NSMutableDictionary *userInfo = [query.dictionaryValue mutableCopy];
|
||||
userInfo[NSLocalizedDescriptionKey] =
|
||||
[NSString stringWithFormat:@"State mismatch, expecting %@ but got %@ in authorization "
|
||||
"response %@",
|
||||
_request.state,
|
||||
response.state,
|
||||
response];
|
||||
response = nil;
|
||||
error = [NSError errorWithDomain:OIDOAuthAuthorizationErrorDomain
|
||||
code:OIDErrorCodeOAuthAuthorizationClientError
|
||||
userInfo:userInfo];
|
||||
}
|
||||
|
||||
[_externalUserAgent dismissExternalUserAgentAnimated:YES completion:^{
|
||||
[self didFinishWithResponse:response error:error];
|
||||
}];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)failExternalUserAgentFlowWithError:(NSError *)error {
|
||||
[self didFinishWithResponse:nil error:error];
|
||||
}
|
||||
|
||||
/*! @brief Invokes the pending callback and performs cleanup.
|
||||
@param response The authorization response, if any to return to the callback.
|
||||
@param error The error, if any, to return to the callback.
|
||||
*/
|
||||
- (void)didFinishWithResponse:(nullable OIDEndSessionResponse *)response
|
||||
error:(nullable NSError *)error {
|
||||
OIDEndSessionCallback callback = _pendingEndSessionCallback;
|
||||
_pendingEndSessionCallback = nil;
|
||||
_externalUserAgent = nil;
|
||||
if (callback) {
|
||||
callback(response, error);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation OIDAuthorizationService
|
||||
|
||||
+ (void)discoverServiceConfigurationForIssuer:(NSURL *)issuerURL
|
||||
completion:(OIDDiscoveryCallback)completion {
|
||||
NSURL *fullDiscoveryURL =
|
||||
[issuerURL URLByAppendingPathComponent:kOpenIDConfigurationWellKnownPath];
|
||||
|
||||
[[self class] discoverServiceConfigurationForDiscoveryURL:fullDiscoveryURL
|
||||
completion:completion];
|
||||
}
|
||||
|
||||
+ (void)discoverServiceConfigurationForDiscoveryURL:(NSURL *)discoveryURL
|
||||
completion:(OIDDiscoveryCallback)completion {
|
||||
|
||||
NSURLSession *session = [OIDURLSessionProvider session];
|
||||
NSURLSessionDataTask *task =
|
||||
[session dataTaskWithURL:discoveryURL
|
||||
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||
// If we got any sort of error, just report it.
|
||||
if (error || !data) {
|
||||
NSString *errorDescription =
|
||||
[NSString stringWithFormat:@"Connection error fetching discovery document '%@': %@.",
|
||||
discoveryURL,
|
||||
error.localizedDescription];
|
||||
error = [OIDErrorUtilities errorWithCode:OIDErrorCodeNetworkError
|
||||
underlyingError:error
|
||||
description:errorDescription];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(nil, error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
NSHTTPURLResponse *urlResponse = (NSHTTPURLResponse *)response;
|
||||
|
||||
// Check for non-200 status codes.
|
||||
// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse
|
||||
if (urlResponse.statusCode != 200) {
|
||||
NSError *URLResponseError = [OIDErrorUtilities HTTPErrorWithHTTPResponse:urlResponse
|
||||
data:data];
|
||||
NSString *errorDescription =
|
||||
[NSString stringWithFormat:@"Non-200 HTTP response (%d) fetching discovery document "
|
||||
"'%@'.",
|
||||
(int)urlResponse.statusCode,
|
||||
discoveryURL];
|
||||
error = [OIDErrorUtilities errorWithCode:OIDErrorCodeNetworkError
|
||||
underlyingError:URLResponseError
|
||||
description:errorDescription];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(nil, error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Construct an OIDServiceDiscovery with the received JSON.
|
||||
OIDServiceDiscovery *discovery =
|
||||
[[OIDServiceDiscovery alloc] initWithJSONData:data error:&error];
|
||||
if (error || !discovery) {
|
||||
NSString *errorDescription =
|
||||
[NSString stringWithFormat:@"JSON error parsing document at '%@': %@",
|
||||
discoveryURL,
|
||||
error.localizedDescription];
|
||||
error = [OIDErrorUtilities errorWithCode:OIDErrorCodeNetworkError
|
||||
underlyingError:error
|
||||
description:errorDescription];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(nil, error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Create our service configuration with the discovery document and return it.
|
||||
OIDServiceConfiguration *configuration =
|
||||
[[OIDServiceConfiguration alloc] initWithDiscoveryDocument:discovery];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(configuration, nil);
|
||||
});
|
||||
}];
|
||||
[task resume];
|
||||
}
|
||||
|
||||
#pragma mark - Authorization Endpoint
|
||||
|
||||
+ (id<OIDExternalUserAgentSession>) presentAuthorizationRequest:(OIDAuthorizationRequest *)request
|
||||
externalUserAgent:(id<OIDExternalUserAgent>)externalUserAgent
|
||||
callback:(OIDAuthorizationCallback)callback {
|
||||
|
||||
AppAuthRequestTrace(@"Authorization Request: %@", request);
|
||||
|
||||
OIDAuthorizationSession *flowSession = [[OIDAuthorizationSession alloc] initWithRequest:request];
|
||||
[flowSession presentAuthorizationWithExternalUserAgent:externalUserAgent callback:callback];
|
||||
return flowSession;
|
||||
}
|
||||
|
||||
+ (id<OIDExternalUserAgentSession>)
|
||||
presentEndSessionRequest:(OIDEndSessionRequest *)request
|
||||
externalUserAgent:(id<OIDExternalUserAgent>)externalUserAgent
|
||||
callback:(OIDEndSessionCallback)callback {
|
||||
OIDEndSessionImplementation *flowSession =
|
||||
[[OIDEndSessionImplementation alloc] initWithRequest:request];
|
||||
[flowSession presentAuthorizationWithExternalUserAgent:externalUserAgent callback:callback];
|
||||
return flowSession;
|
||||
}
|
||||
|
||||
#pragma mark - Token Endpoint
|
||||
|
||||
+ (void)performTokenRequest:(OIDTokenRequest *)request callback:(OIDTokenCallback)callback {
|
||||
[[self class] performTokenRequest:request
|
||||
originalAuthorizationResponse:nil
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
+ (void)performTokenRequest:(OIDTokenRequest *)request
|
||||
originalAuthorizationResponse:(OIDAuthorizationResponse *_Nullable)authorizationResponse
|
||||
callback:(OIDTokenCallback)callback {
|
||||
|
||||
NSURLRequest *URLRequest = [request URLRequest];
|
||||
|
||||
AppAuthRequestTrace(@"Token Request: %@\nHeaders:%@\nHTTPBody: %@",
|
||||
URLRequest.URL,
|
||||
URLRequest.allHTTPHeaderFields,
|
||||
[[NSString alloc] initWithData:URLRequest.HTTPBody
|
||||
encoding:NSUTF8StringEncoding]);
|
||||
|
||||
NSURLSession *session = [OIDURLSessionProvider session];
|
||||
[[session dataTaskWithRequest:URLRequest
|
||||
completionHandler:^(NSData *_Nullable data,
|
||||
NSURLResponse *_Nullable response,
|
||||
NSError *_Nullable error) {
|
||||
if (error) {
|
||||
// A network error or server error occurred.
|
||||
NSString *errorDescription =
|
||||
[NSString stringWithFormat:@"Connection error making token request to '%@': %@.",
|
||||
URLRequest.URL,
|
||||
error.localizedDescription];
|
||||
NSError *returnedError =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeNetworkError
|
||||
underlyingError:error
|
||||
description:errorDescription];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(nil, returnedError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
NSHTTPURLResponse *HTTPURLResponse = (NSHTTPURLResponse *)response;
|
||||
NSInteger statusCode = HTTPURLResponse.statusCode;
|
||||
AppAuthRequestTrace(@"Token Response: HTTP Status %d\nHTTPBody: %@",
|
||||
(int)statusCode,
|
||||
[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
|
||||
if (statusCode != 200) {
|
||||
// A server error occurred.
|
||||
NSError *serverError =
|
||||
[OIDErrorUtilities HTTPErrorWithHTTPResponse:HTTPURLResponse data:data];
|
||||
|
||||
// HTTP 4xx may indicate an RFC6749 Section 5.2 error response, attempts to parse as such.
|
||||
if (statusCode >= 400 && statusCode < 500) {
|
||||
NSError *jsonDeserializationError;
|
||||
NSDictionary<NSString *, NSObject<NSCopying> *> *json =
|
||||
[NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonDeserializationError];
|
||||
|
||||
// If the HTTP 4xx response parses as JSON and has an 'error' key, it's an OAuth error.
|
||||
// These errors are special as they indicate a problem with the authorization grant.
|
||||
if (json[OIDOAuthErrorFieldError]) {
|
||||
NSError *oauthError =
|
||||
[OIDErrorUtilities OAuthErrorWithDomain:OIDOAuthTokenErrorDomain
|
||||
OAuthResponse:json
|
||||
underlyingError:serverError];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(nil, oauthError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Status code indicates this is an error, but not an RFC6749 Section 5.2 error.
|
||||
NSString *errorDescription =
|
||||
[NSString stringWithFormat:@"Non-200 HTTP response (%d) making token request to '%@'.",
|
||||
(int)statusCode,
|
||||
URLRequest.URL];
|
||||
NSError *returnedError =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeServerError
|
||||
underlyingError:serverError
|
||||
description:errorDescription];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(nil, returnedError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
NSError *jsonDeserializationError;
|
||||
NSDictionary<NSString *, NSObject<NSCopying> *> *json =
|
||||
[NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonDeserializationError];
|
||||
if (jsonDeserializationError) {
|
||||
// A problem occurred deserializing the response/JSON.
|
||||
NSString *errorDescription =
|
||||
[NSString stringWithFormat:@"JSON error parsing token response: %@",
|
||||
jsonDeserializationError.localizedDescription];
|
||||
NSError *returnedError =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeJSONDeserializationError
|
||||
underlyingError:jsonDeserializationError
|
||||
description:errorDescription];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(nil, returnedError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
OIDTokenResponse *tokenResponse =
|
||||
[[OIDTokenResponse alloc] initWithRequest:request parameters:json];
|
||||
if (!tokenResponse) {
|
||||
// A problem occurred constructing the token response from the JSON.
|
||||
NSError *returnedError =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeTokenResponseConstructionError
|
||||
underlyingError:jsonDeserializationError
|
||||
description:@"Token response invalid."];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(nil, returnedError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// If an ID Token is included in the response, validates the ID Token following the rules
|
||||
// in OpenID Connect Core Section 3.1.3.7 for features that AppAuth directly supports
|
||||
// (which excludes rules #1, #4, #5, #7, #8, #12, and #13). Regarding rule #6, ID Tokens
|
||||
// received by this class are received via direct communication between the Client and the Token
|
||||
// Endpoint, thus we are exercising the option to rely only on the TLS validation. AppAuth
|
||||
// has a zero dependencies policy, and verifying the JWT signature would add a dependency.
|
||||
// Users of the library are welcome to perform the JWT signature verification themselves should
|
||||
// they wish.
|
||||
if (tokenResponse.idToken) {
|
||||
OIDIDToken *idToken = [[OIDIDToken alloc] initWithIDTokenString:tokenResponse.idToken];
|
||||
if (!idToken) {
|
||||
NSError *invalidIDToken =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenParsingError
|
||||
underlyingError:nil
|
||||
description:@"ID Token parsing failed"];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(nil, invalidIDToken);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// OpenID Connect Core Section 3.1.3.7. rule #1
|
||||
// Not supported: AppAuth does not support JWT encryption.
|
||||
|
||||
// OpenID Connect Core Section 3.1.3.7. rule #2
|
||||
// Validates that the issuer in the ID Token matches that of the discovery document.
|
||||
NSURL *issuer = tokenResponse.request.configuration.issuer;
|
||||
if (issuer && ![idToken.issuer isEqual:issuer]) {
|
||||
NSError *invalidIDToken =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenFailedValidationError
|
||||
underlyingError:nil
|
||||
description:@"Issuer mismatch"];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(nil, invalidIDToken);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// OpenID Connect Core Section 3.1.3.7. rule #3 & Section 2 azp Claim
|
||||
// Validates that the aud (audience) Claim contains the client ID, or that the azp
|
||||
// (authorized party) Claim matches the client ID.
|
||||
NSString *clientID = tokenResponse.request.clientID;
|
||||
if (![idToken.audience containsObject:clientID] &&
|
||||
![idToken.claims[@"azp"] isEqualToString:clientID]) {
|
||||
NSError *invalidIDToken =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenFailedValidationError
|
||||
underlyingError:nil
|
||||
description:@"Audience mismatch"];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(nil, invalidIDToken);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// OpenID Connect Core Section 3.1.3.7. rules #4 & #5
|
||||
// Not supported.
|
||||
|
||||
// OpenID Connect Core Section 3.1.3.7. rule #6
|
||||
// As noted above, AppAuth only supports the code flow which results in direct communication
|
||||
// of the ID Token from the Token Endpoint to the Client, and we are exercising the option to
|
||||
// use TSL server validation instead of checking the token signature. Users may additionally
|
||||
// check the token signature should they wish.
|
||||
|
||||
// OpenID Connect Core Section 3.1.3.7. rules #7 & #8
|
||||
// Not applicable. See rule #6.
|
||||
|
||||
// OpenID Connect Core Section 3.1.3.7. rule #9
|
||||
// Validates that the current time is before the expiry time.
|
||||
NSTimeInterval expiresAtDifference = [idToken.expiresAt timeIntervalSinceNow];
|
||||
if (expiresAtDifference < 0) {
|
||||
NSError *invalidIDToken =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenFailedValidationError
|
||||
underlyingError:nil
|
||||
description:@"ID Token expired"];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(nil, invalidIDToken);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// OpenID Connect Core Section 3.1.3.7. rule #10
|
||||
// Validates that the issued at time is not more than +/- 10 minutes on the current time.
|
||||
NSTimeInterval issuedAtDifference = [idToken.issuedAt timeIntervalSinceNow];
|
||||
if (fabs(issuedAtDifference) > kOIDAuthorizationSessionIATMaxSkew) {
|
||||
NSString *message =
|
||||
[NSString stringWithFormat:@"Issued at time is more than %d seconds before or after "
|
||||
"the current time",
|
||||
kOIDAuthorizationSessionIATMaxSkew];
|
||||
NSError *invalidIDToken =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenFailedValidationError
|
||||
underlyingError:nil
|
||||
description:message];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(nil, invalidIDToken);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Only relevant for the authorization_code response type
|
||||
if ([tokenResponse.request.grantType isEqual:OIDGrantTypeAuthorizationCode]) {
|
||||
// OpenID Connect Core Section 3.1.3.7. rule #11
|
||||
// Validates the nonce.
|
||||
NSString *nonce = authorizationResponse.request.nonce;
|
||||
if (nonce && ![idToken.nonce isEqual:nonce]) {
|
||||
NSError *invalidIDToken =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenFailedValidationError
|
||||
underlyingError:nil
|
||||
description:@"Nonce mismatch"];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(nil, invalidIDToken);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// OpenID Connect Core Section 3.1.3.7. rules #12
|
||||
// ACR is not directly supported by AppAuth.
|
||||
|
||||
// OpenID Connect Core Section 3.1.3.7. rules #12
|
||||
// max_age is not directly supported by AppAuth.
|
||||
}
|
||||
|
||||
// Success
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(tokenResponse, nil);
|
||||
});
|
||||
}] resume];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Registration Endpoint
|
||||
|
||||
+ (void)performRegistrationRequest:(OIDRegistrationRequest *)request
|
||||
completion:(OIDRegistrationCompletion)completion {
|
||||
NSURLRequest *URLRequest = [request URLRequest];
|
||||
if (!URLRequest) {
|
||||
// A problem occurred deserializing the response/JSON.
|
||||
NSError *returnedError = [OIDErrorUtilities errorWithCode:OIDErrorCodeJSONSerializationError
|
||||
underlyingError:nil
|
||||
description:@"The registration request could not "
|
||||
"be serialized as JSON."];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(nil, returnedError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
NSURLSession *session = [OIDURLSessionProvider session];
|
||||
[[session dataTaskWithRequest:URLRequest
|
||||
completionHandler:^(NSData *_Nullable data,
|
||||
NSURLResponse *_Nullable response,
|
||||
NSError *_Nullable error) {
|
||||
if (error) {
|
||||
// A network error or server error occurred.
|
||||
NSString *errorDescription =
|
||||
[NSString stringWithFormat:@"Connection error making registration request to '%@': %@.",
|
||||
URLRequest.URL,
|
||||
error.localizedDescription];
|
||||
NSError *returnedError = [OIDErrorUtilities errorWithCode:OIDErrorCodeNetworkError
|
||||
underlyingError:error
|
||||
description:errorDescription];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(nil, returnedError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
NSHTTPURLResponse *HTTPURLResponse = (NSHTTPURLResponse *) response;
|
||||
|
||||
if (HTTPURLResponse.statusCode != 201 && HTTPURLResponse.statusCode != 200) {
|
||||
// A server error occurred.
|
||||
NSError *serverError = [OIDErrorUtilities HTTPErrorWithHTTPResponse:HTTPURLResponse
|
||||
data:data];
|
||||
|
||||
// HTTP 400 may indicate an OpenID Connect Dynamic Client Registration 1.0 Section 3.3 error
|
||||
// response, checks for that
|
||||
if (HTTPURLResponse.statusCode == 400) {
|
||||
NSError *jsonDeserializationError;
|
||||
NSDictionary<NSString *, NSObject <NSCopying> *> *json =
|
||||
[NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonDeserializationError];
|
||||
|
||||
// if the HTTP 400 response parses as JSON and has an 'error' key, it's an OAuth error
|
||||
// these errors are special as they indicate a problem with the authorization grant
|
||||
if (json[OIDOAuthErrorFieldError]) {
|
||||
NSError *oauthError =
|
||||
[OIDErrorUtilities OAuthErrorWithDomain:OIDOAuthRegistrationErrorDomain
|
||||
OAuthResponse:json
|
||||
underlyingError:serverError];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(nil, oauthError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// not an OAuth error, just a generic server error
|
||||
NSString *errorDescription =
|
||||
[NSString stringWithFormat:@"Non-200/201 HTTP response (%d) making registration request "
|
||||
"to '%@'.",
|
||||
(int)HTTPURLResponse.statusCode,
|
||||
URLRequest.URL];
|
||||
NSError *returnedError = [OIDErrorUtilities errorWithCode:OIDErrorCodeServerError
|
||||
underlyingError:serverError
|
||||
description:errorDescription];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(nil, returnedError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
NSError *jsonDeserializationError;
|
||||
NSDictionary<NSString *, NSObject <NSCopying> *> *json =
|
||||
[NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonDeserializationError];
|
||||
if (jsonDeserializationError) {
|
||||
// A problem occurred deserializing the response/JSON.
|
||||
NSString *errorDescription =
|
||||
[NSString stringWithFormat:@"JSON error parsing registration response: %@",
|
||||
jsonDeserializationError.localizedDescription];
|
||||
NSError *returnedError = [OIDErrorUtilities errorWithCode:OIDErrorCodeJSONDeserializationError
|
||||
underlyingError:jsonDeserializationError
|
||||
description:errorDescription];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(nil, returnedError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
OIDRegistrationResponse *registrationResponse =
|
||||
[[OIDRegistrationResponse alloc] initWithRequest:request
|
||||
parameters:json];
|
||||
if (!registrationResponse) {
|
||||
// A problem occurred constructing the registration response from the JSON.
|
||||
NSError *returnedError =
|
||||
[OIDErrorUtilities errorWithCode:OIDErrorCodeRegistrationResponseConstructionError
|
||||
underlyingError:nil
|
||||
description:@"Registration response invalid."];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(nil, returnedError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Success
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(registrationResponse, nil);
|
||||
});
|
||||
}] resume];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,51 +0,0 @@
|
||||
/*! @file OIDClientMetadataParameters.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 The AppAuth for iOS Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Parameter name for the token endpoint authentication method.
|
||||
*/
|
||||
extern NSString *const OIDTokenEndpointAuthenticationMethodParam;
|
||||
|
||||
/*! @brief Parameter name for the application type.
|
||||
*/
|
||||
extern NSString *const OIDApplicationTypeParam;
|
||||
|
||||
/*! @brief Parameter name for the redirect URI values.
|
||||
*/
|
||||
extern NSString *const OIDRedirectURIsParam;
|
||||
|
||||
/*! @brief Parameter name for the response type values.
|
||||
*/
|
||||
extern NSString *const OIDResponseTypesParam;
|
||||
|
||||
/*! @brief Parameter name for the grant type values.
|
||||
*/
|
||||
extern NSString *const OIDGrantTypesParam;
|
||||
|
||||
/*! @brief Parameter name for the subject type.
|
||||
*/
|
||||
extern NSString *const OIDSubjectTypeParam;
|
||||
|
||||
/*! @brief Application type that indicates this client is a native (not a web) application.
|
||||
*/
|
||||
extern NSString *const OIDApplicationTypeNative;
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,33 +0,0 @@
|
||||
/*! @file OIDClientMetadataParameters.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 The AppAuth for iOS Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDClientMetadataParameters.h"
|
||||
|
||||
NSString *const OIDTokenEndpointAuthenticationMethodParam = @"token_endpoint_auth_method";
|
||||
|
||||
NSString *const OIDApplicationTypeParam = @"application_type";
|
||||
|
||||
NSString *const OIDRedirectURIsParam = @"redirect_uris";
|
||||
|
||||
NSString *const OIDResponseTypesParam = @"response_types";
|
||||
|
||||
NSString *const OIDGrantTypesParam = @"grant_types";
|
||||
|
||||
NSString *const OIDSubjectTypeParam = @"subject_type";
|
||||
|
||||
NSString *const OIDApplicationTypeNative = @"native";
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
/*! @file OIDDefines.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*! @def OIDIsEqualIncludingNil(x, y)
|
||||
@brief Returns YES if x and y are equal by reference or value.
|
||||
@discussion NOTE: parameters may be evaluated multiple times. Be careful if using this check
|
||||
with expressions - especially if the expressions have side effects.
|
||||
@param x An object.
|
||||
@param y An object.
|
||||
*/
|
||||
#define OIDIsEqualIncludingNil(x, y) (((x) == (y)) || [(x) isEqual:(y)])
|
||||
|
||||
/*! @def OID_UNAVAILABLE_USE_INITIALIZER(designatedInitializer)
|
||||
@brief Provides a template implementation for init-family methods which have been marked as
|
||||
NS_UNAVILABLE. Stops the compiler from giving a warning when it's the super class'
|
||||
designated initializer, and gives callers useful feedback telling them what the
|
||||
new designated initializer is.
|
||||
@remarks Takes a SEL as a parameter instead of a string so that we get compiler warnings if the
|
||||
designated intializer's signature changes.
|
||||
@param designatedInitializer A SEL referencing the designated initializer.
|
||||
*/
|
||||
#define OID_UNAVAILABLE_USE_INITIALIZER(designatedInitializer) { \
|
||||
NSString *reason = [NSString stringWithFormat:@"Called: %@\nDesignated Initializer:%@", \
|
||||
NSStringFromSelector(_cmd), \
|
||||
NSStringFromSelector(designatedInitializer)]; \
|
||||
@throw [NSException exceptionWithName:@"Attempt to call unavailable initializer." \
|
||||
reason:reason \
|
||||
userInfo:nil]; \
|
||||
}
|
||||
|
||||
#ifdef _APPAUTHTRACE
|
||||
# define AppAuthRequestTrace(fmt, ...) NSLog(fmt, ##__VA_ARGS__);
|
||||
#else // _APPAUTHTRACE
|
||||
# define AppAuthRequestTrace(...)
|
||||
#endif // _APPAUTHTRACE
|
||||
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
/*! @file OIDEndSessionRequest.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2017 The AppAuth Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "OIDExternalUserAgentRequest.h"
|
||||
|
||||
@class OIDServiceConfiguration;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OIDEndSessionRequest : NSObject
|
||||
<NSCopying, NSSecureCoding, OIDExternalUserAgentRequest>
|
||||
|
||||
/*! @brief The service's configuration.
|
||||
@remarks This configuration specifies how to connect to a particular OAuth provider.
|
||||
Configurations may be created manually, or via an OpenID Connect Discovery Document.
|
||||
*/
|
||||
@property(nonatomic, readonly) OIDServiceConfiguration *configuration;
|
||||
|
||||
/*! @brief The client's redirect URI.
|
||||
@remarks post_logout_redirect_uri
|
||||
@see http://openid.net/specs/openid-connect-session-1_0.html#RPLogout
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *postLogoutRedirectURL;
|
||||
|
||||
/*! @brief Previously issued ID Token passed to the end session endpoint as a hint about the End-User's current authenticated
|
||||
session with the Client
|
||||
@remarks id_token_hint
|
||||
@see http://openid.net/specs/openid-connect-session-1_0.html#RPLogout
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *idTokenHint;
|
||||
|
||||
/*! @brief An opaque value used by the client to maintain state between the request and callback.
|
||||
@remarks state
|
||||
@discussion If this value is not explicitly set, this library will automatically add state and
|
||||
perform appropriate validation of the state in the authorization response. It is recommended
|
||||
that the default implementation of this parameter be used wherever possible. Typically used
|
||||
to prevent CSRF attacks, as recommended in RFC6819 Section 5.3.5.
|
||||
@see http://openid.net/specs/openid-connect-session-1_0.html#RPLogout
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *state;
|
||||
|
||||
/*! @brief The client's additional authorization parameters.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSDictionary<NSString *, NSString *> *additionalParameters;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use @c initWithConfiguration:clientId:scopes:redirectURL:additionalParameters:.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Creates an authorization request with opinionated defaults (a secure @c state).
|
||||
@param configuration The service's configuration.
|
||||
@param idTokenHint The previously issued ID Token
|
||||
@param postLogoutRedirectURL The client's post-logout redirect URI.
|
||||
callback.
|
||||
@param additionalParameters The client's additional authorization parameters.
|
||||
*/
|
||||
- (instancetype)
|
||||
initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
idTokenHint:(NSString *)idTokenHint
|
||||
postLogoutRedirectURL:(NSURL *)postLogoutRedirectURL
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;
|
||||
|
||||
/*! @brief Designated initializer.
|
||||
@param configuration The service's configuration.
|
||||
@param idTokenHint The previously issued ID Token
|
||||
@param postLogoutRedirectURL The client's post-logout redirect URI.
|
||||
@param state An opaque value used by the client to maintain state between the request and
|
||||
callback.
|
||||
@param additionalParameters The client's additional authorization parameters.
|
||||
*/
|
||||
- (instancetype)
|
||||
initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
idTokenHint:(NSString *)idTokenHint
|
||||
postLogoutRedirectURL:(NSURL *)postLogoutRedirectURL
|
||||
state:(NSString *)state
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/*! @brief Constructs the request URI by adding the request parameters to the query component of the
|
||||
authorization endpoint URI using the "application/x-www-form-urlencoded" format.
|
||||
@return A URL representing the authorization request.
|
||||
@see http://openid.net/specs/openid-connect-session-1_0.html#RPLogout
|
||||
*/
|
||||
- (NSURL *)endSessionRequestURL;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-190
@@ -1,190 +0,0 @@
|
||||
/*! @file OIDEndSessionRequest.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2017 The AppAuth Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDEndSessionRequest.h"
|
||||
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDTokenUtilities.h"
|
||||
#import "OIDServiceConfiguration.h"
|
||||
#import "OIDServiceDiscovery.h"
|
||||
#import "OIDURLQueryComponent.h"
|
||||
|
||||
/*! @brief The key for the @c configuration property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kConfigurationKey = @"configuration";
|
||||
|
||||
/*! @brief Key used to encode the @c state property for @c NSSecureCoding, and on the URL request.
|
||||
*/
|
||||
static NSString *const kStateKey = @"state";
|
||||
|
||||
/*! @brief Key used to encode the @c postLogoutRedirectURL property for @c NSSecureCoding, and on the URL request.
|
||||
*/
|
||||
static NSString *const kPostLogoutRedirectURLKey = @"post_logout_redirect_uri";
|
||||
|
||||
/*! @brief Key used to encode the @c idTokenHint property for @c NSSecureCoding, and on the URL request.
|
||||
*/
|
||||
static NSString *const kIdTokenHintKey = @"id_token_hint";
|
||||
|
||||
/*! @brief Key used to encode the @c additionalParameters property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kAdditionalParametersKey = @"additionalParameters";
|
||||
|
||||
/*! @brief Number of random bytes generated for the @state.
|
||||
*/
|
||||
static NSUInteger const kStateSizeBytes = 32;
|
||||
|
||||
/*! @brief Assertion text for missing end_session_endpoint.
|
||||
*/
|
||||
static NSString *const OIDMissingEndSessionEndpointMessage =
|
||||
@"The service configuration is missing an end_session_endpoint.";
|
||||
|
||||
@implementation OIDEndSessionRequest
|
||||
|
||||
- (instancetype)init
|
||||
OID_UNAVAILABLE_USE_INITIALIZER(
|
||||
@selector(initWithConfiguration:
|
||||
idTokenHint:
|
||||
postLogoutRedirectURL:
|
||||
additionalParameters:)
|
||||
)
|
||||
|
||||
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
idTokenHint:(NSString *)idTokenHint
|
||||
postLogoutRedirectURL:(NSURL *)postLogoutRedirectURL
|
||||
state:(NSString *)state
|
||||
additionalParameters:(NSDictionary<NSString *,NSString *> *)additionalParameters
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_configuration = [configuration copy];
|
||||
_idTokenHint = [idTokenHint copy];
|
||||
_postLogoutRedirectURL = [postLogoutRedirectURL copy];
|
||||
_state = [state copy];
|
||||
_additionalParameters =
|
||||
[[NSDictionary alloc] initWithDictionary:additionalParameters copyItems:YES];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
idTokenHint:(NSString *)idTokenHint
|
||||
postLogoutRedirectURL:(NSURL *)postLogoutRedirectURL
|
||||
additionalParameters:(NSDictionary<NSString *,NSString *> *)additionalParameters
|
||||
{
|
||||
return [self initWithConfiguration:configuration
|
||||
idTokenHint:idTokenHint
|
||||
postLogoutRedirectURL:postLogoutRedirectURL
|
||||
state:[[self class] generateState]
|
||||
additionalParameters:additionalParameters];
|
||||
}
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
// The documentation for NSCopying specifically advises us to return a reference to the original
|
||||
// instance in the case where instances are immutable (as ours is):
|
||||
// "Implement NSCopying by retaining the original instead of creating a new copy when the class
|
||||
// and its contents are immutable."
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
OIDServiceConfiguration *configuration = [aDecoder decodeObjectOfClass:[OIDServiceConfiguration class] forKey:kConfigurationKey];
|
||||
|
||||
NSString *idTokenHint = [aDecoder decodeObjectOfClass:[NSString class] forKey:kIdTokenHintKey];
|
||||
NSURL *postLogoutRedirectURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:kPostLogoutRedirectURLKey];
|
||||
NSString *state = [aDecoder decodeObjectOfClass:[NSString class] forKey:kStateKey];
|
||||
NSSet *additionalParameterCodingClasses = [NSSet setWithArray:@[
|
||||
[NSDictionary class],
|
||||
[NSString class]
|
||||
]];
|
||||
NSDictionary *additionalParameters = [aDecoder decodeObjectOfClasses:additionalParameterCodingClasses
|
||||
forKey:kAdditionalParametersKey];
|
||||
|
||||
self = [self initWithConfiguration:configuration
|
||||
idTokenHint:idTokenHint
|
||||
postLogoutRedirectURL:postLogoutRedirectURL
|
||||
state:state
|
||||
additionalParameters:additionalParameters];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[aCoder encodeObject:_configuration forKey:kConfigurationKey];
|
||||
[aCoder encodeObject:_idTokenHint forKey:kIdTokenHintKey];
|
||||
[aCoder encodeObject:_postLogoutRedirectURL forKey:kPostLogoutRedirectURLKey];
|
||||
[aCoder encodeObject:_state forKey:kStateKey];
|
||||
[aCoder encodeObject:_additionalParameters forKey:kAdditionalParametersKey];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject overrides
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, request: %@>",
|
||||
NSStringFromClass([self class]),
|
||||
(void *)self,
|
||||
self.endSessionRequestURL];
|
||||
}
|
||||
|
||||
+ (nullable NSString *)generateState {
|
||||
return [OIDTokenUtilities randomURLSafeStringWithSize:kStateSizeBytes];
|
||||
}
|
||||
|
||||
#pragma mark - OIDExternalUserAgentRequest
|
||||
|
||||
- (NSURL*)externalUserAgentRequestURL {
|
||||
return [self endSessionRequestURL];
|
||||
}
|
||||
|
||||
- (NSString *)redirectScheme {
|
||||
return [_postLogoutRedirectURL scheme];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSURL *)endSessionRequestURL {
|
||||
OIDURLQueryComponent *query = [[OIDURLQueryComponent alloc] init];
|
||||
|
||||
// Add any additional parameters the client has specified.
|
||||
[query addParameters:_additionalParameters];
|
||||
|
||||
// Add optional parameters, as applicable.
|
||||
if (_idTokenHint) {
|
||||
[query addParameter:kIdTokenHintKey value:_idTokenHint];
|
||||
}
|
||||
|
||||
if (_postLogoutRedirectURL) {
|
||||
[query addParameter:kPostLogoutRedirectURLKey value:_postLogoutRedirectURL.absoluteString];
|
||||
}
|
||||
|
||||
if (_state) {
|
||||
[query addParameter:kStateKey value:_state];
|
||||
}
|
||||
|
||||
NSAssert(_configuration.endSessionEndpoint, OIDMissingEndSessionEndpointMessage);
|
||||
|
||||
// Construct the URL
|
||||
return [query URLByReplacingQueryInURL:_configuration.endSessionEndpoint];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,64 +0,0 @@
|
||||
/*! @file OIDEndSessionResponse.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2017 The AppAuth Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class OIDEndSessionRequest;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Represents the response to an End Session request.
|
||||
@see http://openid.net/specs/openid-connect-session-1_0.html#RPLogout
|
||||
*/
|
||||
|
||||
@interface OIDEndSessionResponse : NSObject <NSCopying, NSSecureCoding>
|
||||
|
||||
/*! @brief The request which was serviced.
|
||||
*/
|
||||
@property(nonatomic, readonly) OIDEndSessionRequest *request;
|
||||
|
||||
/*! @brief REQUIRED if the "state" parameter was present in the client end-session request. The
|
||||
exact value received from the client.
|
||||
@remarks state
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *state;
|
||||
|
||||
/*! @brief Additional parameters returned from the end session endpoint.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSDictionary<NSString *, NSObject<NSCopying> *> *additionalParameters;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use initWithParameters:.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Designated initializer.
|
||||
@param request The serviced request.
|
||||
@param parameters The decoded parameters returned from the End Session Endpoint.
|
||||
@remarks Known parameters are extracted from the @c parameters parameter and the normative
|
||||
properties are populated. Non-normative parameters are placed in the
|
||||
@c #additionalParameters dictionary.
|
||||
*/
|
||||
- (instancetype)initWithRequest:(OIDEndSessionRequest *)request
|
||||
parameters:(NSDictionary<NSString *, NSObject<NSCopying> *> *)parameters
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-118
@@ -1,118 +0,0 @@
|
||||
/*! @file OIDEndSessionResponse.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2017 The AppAuth Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDEndSessionResponse.h"
|
||||
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDEndSessionRequest.h"
|
||||
#import "OIDFieldMapping.h"
|
||||
|
||||
/*! @brief The key for the @c state property in the incoming parameters and for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kStateKey = @"state";
|
||||
|
||||
/*! @brief Key used to encode the @c request property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kRequestKey = @"request";
|
||||
|
||||
/*! @brief Key used to encode the @c additionalParameters property for
|
||||
@c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kAdditionalParametersKey = @"additionalParameters";
|
||||
|
||||
@implementation OIDEndSessionResponse
|
||||
|
||||
#pragma mark - Initializers
|
||||
|
||||
- (instancetype)init
|
||||
OID_UNAVAILABLE_USE_INITIALIZER(@selector(initWithRequest:parameters:))
|
||||
|
||||
- (instancetype)initWithRequest:(OIDEndSessionRequest *)request
|
||||
parameters:(NSDictionary<NSString *,NSObject<NSCopying> *> *)parameters {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_request = [request copy];
|
||||
NSDictionary<NSString *, NSObject<NSCopying> *> *additionalParameters =
|
||||
[OIDFieldMapping remainingParametersWithMap:[[self class] fieldMap]
|
||||
parameters:parameters
|
||||
instance:self];
|
||||
_additionalParameters = additionalParameters;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/*! @brief Returns a mapping of incoming parameters to instance variables.
|
||||
@return A mapping of incoming parameters to instance variables.
|
||||
*/
|
||||
+ (NSDictionary<NSString *, OIDFieldMapping *> *)fieldMap {
|
||||
static NSMutableDictionary<NSString *, OIDFieldMapping *> *fieldMap;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
fieldMap = [NSMutableDictionary dictionary];
|
||||
fieldMap[kStateKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_state" type:[NSString class]];
|
||||
});
|
||||
return fieldMap;
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
// The documentation for NSCopying specifically advises us to return a reference to the original
|
||||
// instance in the case where instances are immutable (as ours is):
|
||||
// "Implement NSCopying by retaining the original instead of creating a new copy when the class
|
||||
// and its contents are immutable."
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
OIDEndSessionRequest *request =
|
||||
[aDecoder decodeObjectOfClass:[OIDEndSessionRequest class] forKey:kRequestKey];
|
||||
self = [self initWithRequest:request parameters:@{ }];
|
||||
if (self) {
|
||||
[OIDFieldMapping decodeWithCoder:aDecoder map:[[self class] fieldMap] instance:self];
|
||||
_additionalParameters = [aDecoder decodeObjectOfClasses:[OIDFieldMapping JSONTypes]
|
||||
forKey:kAdditionalParametersKey];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[aCoder encodeObject:_request forKey:kRequestKey];
|
||||
[OIDFieldMapping encodeWithCoder:aCoder map:[[self class] fieldMap] instance:self];
|
||||
[aCoder encodeObject:_additionalParameters forKey:kAdditionalParametersKey];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject overrides
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, state: \"%@\", "
|
||||
"additionalParameters: %@, request: %@>",
|
||||
NSStringFromClass([self class]),
|
||||
(void *)self,
|
||||
_state,
|
||||
_additionalParameters,
|
||||
_request];
|
||||
}
|
||||
@end
|
||||
-393
@@ -1,393 +0,0 @@
|
||||
/*! @file OIDError.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief The error domain for all NSErrors returned from the AppAuth library.
|
||||
*/
|
||||
extern NSString *const OIDGeneralErrorDomain;
|
||||
|
||||
/*! @brief The error domain for OAuth specific errors on the authorization endpoint.
|
||||
@discussion This error domain is used when the server responds to an authorization request
|
||||
with an explicit OAuth error, as defined by RFC6749 Section 4.1.2.1. If the authorization
|
||||
response is invalid and not explicitly an error response, another error domain will be used.
|
||||
The error response parameter dictionary is available in the
|
||||
\NSError_userInfo dictionary using the @c ::OIDOAuthErrorResponseErrorKey key.
|
||||
The \NSError_code will be one of the @c ::OIDErrorCodeOAuthAuthorization enum values.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
extern NSString *const OIDOAuthAuthorizationErrorDomain;
|
||||
|
||||
/*! @brief The error domain for OAuth specific errors on the token endpoint.
|
||||
@discussion This error domain is used when the server responds with HTTP 400 and an OAuth error,
|
||||
as defined RFC6749 Section 5.2. If an HTTP 400 response does not parse as an OAuth error
|
||||
(i.e. no 'error' field is present or the JSON is invalid), another error domain will be
|
||||
used. The entire OAuth error response dictionary is available in the \NSError_userInfo
|
||||
dictionary using the @c ::OIDOAuthErrorResponseErrorKey key. Unlike transient network
|
||||
errors, errors in this domain invalidate the authentication state, and either indicate a
|
||||
client error or require user interaction (i.e. reauthentication) to resolve.
|
||||
The \NSError_code will be one of the @c ::OIDErrorCodeOAuthToken enum values.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
extern NSString *const OIDOAuthTokenErrorDomain;
|
||||
|
||||
/*! @brief The error domain for dynamic client registration errors.
|
||||
@discussion This error domain is used when the server responds with HTTP 400 and an OAuth error,
|
||||
as defined in OpenID Connect Dynamic Client Registration 1.0 Section 3.3. If an HTTP 400
|
||||
response does not parse as an OAuth error (i.e. no 'error' field is present or the JSON is
|
||||
invalid), another error domain will be used. The entire OAuth error response dictionary is
|
||||
available in the \NSError_userInfo dictionary using the @c ::OIDOAuthErrorResponseErrorKey
|
||||
key. Unlike transient network errors, errors in this domain invalidate the authentication
|
||||
state, and indicates a client error.
|
||||
The \NSError_code will be one of the @c ::OIDErrorCodeOAuthToken enum values.
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError
|
||||
*/
|
||||
extern NSString *const OIDOAuthRegistrationErrorDomain;
|
||||
|
||||
/*! @brief The error domain for authorization errors encountered out of band on the resource server.
|
||||
*/
|
||||
extern NSString *const OIDResourceServerAuthorizationErrorDomain;
|
||||
|
||||
/*! @brief An error domain representing received HTTP errors.
|
||||
*/
|
||||
extern NSString *const OIDHTTPErrorDomain;
|
||||
|
||||
/*! @brief An error key for the original OAuth error response (if any).
|
||||
*/
|
||||
extern NSString *const OIDOAuthErrorResponseErrorKey;
|
||||
|
||||
/*! @brief The key of the 'error' response field in a RFC6749 Section 5.2 response.
|
||||
@remark error
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
extern NSString *const OIDOAuthErrorFieldError;
|
||||
|
||||
/*! @brief The key of the 'error_description' response field in a RFC6749 Section 5.2 response.
|
||||
@remark error_description
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
extern NSString *const OIDOAuthErrorFieldErrorDescription;
|
||||
|
||||
/*! @brief The key of the 'error_uri' response field in a RFC6749 Section 5.2 response.
|
||||
@remark error_uri
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
extern NSString *const OIDOAuthErrorFieldErrorURI;
|
||||
|
||||
/*! @brief The various error codes returned from the AppAuth library.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, OIDErrorCode) {
|
||||
/*! @brief Indicates a problem parsing an OpenID Connect Service Discovery document.
|
||||
*/
|
||||
OIDErrorCodeInvalidDiscoveryDocument = -2,
|
||||
|
||||
/*! @brief Indicates the user manually canceled the OAuth authorization code flow.
|
||||
*/
|
||||
OIDErrorCodeUserCanceledAuthorizationFlow = -3,
|
||||
|
||||
/*! @brief Indicates an OAuth authorization flow was programmatically cancelled.
|
||||
*/
|
||||
OIDErrorCodeProgramCanceledAuthorizationFlow = -4,
|
||||
|
||||
/*! @brief Indicates a network error or server error occurred.
|
||||
*/
|
||||
OIDErrorCodeNetworkError = -5,
|
||||
|
||||
/*! @brief Indicates a server error occurred.
|
||||
*/
|
||||
OIDErrorCodeServerError = -6,
|
||||
|
||||
/*! @brief Indicates a problem occurred deserializing the response/JSON.
|
||||
*/
|
||||
OIDErrorCodeJSONDeserializationError = -7,
|
||||
|
||||
/*! @brief Indicates a problem occurred constructing the token response from the JSON.
|
||||
*/
|
||||
OIDErrorCodeTokenResponseConstructionError = -8,
|
||||
|
||||
/*! @brief @c UIApplication.openURL: returned NO when attempting to open the authorization
|
||||
request in mobile Safari.
|
||||
*/
|
||||
OIDErrorCodeSafariOpenError = -9,
|
||||
|
||||
/*! @brief @c NSWorkspace.openURL returned NO when attempting to open the authorization
|
||||
request in the default browser.
|
||||
*/
|
||||
OIDErrorCodeBrowserOpenError = -10,
|
||||
|
||||
/*! @brief Indicates a problem when trying to refresh the tokens.
|
||||
*/
|
||||
OIDErrorCodeTokenRefreshError = -11,
|
||||
|
||||
/*! @brief Indicates a problem occurred constructing the registration response from the JSON.
|
||||
*/
|
||||
OIDErrorCodeRegistrationResponseConstructionError = -12,
|
||||
|
||||
/*! @brief Indicates a problem occurred deserializing the response/JSON.
|
||||
*/
|
||||
OIDErrorCodeJSONSerializationError = -13,
|
||||
|
||||
/*! @brief The ID Token did not parse.
|
||||
*/
|
||||
OIDErrorCodeIDTokenParsingError = -14,
|
||||
|
||||
/*! @brief The ID Token did not pass validation (e.g. issuer, audience checks).
|
||||
*/
|
||||
OIDErrorCodeIDTokenFailedValidationError = -15,
|
||||
};
|
||||
|
||||
/*! @brief Enum of all possible OAuth error codes as defined by RFC6749
|
||||
@discussion Used by @c ::OIDErrorCodeOAuthAuthorization and @c ::OIDErrorCodeOAuthToken
|
||||
which define endpoint-specific subsets of OAuth codes. Those enum types are down-castable
|
||||
to this one.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-11.4
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, OIDErrorCodeOAuth) {
|
||||
|
||||
/*! @remarks invalid_request
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthInvalidRequest = -2,
|
||||
|
||||
/*! @remarks unauthorized_client
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthUnauthorizedClient = -3,
|
||||
|
||||
/*! @remarks access_denied
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthAccessDenied = -4,
|
||||
|
||||
/*! @remarks unsupported_response_type
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthUnsupportedResponseType = -5,
|
||||
|
||||
/*! @remarks invalid_scope
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthInvalidScope = -6,
|
||||
|
||||
/*! @remarks server_error
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthServerError = -7,
|
||||
|
||||
/*! @remarks temporarily_unavailable
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthTemporarilyUnavailable = -8,
|
||||
|
||||
/*! @remarks invalid_client
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthInvalidClient = -9,
|
||||
|
||||
/*! @remarks invalid_grant
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthInvalidGrant = -10,
|
||||
|
||||
/*! @remarks unsupported_grant_type
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthUnsupportedGrantType = -11,
|
||||
|
||||
/*! @remarks invalid_redirect_uri
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError
|
||||
*/
|
||||
OIDErrorCodeOAuthInvalidRedirectURI = -12,
|
||||
|
||||
/*! @remarks invalid_client_metadata
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError
|
||||
*/
|
||||
OIDErrorCodeOAuthInvalidClientMetadata = -13,
|
||||
|
||||
/*! @brief An authorization error occurring on the client rather than the server. For example,
|
||||
due to a state mismatch or misconfiguration. Should be treated as an unrecoverable
|
||||
authorization error.
|
||||
*/
|
||||
OIDErrorCodeOAuthClientError = -0xEFFF,
|
||||
|
||||
/*! @brief An OAuth error not known to this library
|
||||
@discussion Indicates an OAuth error as per RFC6749, but the error code was not in our
|
||||
list. It could be a custom error code, or one from an OAuth extension. See the "error" key
|
||||
of the \NSError_userInfo property. Such errors are assumed to invalidate the
|
||||
authentication state
|
||||
*/
|
||||
OIDErrorCodeOAuthOther = -0xF000,
|
||||
};
|
||||
|
||||
/*! @brief The error codes for the @c ::OIDOAuthAuthorizationErrorDomain error domain
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, OIDErrorCodeOAuthAuthorization) {
|
||||
/*! @remarks invalid_request
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthAuthorizationInvalidRequest = OIDErrorCodeOAuthInvalidRequest,
|
||||
|
||||
/*! @remarks unauthorized_client
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthAuthorizationUnauthorizedClient = OIDErrorCodeOAuthUnauthorizedClient,
|
||||
|
||||
/*! @remarks access_denied
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthAuthorizationAccessDenied =
|
||||
OIDErrorCodeOAuthAccessDenied,
|
||||
|
||||
/*! @remarks unsupported_response_type
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthAuthorizationUnsupportedResponseType =
|
||||
OIDErrorCodeOAuthUnsupportedResponseType,
|
||||
|
||||
/*! @brief Indicates a network error or server error occurred.
|
||||
@remarks invalid_scope
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthAuthorizationAuthorizationInvalidScope = OIDErrorCodeOAuthInvalidScope,
|
||||
|
||||
/*! @brief Indicates a server error occurred.
|
||||
@remarks server_error
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthAuthorizationServerError = OIDErrorCodeOAuthServerError,
|
||||
|
||||
/*! @remarks temporarily_unavailable
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthAuthorizationTemporarilyUnavailable = OIDErrorCodeOAuthTemporarilyUnavailable,
|
||||
|
||||
/*! @brief An authorization error occurring on the client rather than the server. For example,
|
||||
due to a state mismatch or client misconfiguration. Should be treated as an unrecoverable
|
||||
authorization error.
|
||||
*/
|
||||
OIDErrorCodeOAuthAuthorizationClientError = OIDErrorCodeOAuthClientError,
|
||||
|
||||
/*! @brief An authorization OAuth error not known to this library
|
||||
@discussion this indicates an OAuth error as per RFC6749, but the error code was not in our
|
||||
list. It could be a custom error code, or one from an OAuth extension. See the "error" key
|
||||
of the \NSError_userInfo property. We assume such errors are not transient.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
*/
|
||||
OIDErrorCodeOAuthAuthorizationOther = OIDErrorCodeOAuthOther,
|
||||
};
|
||||
|
||||
|
||||
/*! @brief The error codes for the @c ::OIDOAuthTokenErrorDomain error domain
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, OIDErrorCodeOAuthToken) {
|
||||
/*! @remarks invalid_request
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthTokenInvalidRequest = OIDErrorCodeOAuthInvalidRequest,
|
||||
|
||||
/*! @remarks invalid_client
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthTokenInvalidClient = OIDErrorCodeOAuthInvalidClient,
|
||||
|
||||
/*! @remarks invalid_grant
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthTokenInvalidGrant = OIDErrorCodeOAuthInvalidGrant,
|
||||
|
||||
/*! @remarks unauthorized_client
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthTokenUnauthorizedClient = OIDErrorCodeOAuthUnauthorizedClient,
|
||||
|
||||
/*! @remarks unsupported_grant_type
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthTokenUnsupportedGrantType = OIDErrorCodeOAuthUnsupportedGrantType,
|
||||
|
||||
/*! @remarks invalid_scope
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthTokenInvalidScope = OIDErrorCodeOAuthInvalidScope,
|
||||
|
||||
/*! @brief An unrecoverable token error occurring on the client rather than the server.
|
||||
*/
|
||||
OIDErrorCodeOAuthTokenClientError = OIDErrorCodeOAuthClientError,
|
||||
|
||||
/*! @brief A token endpoint OAuth error not known to this library
|
||||
@discussion this indicates an OAuth error as per RFC6749, but the error code was not in our
|
||||
list. It could be a custom error code, or one from an OAuth extension. See the "error" key
|
||||
of the \NSError_userInfo property. We assume such errors are not transient.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthTokenOther = OIDErrorCodeOAuthOther,
|
||||
};
|
||||
|
||||
/*! @brief The error codes for the @c ::OIDOAuthRegistrationErrorDomain error domain
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, OIDErrorCodeOAuthRegistration) {
|
||||
/*! @remarks invalid_request
|
||||
@see http://tools.ietf.org/html/rfc6750#section-3.1
|
||||
*/
|
||||
OIDErrorCodeOAuthRegistrationInvalidRequest = OIDErrorCodeOAuthInvalidRequest,
|
||||
|
||||
/*! @remarks invalid_redirect_uri
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError
|
||||
*/
|
||||
OIDErrorCodeOAuthRegistrationInvalidRedirectURI = OIDErrorCodeOAuthInvalidRedirectURI,
|
||||
|
||||
/*! @remarks invalid_client_metadata
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError
|
||||
*/
|
||||
OIDErrorCodeOAuthRegistrationInvalidClientMetadata = OIDErrorCodeOAuthInvalidClientMetadata,
|
||||
|
||||
/*! @brief An unrecoverable token error occurring on the client rather than the server.
|
||||
*/
|
||||
OIDErrorCodeOAuthRegistrationClientError = OIDErrorCodeOAuthClientError,
|
||||
|
||||
/*! @brief A registration endpoint OAuth error not known to this library
|
||||
@discussion this indicates an OAuth error, but the error code was not in our
|
||||
list. It could be a custom error code, or one from an OAuth extension. See the "error" key
|
||||
of the \NSError_userInfo property. We assume such errors are not transient.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
OIDErrorCodeOAuthRegistrationOther = OIDErrorCodeOAuthOther,
|
||||
};
|
||||
|
||||
|
||||
/*! @brief The exception text for the exception which occurs when a
|
||||
@c OIDExternalUserAgentSession receives a message after it has already completed.
|
||||
*/
|
||||
extern NSString *const OIDOAuthExceptionInvalidAuthorizationFlow;
|
||||
|
||||
/*! @brief The text for the exception which occurs when a Token Request is constructed
|
||||
with a null redirectURL for a grant_type that requires a nonnull Redirect
|
||||
*/
|
||||
extern NSString *const OIDOAuthExceptionInvalidTokenRequestNullRedirectURL;
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*! @file OIDError.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDError.h"
|
||||
|
||||
NSString *const OIDGeneralErrorDomain = @"org.openid.appauth.general";
|
||||
|
||||
NSString *const OIDOAuthTokenErrorDomain = @"org.openid.appauth.oauth_token";
|
||||
|
||||
NSString *const OIDOAuthAuthorizationErrorDomain = @"org.openid.appauth.oauth_authorization";
|
||||
|
||||
NSString *const OIDOAuthRegistrationErrorDomain = @"org.openid.appauth.oauth_registration";
|
||||
|
||||
NSString *const OIDResourceServerAuthorizationErrorDomain = @"org.openid.appauth.resourceserver";
|
||||
|
||||
NSString *const OIDHTTPErrorDomain = @"org.openid.appauth.remote-http";
|
||||
|
||||
NSString *const OIDOAuthExceptionInvalidAuthorizationFlow = @"An OAuth redirect was sent to a "
|
||||
"OIDExternalUserAgentSession after it already completed.";
|
||||
|
||||
NSString *const OIDOAuthExceptionInvalidTokenRequestNullRedirectURL = @"A OIDTokenRequest was "
|
||||
"created with a grant_type that requires a redirectURL, but a null redirectURL was given";
|
||||
|
||||
NSString *const OIDOAuthErrorResponseErrorKey = @"OIDOAuthErrorResponseErrorKey";
|
||||
|
||||
NSString *const OIDOAuthErrorFieldError = @"error";
|
||||
|
||||
NSString *const OIDOAuthErrorFieldErrorDescription = @"error_description";
|
||||
|
||||
NSString *const OIDOAuthErrorFieldErrorURI = @"error_uri";
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
/*! @file OIDErrorUtilities.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "OIDError.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Convenience methods for creating standardized \NSError instances.
|
||||
*/
|
||||
@interface OIDErrorUtilities : NSObject
|
||||
|
||||
/*! @brief Creates a standard \NSError from an @c ::OIDErrorCode and custom user info.
|
||||
Automatically populates the localized error description.
|
||||
@param code The error code.
|
||||
@param underlyingError The underlying error which occurred, if applicable.
|
||||
@param description A custom description, if applicable.
|
||||
@return An \NSError representing the error code.
|
||||
*/
|
||||
+ (NSError *)errorWithCode:(OIDErrorCode)code
|
||||
underlyingError:(nullable NSError *)underlyingError
|
||||
description:(nullable NSString *)description;
|
||||
|
||||
/*! @brief Creates a standard \NSError from an @c ::OIDErrorCode and custom user info.
|
||||
Automatically populates the localized error description.
|
||||
@param OAuthErrorDomain The OAuth error domain. Must be @c ::OIDOAuthAuthorizationErrorDomain or
|
||||
@c ::OIDOAuthTokenErrorDomain.
|
||||
@param errorResponse The dictionary from an OAuth error response (as per RFC6749 Section 5.2).
|
||||
@param underlyingError The underlying error which occurred, if applicable.
|
||||
@return An \NSError representing the OAuth error.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
+ (NSError *)OAuthErrorWithDomain:(NSString *)OAuthErrorDomain
|
||||
OAuthResponse:(NSDictionary *)errorResponse
|
||||
underlyingError:(nullable NSError *)underlyingError;
|
||||
|
||||
/*! @brief Creates a \NSError indicating that the resource server responded with an authorization
|
||||
error.
|
||||
@param code Your error code.
|
||||
@param errorResponse The resource server error response, if any.
|
||||
@param underlyingError The underlying error which occurred, if applicable.
|
||||
@return An \NSError representing the authorization error from the resource server.
|
||||
*/
|
||||
+ (NSError *)resourceServerAuthorizationErrorWithCode:(NSInteger)code
|
||||
errorResponse:(nullable NSDictionary *)errorResponse
|
||||
underlyingError:(nullable NSError *)underlyingError;
|
||||
|
||||
|
||||
/*! @brief Creates a standard \NSError from an \NSHTTPURLResponse. Automatically
|
||||
populates the localized error description with the response data associated with the
|
||||
\NSHTTPURLResponse, if available.
|
||||
@param HTTPURLResponse The response which indicates an error occurred.
|
||||
@param data The response data associated with the response which should be converted to an
|
||||
@c NSString assuming a UTF-8 encoding, if available.
|
||||
@return An \NSError representing the error.
|
||||
*/
|
||||
+ (NSError *)HTTPErrorWithHTTPResponse:(NSHTTPURLResponse *)HTTPURLResponse
|
||||
data:(nullable NSData *)data;
|
||||
|
||||
/*! @brief Raises an exception with the given name as both the name, and the message.
|
||||
@param name The name of the exception.
|
||||
*/
|
||||
+ (void)raiseException:(NSString *)name;
|
||||
|
||||
/*! @brief Raises an exception with the given name and message.
|
||||
@param name The name of the exception.
|
||||
@param message The message of the exception.
|
||||
*/
|
||||
+ (void)raiseException:(NSString *)name message:(NSString *)message;
|
||||
|
||||
/*! @brief Converts an OAuth error code into an @c ::OIDErrorCodeOAuth error code.
|
||||
@param errorCode The OAuth error code.
|
||||
@discussion Returns @c ::OIDErrorCodeOAuthOther if the string is not in AppAuth's list.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
+ (OIDErrorCodeOAuth)OAuthErrorCodeFromString:(NSString *)errorCode;
|
||||
|
||||
/*! @brief Returns true if the given error domain is an OAuth error domain.
|
||||
@param errorDomain The error domain to test.
|
||||
@discussion An OAuth error domain is used for errors returned per RFC6749 sections 4.1.2.1 and
|
||||
5.2. Other errors, such as network errors can also occur but they will not have an OAuth
|
||||
error domain.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.2
|
||||
*/
|
||||
+ (BOOL)isOAuthErrorDomain:(NSString*)errorDomain;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-172
@@ -1,172 +0,0 @@
|
||||
/*! @file OIDErrorUtilities.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDErrorUtilities.h"
|
||||
|
||||
@implementation OIDErrorUtilities
|
||||
|
||||
+ (NSError *)errorWithCode:(OIDErrorCode)code
|
||||
underlyingError:(NSError *)underlyingError
|
||||
description:(NSString *)description {
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
if (underlyingError) {
|
||||
userInfo[NSUnderlyingErrorKey] = underlyingError;
|
||||
}
|
||||
if (description) {
|
||||
userInfo[NSLocalizedDescriptionKey] = description;
|
||||
}
|
||||
// TODO: Populate localized description based on code.
|
||||
NSError *error = [NSError errorWithDomain:OIDGeneralErrorDomain
|
||||
code:code
|
||||
userInfo:userInfo];
|
||||
return error;
|
||||
}
|
||||
|
||||
+ (BOOL)isOAuthErrorDomain:(NSString *)errorDomain {
|
||||
return errorDomain == OIDOAuthRegistrationErrorDomain
|
||||
|| errorDomain == OIDOAuthAuthorizationErrorDomain
|
||||
|| errorDomain == OIDOAuthTokenErrorDomain;
|
||||
}
|
||||
|
||||
+ (NSError *)resourceServerAuthorizationErrorWithCode:(NSInteger)code
|
||||
errorResponse:(nullable NSDictionary *)errorResponse
|
||||
underlyingError:(nullable NSError *)underlyingError {
|
||||
// builds the userInfo dictionary with the full OAuth response and other information
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
if (errorResponse) {
|
||||
userInfo[OIDOAuthErrorResponseErrorKey] = errorResponse;
|
||||
}
|
||||
if (underlyingError) {
|
||||
userInfo[NSUnderlyingErrorKey] = underlyingError;
|
||||
}
|
||||
NSError *error = [NSError errorWithDomain:OIDResourceServerAuthorizationErrorDomain
|
||||
code:code
|
||||
userInfo:userInfo];
|
||||
return error;
|
||||
}
|
||||
|
||||
+ (NSError *)OAuthErrorWithDomain:(NSString *)oAuthErrorDomain
|
||||
OAuthResponse:(NSDictionary *)errorResponse
|
||||
underlyingError:(NSError *)underlyingError {
|
||||
// not a valid OAuth error
|
||||
if (![self isOAuthErrorDomain:oAuthErrorDomain]
|
||||
|| !errorResponse
|
||||
|| !errorResponse[OIDOAuthErrorFieldError]
|
||||
|| ![errorResponse[OIDOAuthErrorFieldError] isKindOfClass:[NSString class]]) {
|
||||
return [[self class] errorWithCode:OIDErrorCodeNetworkError
|
||||
underlyingError:underlyingError
|
||||
description:underlyingError.localizedDescription];
|
||||
}
|
||||
|
||||
// builds the userInfo dictionary with the full OAuth response and other information
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
userInfo[OIDOAuthErrorResponseErrorKey] = errorResponse;
|
||||
if (underlyingError) {
|
||||
userInfo[NSUnderlyingErrorKey] = underlyingError;
|
||||
}
|
||||
|
||||
NSString *oauthErrorCodeString = errorResponse[OIDOAuthErrorFieldError];
|
||||
NSString *oauthErrorMessage = nil;
|
||||
if ([errorResponse[OIDOAuthErrorFieldErrorDescription] isKindOfClass:[NSString class]]) {
|
||||
oauthErrorMessage = errorResponse[OIDOAuthErrorFieldErrorDescription];
|
||||
} else {
|
||||
oauthErrorMessage = [errorResponse[OIDOAuthErrorFieldErrorDescription] description];
|
||||
}
|
||||
NSString *oauthErrorURI = nil;
|
||||
if ([errorResponse[OIDOAuthErrorFieldErrorURI] isKindOfClass:[NSString class]]) {
|
||||
oauthErrorURI = errorResponse[OIDOAuthErrorFieldErrorURI];
|
||||
} else {
|
||||
oauthErrorURI = [errorResponse[OIDOAuthErrorFieldErrorURI] description];
|
||||
}
|
||||
|
||||
// builds the error description, using the information supplied by the server if possible
|
||||
NSMutableString *description = [NSMutableString string];
|
||||
[description appendString:oauthErrorCodeString];
|
||||
if (oauthErrorMessage) {
|
||||
[description appendString:@": "];
|
||||
[description appendString:oauthErrorMessage];
|
||||
}
|
||||
if (oauthErrorURI) {
|
||||
if ([description length] > 0) {
|
||||
[description appendString:@" - "];
|
||||
}
|
||||
[description appendString:oauthErrorURI];
|
||||
}
|
||||
if ([description length] == 0) {
|
||||
// backup description
|
||||
[description appendFormat:@"OAuth error: %@ - https://tools.ietf.org/html/rfc6749#section-5.2",
|
||||
oauthErrorCodeString];
|
||||
}
|
||||
userInfo[NSLocalizedDescriptionKey] = description;
|
||||
|
||||
// looks up the error code based on the "error" response param
|
||||
OIDErrorCodeOAuth code = [[self class] OAuthErrorCodeFromString:oauthErrorCodeString];
|
||||
|
||||
NSError *error = [NSError errorWithDomain:oAuthErrorDomain
|
||||
code:code
|
||||
userInfo:userInfo];
|
||||
return error;
|
||||
}
|
||||
|
||||
+ (NSError *)HTTPErrorWithHTTPResponse:(NSHTTPURLResponse *)HTTPURLResponse
|
||||
data:(nullable NSData *)data {
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
if (data) {
|
||||
NSString *serverResponse =
|
||||
[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
if (serverResponse) {
|
||||
userInfo[NSLocalizedDescriptionKey] = serverResponse;
|
||||
}
|
||||
}
|
||||
NSError *serverError =
|
||||
[NSError errorWithDomain:OIDHTTPErrorDomain
|
||||
code:HTTPURLResponse.statusCode
|
||||
userInfo:userInfo];
|
||||
return serverError;
|
||||
}
|
||||
|
||||
+ (OIDErrorCodeOAuth)OAuthErrorCodeFromString:(NSString *)errorCode {
|
||||
NSDictionary *errorCodes = @{
|
||||
@"invalid_request": @(OIDErrorCodeOAuthInvalidRequest),
|
||||
@"unauthorized_client": @(OIDErrorCodeOAuthUnauthorizedClient),
|
||||
@"access_denied": @(OIDErrorCodeOAuthAccessDenied),
|
||||
@"unsupported_response_type": @(OIDErrorCodeOAuthUnsupportedResponseType),
|
||||
@"invalid_scope": @(OIDErrorCodeOAuthInvalidScope),
|
||||
@"server_error": @(OIDErrorCodeOAuthServerError),
|
||||
@"temporarily_unavailable": @(OIDErrorCodeOAuthTemporarilyUnavailable),
|
||||
@"invalid_client": @(OIDErrorCodeOAuthInvalidClient),
|
||||
@"invalid_grant": @(OIDErrorCodeOAuthInvalidGrant),
|
||||
@"unsupported_grant_type": @(OIDErrorCodeOAuthUnsupportedGrantType),
|
||||
};
|
||||
NSNumber *code = errorCodes[errorCode];
|
||||
if (code) {
|
||||
return [code integerValue];
|
||||
} else {
|
||||
return OIDErrorCodeOAuthOther;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)raiseException:(NSString *)name {
|
||||
[[self class] raiseException:name message:name];
|
||||
}
|
||||
|
||||
+ (void)raiseException:(NSString *)name message:(NSString *)message {
|
||||
[NSException raise:name format:@"%@", message];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,53 +0,0 @@
|
||||
/*! @file OIDExternalUserAgent.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol OIDExternalUserAgentSession;
|
||||
@protocol OIDExternalUserAgentRequest;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @protocol OIDExternalUserAgent
|
||||
@brief An external user-agent UI that presents displays the request to the user. Clients may
|
||||
provide custom implementations of an external user-agent to customize the way the requests
|
||||
are presented to the end user.
|
||||
*/
|
||||
@protocol OIDExternalUserAgent<NSObject>
|
||||
|
||||
/*! @brief Presents the request in the external user-agent.
|
||||
@param request The request to be presented in the external user-agent.
|
||||
@param session The @c OIDExternalUserAgentSession instance that initiates presenting the UI.
|
||||
Concrete implementations of a @c OIDExternalUserAgent may call
|
||||
resumeExternalUserAgentFlowWithURL or failExternalUserAgentFlowWithError on session to either
|
||||
resume or fail the request.
|
||||
@return YES If the request UI was successfully presented to the user.
|
||||
*/
|
||||
- (BOOL)presentExternalUserAgentRequest:(id<OIDExternalUserAgentRequest> )request
|
||||
session:(id<OIDExternalUserAgentSession>)session;
|
||||
|
||||
/*! @brief Dimisses the external user-agent and calls completion when the dismiss operation ends.
|
||||
@param animated Whether or not the dismiss operation should be animated.
|
||||
@remarks Has no effect if no UI is presented.
|
||||
@param completion The block to be called when the dismiss operations ends
|
||||
*/
|
||||
- (void)dismissExternalUserAgentAnimated:(BOOL)animated completion:(void (^)(void))completion;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,37 +0,0 @@
|
||||
/*! @file OIDExternalUserAgent.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2017 The AppAuth Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*! @protocol OIDExternalUserAgent
|
||||
@brief An interface that any external user-agent request may implement to use the
|
||||
@c OIDExternalUserAgent flow.
|
||||
*/
|
||||
@protocol OIDExternalUserAgentRequest
|
||||
|
||||
/*! @brief Method to create and return the complete request URL instance.
|
||||
@return A @c NSURL instance which contains the URL to be opened in an external UI (i.e. browser)
|
||||
*/
|
||||
- (NSURL*)externalUserAgentRequestURL;
|
||||
|
||||
/*! @brief If this external user-agent request has a redirect URL, this should return its scheme.
|
||||
Since some external requests have optional callbacks (such as the end session endpoint), the
|
||||
return value of this method is nullable.
|
||||
@return A @c NSString instance that contains the scheme of a callback url, or nil if there is
|
||||
no callback url for this request.
|
||||
*/
|
||||
- (NSString*)redirectScheme;
|
||||
@end
|
||||
@@ -1,65 +0,0 @@
|
||||
/*! @file OIDExternalUserAgentSession.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2017 The AppAuth Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Represents an in-flight external user-agent session.
|
||||
*/
|
||||
@protocol OIDExternalUserAgentSession <NSObject>
|
||||
|
||||
/*! @brief Cancels the code flow session, invoking the request's callback with a cancelled error.
|
||||
@remarks Has no effect if called more than once, or after a
|
||||
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message was received.
|
||||
Will cause an error with code: @c ::OIDErrorCodeProgramCanceledAuthorizationFlow to be
|
||||
passed to the @c callback block passed to
|
||||
@c OIDAuthorizationService.presentAuthorizationRequest:presentingViewController:callback:
|
||||
*/
|
||||
- (void)cancel;
|
||||
|
||||
/*! @brief Cancels the code flow session, invoking the request's callback with a cancelled error.
|
||||
@remarks Has no effect if called more than once, or after a
|
||||
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message was received.
|
||||
Will cause an error with code: @c ::OIDErrorCodeProgramCanceledAuthorizationFlow to be
|
||||
passed to the @c callback block passed to
|
||||
@c OIDAuthorizationService.presentAuthorizationRequest:presentingViewController:callback:
|
||||
@param completion The block to be called when the cancel operation ends
|
||||
*/
|
||||
- (void)cancelWithCompletion:(nullable void (^)(void))completion;
|
||||
|
||||
/*! @brief Clients should call this method with the result of the external user-agent code flow if
|
||||
it becomes available.
|
||||
@param URL The redirect URL invoked by the server.
|
||||
@discussion When the URL represented a valid response, implementations should clean up any
|
||||
left-over UI state from the request, for example by closing the
|
||||
\SFSafariViewController or loopback HTTP listener if those were used. The completion block
|
||||
of the pending request should then be invoked.
|
||||
@remarks Has no effect if called more than once, or after a @c cancel message was received.
|
||||
@return YES if the passed URL matches the expected redirect URL and was consumed, NO otherwise.
|
||||
*/
|
||||
- (BOOL)resumeExternalUserAgentFlowWithURL:(NSURL *)URL;
|
||||
|
||||
/*! @brief @c OIDExternalUserAgent or clients should call this method when the
|
||||
external user-agent flow failed with a non-OAuth error.
|
||||
@param error The error that is the reason for the failure of this external flow.
|
||||
@remarks Has no effect if called more than once, or after a @c cancel message was received.
|
||||
*/
|
||||
- (void)failExternalUserAgentFlowWithError:(NSError *)error;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
/*! @file OIDFieldMapping.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Represents a function which transforms incoming source values into instance variable
|
||||
values.
|
||||
*/
|
||||
typedef _Nullable id(^OIDFieldMappingConversionFunction)(NSObject *_Nullable value);
|
||||
|
||||
/*! @brief Describes the mapping of a key/value pair to an iVar with an optional conversion
|
||||
function.
|
||||
*/
|
||||
@interface OIDFieldMapping : NSObject
|
||||
|
||||
/*! @brief The name of the instance variable the field should be mapped to.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString *name;
|
||||
|
||||
/*! @brief The type of the instance variable.
|
||||
*/
|
||||
@property(nonatomic, readonly) Class expectedType;
|
||||
|
||||
/*! @brief An optional conversion function which specifies a transform from the incoming data to the
|
||||
instance variable value.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) OIDFieldMappingConversionFunction conversion;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use initWithName:type:conversion:.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief The designated initializer.
|
||||
@param name The name of the instance variable the field should be mapped to.
|
||||
@param type The type of the instance variable.
|
||||
@param conversion An optional conversion function which specifies a transform from the incoming
|
||||
data to the instance variable value. Used during the process performed by
|
||||
@c OIDFieldMapping.remainingParametersWithMap:parameters:instance: but not during
|
||||
encoding/decoding, since the encoded and decoded values should already be of the type
|
||||
specified by the @c type parameter.
|
||||
*/
|
||||
- (instancetype)initWithName:(NSString *)name
|
||||
type:(Class)type
|
||||
conversion:(nullable OIDFieldMappingConversionFunction)conversion
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/*! @brief A convenience initializer.
|
||||
@param name The name of the instance variable the field should be mapped to.
|
||||
@param type The type of the instance variable.
|
||||
*/
|
||||
- (instancetype)initWithName:(NSString *)name
|
||||
type:(Class)type;
|
||||
|
||||
/*! @brief Performs a mapping of key/value pairs in an incoming parameters dictionary to instance
|
||||
variables, returning a dictionary of parameter key/values which didn't map to instance
|
||||
variables.
|
||||
@param map A mapping of incoming keys to instance variables.
|
||||
@param parameters Incoming key value pairs to map to an instance's variables.
|
||||
@param instance The instance whose variables should be set based on the mapping.
|
||||
@return A dictionary of parameter key/values which didn't map to instance variables.
|
||||
*/
|
||||
+ (NSDictionary<NSString *, NSObject<NSCopying> *> *)remainingParametersWithMap:
|
||||
(NSDictionary<NSString *, OIDFieldMapping *> *)map
|
||||
parameters:(NSDictionary<NSString *, NSObject<NSCopying> *> *)parameters
|
||||
instance:(id)instance;
|
||||
|
||||
/*! @brief This helper method for @c NSCoding implementations performs a serialization of fields
|
||||
defined in a field mapping.
|
||||
@param aCoder An @c NSCoder instance to serialize instance variable values to.
|
||||
@param map A mapping of keys to instance variables.
|
||||
@param instance The instance whose variables should be serialized based on the mapping.
|
||||
*/
|
||||
+ (void)encodeWithCoder:(NSCoder *)aCoder
|
||||
map:(NSDictionary<NSString *, OIDFieldMapping *> *)map
|
||||
instance:(id)instance;
|
||||
|
||||
/*! @brief This helper method for @c NSCoding implementations performs a deserialization of
|
||||
fields defined in a field mapping.
|
||||
@param aCoder An @c NSCoder instance from which to deserialize instance variable values from.
|
||||
@param map A mapping of keys to instance variables.
|
||||
@param instance The instance whose variables should be deserialized based on the mapping.
|
||||
*/
|
||||
+ (void)decodeWithCoder:(NSCoder *)aCoder
|
||||
map:(NSDictionary<NSString *, OIDFieldMapping *> *)map
|
||||
instance:(id)instance;
|
||||
|
||||
/*! @brief Returns an @c NSSet of classes suitable for deserializing JSON content in an
|
||||
@c NSSecureCoding context.
|
||||
*/
|
||||
+ (NSSet *)JSONTypes;
|
||||
|
||||
/*! @brief Returns a function for converting an @c NSString to an @c NSURL.
|
||||
*/
|
||||
+ (OIDFieldMappingConversionFunction)URLConversion;
|
||||
|
||||
/*! @brief Returns a function for converting an @c NSNumber number of seconds from now to an
|
||||
@c NSDate.
|
||||
*/
|
||||
+ (OIDFieldMappingConversionFunction)dateSinceNowConversion;
|
||||
|
||||
/*! @brief Returns a function for converting an @c NSNumber representing a unix time stamp to an
|
||||
@c NSDate.
|
||||
*/
|
||||
+ (OIDFieldMappingConversionFunction)dateEpochConversion;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-132
@@ -1,132 +0,0 @@
|
||||
/*! @file OIDFieldMapping.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDFieldMapping.h"
|
||||
|
||||
#import "OIDDefines.h"
|
||||
|
||||
@implementation OIDFieldMapping
|
||||
|
||||
- (nonnull instancetype)init
|
||||
OID_UNAVAILABLE_USE_INITIALIZER(@selector(initWithName:type:conversion:))
|
||||
|
||||
- (instancetype)initWithName:(NSString *)name
|
||||
type:(Class)type {
|
||||
return [self initWithName:name type:type conversion:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithName:(NSString *)name
|
||||
type:(Class)type
|
||||
conversion:(nullable OIDFieldMappingConversionFunction)conversion {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_name = [name copy];
|
||||
_expectedType = type;
|
||||
_conversion = conversion;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (NSDictionary<NSString *, NSObject<NSCopying> *> *)remainingParametersWithMap:
|
||||
(NSDictionary<NSString *, OIDFieldMapping *> *)map
|
||||
parameters:(NSDictionary<NSString *, NSObject<NSCopying> *> *)parameters
|
||||
instance:(id)instance {
|
||||
NSMutableDictionary *additionalParameters = [NSMutableDictionary dictionary];
|
||||
for (NSString *key in parameters) {
|
||||
NSObject<NSCopying> *value = [parameters[key] copy];
|
||||
OIDFieldMapping *mapping = map[key];
|
||||
// If the field doesn't appear in the mapping, we add it to the additional parameters
|
||||
// dictionary.
|
||||
if (!mapping) {
|
||||
additionalParameters[key] = value;
|
||||
continue;
|
||||
}
|
||||
// If the field mapping specifies a conversion function, apply the conversion to the value.
|
||||
if (mapping.conversion) {
|
||||
value = mapping.conversion(value);
|
||||
}
|
||||
// Check the type of the value and make sure it matches the type we expected. If it doesn't we
|
||||
// add the value to the additional parameters dictionary but don't assign the instance variable.
|
||||
if (![value isKindOfClass:mapping.expectedType]) {
|
||||
additionalParameters[key] = value;
|
||||
continue;
|
||||
}
|
||||
// Assign the instance variable.
|
||||
[instance setValue:value forKey:mapping.name];
|
||||
}
|
||||
return additionalParameters;
|
||||
}
|
||||
|
||||
+ (void)encodeWithCoder:(NSCoder *)aCoder
|
||||
map:(NSDictionary<NSString *, OIDFieldMapping *> *)map
|
||||
instance:(id)instance {
|
||||
for (NSString *key in map) {
|
||||
id value = [instance valueForKey:map[key].name];
|
||||
[aCoder encodeObject:value forKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)decodeWithCoder:(NSCoder *)aCoder
|
||||
map:(NSDictionary<NSString *, OIDFieldMapping *> *)map
|
||||
instance:(id)instance {
|
||||
for (NSString *key in map) {
|
||||
OIDFieldMapping *mapping = map[key];
|
||||
id value = [aCoder decodeObjectOfClass:mapping.expectedType forKey:key];
|
||||
[instance setValue:value forKey:mapping.name];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSSet *)JSONTypes {
|
||||
return [NSSet setWithArray:@[
|
||||
[NSDictionary class],
|
||||
[NSArray class],
|
||||
[NSString class],
|
||||
[NSNumber class]
|
||||
]];
|
||||
}
|
||||
|
||||
+ (OIDFieldMappingConversionFunction)URLConversion {
|
||||
return ^id _Nullable(NSObject *_Nullable value) {
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
return [NSURL URLWithString:(NSString *)value];
|
||||
}
|
||||
return value;
|
||||
};
|
||||
}
|
||||
|
||||
+ (OIDFieldMappingConversionFunction)dateSinceNowConversion {
|
||||
return ^id _Nullable(NSObject *_Nullable value) {
|
||||
if (![value isKindOfClass:[NSNumber class]]) {
|
||||
return value;
|
||||
}
|
||||
NSNumber *valueAsNumber = (NSNumber *)value;
|
||||
return [NSDate dateWithTimeIntervalSinceNow:[valueAsNumber longLongValue]];
|
||||
};
|
||||
}
|
||||
|
||||
+ (OIDFieldMappingConversionFunction)dateEpochConversion {
|
||||
return ^id _Nullable(NSObject *_Nullable value) {
|
||||
if (![value isKindOfClass:[NSNumber class]]) {
|
||||
return value;
|
||||
}
|
||||
NSNumber *valueAsNumber = (NSNumber *) value;
|
||||
return [NSDate dateWithTimeIntervalSince1970:[valueAsNumber longLongValue]];
|
||||
};
|
||||
}
|
||||
|
||||
@end
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
/*! @file OIDGrantTypes.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/*! @brief For exchanging an authorization code for an access token.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
*/
|
||||
extern NSString *const OIDGrantTypeAuthorizationCode;
|
||||
|
||||
/*! @brief For refreshing an access token with a refresh token.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-6
|
||||
*/
|
||||
extern NSString *const OIDGrantTypeRefreshToken;
|
||||
|
||||
/*! @brief For obtaining an access token with a username and password.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.3.2
|
||||
*/
|
||||
extern NSString *const OIDGrantTypePassword;
|
||||
|
||||
/*! @brief For obtaining an access token from the token endpoint using client credentials.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.2.1
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.4.2
|
||||
*/
|
||||
extern NSString *const OIDGrantTypeClientCredentials;
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
/*! @file OIDGrantTypes.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDGrantTypes.h"
|
||||
|
||||
NSString *const OIDGrantTypeAuthorizationCode = @"authorization_code";
|
||||
|
||||
NSString *const OIDGrantTypeRefreshToken = @"refresh_token";
|
||||
|
||||
NSString *const OIDGrantTypePassword = @"password";
|
||||
|
||||
NSString *const OIDGrantTypeClientCredentials = @"client_credentials";
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
/*! @file OIDIDToken.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2017 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief A convenience class that parses an ID Token and extracts the claims _but does not_
|
||||
verify its signature. AppAuth only supports the OpenID Code flow, meaning ID Tokens
|
||||
received by AppAuth are sent from the token endpoint on a TLS protected channel,
|
||||
offering some assurances as to the origin of the token. You may wish to additionally
|
||||
verify the ID Token signature using a JWT signature verification library of your
|
||||
choosing.
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
||||
@see https://tools.ietf.org/html/rfc7519
|
||||
@see https://jwt.io/
|
||||
*/
|
||||
@interface OIDIDToken : NSObject
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use @c initWithAuthorizationResponse:.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Parses the given ID Token string.
|
||||
@param idToken The ID Token spring.
|
||||
*/
|
||||
- (nullable instancetype)initWithIDTokenString:(NSString *)idToken;
|
||||
|
||||
/*! @brief The header JWT values.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSDictionary *header;
|
||||
|
||||
/*! @brief All ID Token claims.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSDictionary *claims;
|
||||
|
||||
/*! @brief Issuer Identifier for the Issuer of the response.
|
||||
@remarks iss
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
||||
*/
|
||||
@property(nonatomic, readonly) NSURL *issuer;
|
||||
|
||||
/*! @brief Subject Identifier.
|
||||
@remarks sub
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString *subject;
|
||||
|
||||
/*! @brief Audience(s) that this ID Token is intended for.
|
||||
@remarks aud
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
||||
*/
|
||||
@property(nonatomic, readonly) NSArray *audience;
|
||||
|
||||
/*! @brief Expiration time on or after which the ID Token MUST NOT be accepted for processing.
|
||||
@remarks exp
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
||||
*/
|
||||
@property(nonatomic, readonly) NSDate *expiresAt;
|
||||
|
||||
/*! @brief Time at which the JWT was issued.
|
||||
@remarks iat
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
||||
*/
|
||||
@property(nonatomic, readonly) NSDate *issuedAt;
|
||||
|
||||
/*! @brief String value used to associate a Client session with an ID Token, and to mitigate replay
|
||||
attacks.
|
||||
@remarks nonce
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *nonce;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
/*! @file OIDIDToken.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2017 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDIDToken.h"
|
||||
|
||||
/*! Field keys associated with an ID Token. */
|
||||
static NSString *const kIssKey = @"iss";
|
||||
static NSString *const kSubKey = @"sub";
|
||||
static NSString *const kAudKey = @"aud";
|
||||
static NSString *const kExpKey = @"exp";
|
||||
static NSString *const kIatKey = @"iat";
|
||||
static NSString *const kNonceKey = @"nonce";
|
||||
|
||||
#import "OIDFieldMapping.h"
|
||||
|
||||
@implementation OIDIDToken
|
||||
|
||||
- (instancetype)initWithIDTokenString:(NSString *)idToken {
|
||||
self = [super init];
|
||||
NSArray *sections = [idToken componentsSeparatedByString:@"."];
|
||||
|
||||
// The header and claims sections are required.
|
||||
if (sections.count <= 1) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_header = [[self class] parseJWTSection:sections[0]];
|
||||
_claims = [[self class] parseJWTSection:sections[1]];
|
||||
if (!_header || !_claims) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
[OIDFieldMapping remainingParametersWithMap:[[self class] fieldMap]
|
||||
parameters:_claims
|
||||
instance:self];
|
||||
|
||||
// Required fields.
|
||||
if (!_issuer || !_audience || !_subject || !_expiresAt || !_issuedAt) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*! @brief Returns a mapping of incoming parameters to instance variables.
|
||||
@return A mapping of incoming parameters to instance variables.
|
||||
*/
|
||||
+ (NSDictionary<NSString *, OIDFieldMapping *> *)fieldMap {
|
||||
static NSMutableDictionary<NSString *, OIDFieldMapping *> *fieldMap;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
fieldMap = [NSMutableDictionary dictionary];
|
||||
|
||||
fieldMap[kIssKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_issuer"
|
||||
type:[NSURL class]
|
||||
conversion:[OIDFieldMapping URLConversion]];
|
||||
fieldMap[kSubKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_subject" type:[NSString class]];
|
||||
fieldMap[kAudKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_audience"
|
||||
type:[NSArray class]
|
||||
conversion:^id _Nullable(NSObject *_Nullable value) {
|
||||
if ([value isKindOfClass:[NSArray class]]) {
|
||||
return value;
|
||||
}
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
return @[value];
|
||||
}
|
||||
return nil;
|
||||
}];
|
||||
fieldMap[kExpKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_expiresAt"
|
||||
type:[NSDate class]
|
||||
conversion:^id _Nullable(NSObject *_Nullable value) {
|
||||
if (![value isKindOfClass:[NSNumber class]]) {
|
||||
return value;
|
||||
}
|
||||
NSNumber *valueAsNumber = (NSNumber *)value;
|
||||
return [NSDate dateWithTimeIntervalSince1970:valueAsNumber.longLongValue];
|
||||
}];
|
||||
fieldMap[kIatKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_issuedAt"
|
||||
type:[NSDate class]
|
||||
conversion:^id _Nullable(NSObject *_Nullable value) {
|
||||
if (![value isKindOfClass:[NSNumber class]]) {
|
||||
return value;
|
||||
}
|
||||
NSNumber *valueAsNumber = (NSNumber *)value;
|
||||
return [NSDate dateWithTimeIntervalSince1970:valueAsNumber.longLongValue];
|
||||
}];
|
||||
fieldMap[kNonceKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_nonce" type:[NSString class]];
|
||||
});
|
||||
return fieldMap;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)parseJWTSection:(NSString *)sectionString {
|
||||
NSData *decodedData = [[self class] base64urlNoPaddingDecode:sectionString];
|
||||
|
||||
// Parses JSON.
|
||||
NSError *error;
|
||||
id object = [NSJSONSerialization JSONObjectWithData:decodedData options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error %@ parsing token payload %@", error, sectionString);
|
||||
}
|
||||
if ([object isKindOfClass:[NSDictionary class]]) {
|
||||
return (NSDictionary *)object;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSData *)base64urlNoPaddingDecode:(NSString *)base64urlNoPaddingString {
|
||||
NSMutableString *body = [base64urlNoPaddingString mutableCopy];
|
||||
|
||||
// Converts base64url to base64.
|
||||
NSRange range = NSMakeRange(0, base64urlNoPaddingString.length);
|
||||
[body replaceOccurrencesOfString:@"-" withString:@"+" options:NSLiteralSearch range:range];
|
||||
[body replaceOccurrencesOfString:@"_" withString:@"/" options:NSLiteralSearch range:range];
|
||||
|
||||
// Converts base64 no padding to base64 with padding
|
||||
while (body.length % 4 != 0) {
|
||||
[body appendString:@"="];
|
||||
}
|
||||
|
||||
// Decodes base64 string.
|
||||
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:body options:0];
|
||||
return decodedData;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
/*! @file OIDRegistrationRequest.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 The AppAuth for iOS Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class OIDAuthorizationResponse;
|
||||
@class OIDServiceConfiguration;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Represents a registration request.
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest
|
||||
*/
|
||||
@interface OIDRegistrationRequest : NSObject <NSCopying, NSSecureCoding>
|
||||
|
||||
/*! @brief The service's configuration.
|
||||
@remarks This configuration specifies how to connect to a particular OAuth provider.
|
||||
Configurations may be created manually, or via an OpenID Connect Discovery Document.
|
||||
*/
|
||||
@property(nonatomic, readonly) OIDServiceConfiguration *configuration;
|
||||
|
||||
/*! @brief The initial access token to access the Client Registration Endpoint
|
||||
(if required by the OpenID Provider).
|
||||
@remarks OAuth 2.0 Access Token optionally issued by an Authorization Server granting
|
||||
access to its Client Registration Endpoint. This token (if required) is
|
||||
provisioned out of band.
|
||||
@see Section 3 of OpenID Connect Dynamic Client Registration 1.0
|
||||
https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString *initialAccessToken;
|
||||
|
||||
/*! @brief The application type to register, will always be 'native'.
|
||||
@remarks application_type
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString *applicationType;
|
||||
|
||||
/*! @brief The client's redirect URI's.
|
||||
@remarks redirect_uris
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.1.2
|
||||
*/
|
||||
@property(nonatomic, readonly) NSArray<NSURL *> *redirectURIs;
|
||||
|
||||
/*! @brief The response types to register for usage by this client.
|
||||
@remarks response_types
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#Authentication
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *responseTypes;
|
||||
|
||||
/*! @brief The grant types to register for usage by this client.
|
||||
@remarks grant_types
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *grantTypes;
|
||||
|
||||
/*! @brief The subject type to to request.
|
||||
@remarks subject_type
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *subjectType;
|
||||
|
||||
/*! @brief The client authentication method to use at the token endpoint.
|
||||
@remarks token_endpoint_auth_method
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *tokenEndpointAuthenticationMethod;
|
||||
|
||||
/*! @brief The client's additional token request parameters.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSDictionary<NSString *, NSString *> *additionalParameters;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use initWithConfiguration
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Create a Client Registration Request to an OpenID Provider that supports open Dynamic
|
||||
Registration.
|
||||
@param configuration The service's configuration.
|
||||
@param redirectURIs The redirect URIs to register for the client.
|
||||
@param responseTypes The response types to register for the client.
|
||||
@param grantTypes The grant types to register for the client.
|
||||
@param subjectType The subject type to register for the client.
|
||||
@param tokenEndpointAuthMethod The token endpoint authentication method to register for the
|
||||
client.
|
||||
@param additionalParameters The client's additional registration request parameters.
|
||||
*/
|
||||
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
redirectURIs:(NSArray<NSURL *> *)redirectURIs
|
||||
responseTypes:(nullable NSArray<NSString *> *)responseTypes
|
||||
grantTypes:(nullable NSArray<NSString *> *)grantTypes
|
||||
subjectType:(nullable NSString *)subjectType
|
||||
tokenEndpointAuthMethod:(nullable NSString *)tokenEndpointAuthMethod
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;
|
||||
|
||||
/*! @brief Designated initializer.
|
||||
@param configuration The service's configuration.
|
||||
@param redirectURIs The redirect URIs to register for the client.
|
||||
@param responseTypes The response types to register for the client.
|
||||
@param grantTypes The grant types to register for the client.
|
||||
@param subjectType The subject type to register for the client.
|
||||
@param tokenEndpointAuthMethod The token endpoint authentication method to register for the
|
||||
client.
|
||||
@param initialAccessToken The initial access token to access the Client Registration Endpoint
|
||||
(if required by the OpenID Provider).
|
||||
@param additionalParameters The client's additional registration request parameters.
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration
|
||||
*/
|
||||
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
redirectURIs:(NSArray<NSURL *> *)redirectURIs
|
||||
responseTypes:(nullable NSArray<NSString *> *)responseTypes
|
||||
grantTypes:(nullable NSArray<NSString *> *)grantTypes
|
||||
subjectType:(nullable NSString *)subjectType
|
||||
tokenEndpointAuthMethod:(nullable NSString *)tokenEndpointAuthMethod
|
||||
initialAccessToken:(nullable NSString *)initialAccessToken
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/*! @brief Constructs an @c NSURLRequest representing the registration request.
|
||||
@return An @c NSURLRequest representing the registration request.
|
||||
*/
|
||||
- (NSURLRequest *)URLRequest;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,248 +0,0 @@
|
||||
/*! @file OIDRegistrationRequest.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 The AppAuth for iOS Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDRegistrationRequest.h"
|
||||
|
||||
#import "OIDClientMetadataParameters.h"
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDServiceConfiguration.h"
|
||||
|
||||
/*! @brief The key for the @c configuration property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kConfigurationKey = @"configuration";
|
||||
|
||||
/*! @brief The key for the @c initialAccessToken property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kInitialAccessToken = @"initial_access_token";
|
||||
|
||||
/*! @brief Key used to encode the @c redirectURIs property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kRedirectURIsKey = @"redirect_uris";
|
||||
|
||||
/*! @brief The key for the @c responseTypes property for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kResponseTypesKey = @"response_types";
|
||||
|
||||
/*! @brief Key used to encode the @c grantType property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kGrantTypesKey = @"grant_types";
|
||||
|
||||
/*! @brief Key used to encode the @c subjectType property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kSubjectTypeKey = @"subject_type";
|
||||
|
||||
/*! @brief Key used to encode the @c additionalParameters property for
|
||||
@c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kAdditionalParametersKey = @"additionalParameters";
|
||||
|
||||
@implementation OIDRegistrationRequest
|
||||
|
||||
#pragma mark - Initializers
|
||||
|
||||
- (instancetype)init
|
||||
OID_UNAVAILABLE_USE_INITIALIZER(
|
||||
@selector(initWithConfiguration:
|
||||
redirectURIs:
|
||||
responseTypes:
|
||||
grantTypes:
|
||||
subjectType:
|
||||
tokenEndpointAuthMethod:
|
||||
additionalParameters:)
|
||||
)
|
||||
|
||||
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
redirectURIs:(NSArray<NSURL *> *)redirectURIs
|
||||
responseTypes:(nullable NSArray<NSString *> *)responseTypes
|
||||
grantTypes:(nullable NSArray<NSString *> *)grantTypes
|
||||
subjectType:(nullable NSString *)subjectType
|
||||
tokenEndpointAuthMethod:(nullable NSString *)tokenEndpointAuthenticationMethod
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters {
|
||||
return [self initWithConfiguration:configuration
|
||||
redirectURIs:redirectURIs
|
||||
responseTypes:responseTypes
|
||||
grantTypes:grantTypes
|
||||
subjectType:subjectType
|
||||
tokenEndpointAuthMethod:tokenEndpointAuthenticationMethod
|
||||
initialAccessToken:nil
|
||||
additionalParameters:additionalParameters];
|
||||
}
|
||||
|
||||
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
redirectURIs:(NSArray<NSURL *> *)redirectURIs
|
||||
responseTypes:(nullable NSArray<NSString *> *)responseTypes
|
||||
grantTypes:(nullable NSArray<NSString *> *)grantTypes
|
||||
subjectType:(nullable NSString *)subjectType
|
||||
tokenEndpointAuthMethod:(nullable NSString *)tokenEndpointAuthenticationMethod
|
||||
initialAccessToken:(nullable NSString *)initialAccessToken
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_configuration = [configuration copy];
|
||||
_initialAccessToken = [initialAccessToken copy];
|
||||
_redirectURIs = [redirectURIs copy];
|
||||
_responseTypes = [responseTypes copy];
|
||||
_grantTypes = [grantTypes copy];
|
||||
_subjectType = [subjectType copy];
|
||||
_tokenEndpointAuthenticationMethod = [tokenEndpointAuthenticationMethod copy];
|
||||
_additionalParameters =
|
||||
[[NSDictionary alloc] initWithDictionary:additionalParameters copyItems:YES];
|
||||
|
||||
_applicationType = OIDApplicationTypeNative;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
// The documentation for NSCopying specifically advises us to return a reference to the original
|
||||
// instance in the case where instances are immutable (as ours is):
|
||||
// "Implement NSCopying by retaining the original instead of creating a new copy when the class
|
||||
// and its contents are immutable."
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
OIDServiceConfiguration *configuration =
|
||||
[aDecoder decodeObjectOfClass:[OIDServiceConfiguration class]
|
||||
forKey:kConfigurationKey];
|
||||
NSString *initialAccessToken = [aDecoder decodeObjectOfClass:[NSString class]
|
||||
forKey:kInitialAccessToken];
|
||||
NSArray<NSURL *> *redirectURIs = [aDecoder decodeObjectOfClass:[NSArray<NSURL *> class]
|
||||
forKey:kRedirectURIsKey];
|
||||
NSArray<NSString *> *responseTypes = [aDecoder decodeObjectOfClass:[NSArray<NSString *> class]
|
||||
forKey:kResponseTypesKey];
|
||||
NSArray<NSString *> *grantTypes = [aDecoder decodeObjectOfClass:[NSArray<NSString *> class]
|
||||
forKey:kGrantTypesKey];
|
||||
NSString *subjectType = [aDecoder decodeObjectOfClass:[NSString class]
|
||||
forKey:kSubjectTypeKey];
|
||||
NSString *tokenEndpointAuthenticationMethod =
|
||||
[aDecoder decodeObjectOfClass:[NSString class]
|
||||
forKey:OIDTokenEndpointAuthenticationMethodParam];
|
||||
NSSet *additionalParameterCodingClasses = [NSSet setWithArray:@[ [NSDictionary class],
|
||||
[NSString class] ]];
|
||||
NSDictionary *additionalParameters =
|
||||
[aDecoder decodeObjectOfClasses:additionalParameterCodingClasses
|
||||
forKey:kAdditionalParametersKey];
|
||||
self = [self initWithConfiguration:configuration
|
||||
redirectURIs:redirectURIs
|
||||
responseTypes:responseTypes
|
||||
grantTypes:grantTypes
|
||||
subjectType:subjectType
|
||||
tokenEndpointAuthMethod:tokenEndpointAuthenticationMethod
|
||||
initialAccessToken:initialAccessToken
|
||||
additionalParameters:additionalParameters];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[aCoder encodeObject:_configuration forKey:kConfigurationKey];
|
||||
[aCoder encodeObject:_initialAccessToken forKey:kInitialAccessToken];
|
||||
[aCoder encodeObject:_redirectURIs forKey:kRedirectURIsKey];
|
||||
[aCoder encodeObject:_responseTypes forKey:kResponseTypesKey];
|
||||
[aCoder encodeObject:_grantTypes forKey:kGrantTypesKey];
|
||||
[aCoder encodeObject:_subjectType forKey:kSubjectTypeKey];
|
||||
[aCoder encodeObject:_tokenEndpointAuthenticationMethod
|
||||
forKey:OIDTokenEndpointAuthenticationMethodParam];
|
||||
[aCoder encodeObject:_additionalParameters forKey:kAdditionalParametersKey];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject overrides
|
||||
|
||||
- (NSString *)description {
|
||||
NSURLRequest *request = [self URLRequest];
|
||||
NSString *requestBody = [[NSString alloc] initWithData:request.HTTPBody
|
||||
encoding:NSUTF8StringEncoding];
|
||||
return [NSString stringWithFormat:@"<%@: %p, request: <URL: %@, HTTPBody: %@>>",
|
||||
NSStringFromClass([self class]),
|
||||
(void *)self,
|
||||
request.URL,
|
||||
requestBody];
|
||||
}
|
||||
|
||||
- (NSURLRequest *)URLRequest {
|
||||
static NSString *const kHTTPPost = @"POST";
|
||||
static NSString *const kBearer = @"Bearer";
|
||||
static NSString *const kHTTPContentTypeHeaderKey = @"Content-Type";
|
||||
static NSString *const kHTTPContentTypeHeaderValue = @"application/json";
|
||||
static NSString *const kHTTPAuthorizationHeaderKey = @"Authorization";
|
||||
|
||||
NSData *postBody = [self JSONString];
|
||||
if (!postBody) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSURL *registrationRequestURL = _configuration.registrationEndpoint;
|
||||
NSMutableURLRequest *URLRequest =
|
||||
[[NSURLRequest requestWithURL:registrationRequestURL] mutableCopy];
|
||||
URLRequest.HTTPMethod = kHTTPPost;
|
||||
[URLRequest setValue:kHTTPContentTypeHeaderValue forHTTPHeaderField:kHTTPContentTypeHeaderKey];
|
||||
if (_initialAccessToken) {
|
||||
NSString *value = [NSString stringWithFormat:@"%@ %@", kBearer, _initialAccessToken];
|
||||
[URLRequest setValue:value forHTTPHeaderField:kHTTPAuthorizationHeaderKey];
|
||||
}
|
||||
URLRequest.HTTPBody = postBody;
|
||||
return URLRequest;
|
||||
}
|
||||
|
||||
- (NSData *)JSONString {
|
||||
// Dictionary with several kay/value pairs and the above array of arrays
|
||||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
||||
NSMutableArray<NSString *> *redirectURIStrings =
|
||||
[NSMutableArray arrayWithCapacity:[_redirectURIs count]];
|
||||
for (id obj in _redirectURIs) {
|
||||
[redirectURIStrings addObject:[obj absoluteString]];
|
||||
}
|
||||
dict[OIDRedirectURIsParam] = redirectURIStrings;
|
||||
dict[OIDApplicationTypeParam] = _applicationType;
|
||||
|
||||
if (_additionalParameters) {
|
||||
// Add any additional parameters first to allow them
|
||||
// to be overwritten by instance values
|
||||
[dict addEntriesFromDictionary:_additionalParameters];
|
||||
}
|
||||
if (_responseTypes) {
|
||||
dict[OIDResponseTypesParam] = _responseTypes;
|
||||
}
|
||||
if (_grantTypes) {
|
||||
dict[OIDGrantTypesParam] = _grantTypes;
|
||||
}
|
||||
if (_subjectType) {
|
||||
dict[OIDSubjectTypeParam] = _subjectType;
|
||||
}
|
||||
if (_tokenEndpointAuthenticationMethod) {
|
||||
dict[OIDTokenEndpointAuthenticationMethodParam] = _tokenEndpointAuthenticationMethod;
|
||||
}
|
||||
|
||||
NSError *error;
|
||||
NSData *json = [NSJSONSerialization dataWithJSONObject:dict options:kNilOptions error:&error];
|
||||
if (json == nil || error != nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,126 +0,0 @@
|
||||
/*! @file OIDRegistrationResponse.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 The AppAuth for iOS Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class OIDRegistrationRequest;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Parameter name for the client id.
|
||||
*/
|
||||
extern NSString *const OIDClientIDParam;
|
||||
|
||||
/*! @brief Parameter name for the client id issuance timestamp.
|
||||
*/
|
||||
extern NSString *const OIDClientIDIssuedAtParam;
|
||||
|
||||
/*! @brief Parameter name for the client secret.
|
||||
*/
|
||||
extern NSString *const OIDClientSecretParam;
|
||||
|
||||
/*! @brief Parameter name for the client secret expiration time.
|
||||
*/
|
||||
extern NSString *const OIDClientSecretExpirestAtParam;
|
||||
|
||||
/*! @brief Parameter name for the registration access token.
|
||||
*/
|
||||
extern NSString *const OIDRegistrationAccessTokenParam;
|
||||
|
||||
/*! @brief Parameter name for the client configuration URI.
|
||||
*/
|
||||
extern NSString *const OIDRegistrationClientURIParam;
|
||||
|
||||
/*! @brief Represents a registration response.
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse
|
||||
*/
|
||||
@interface OIDRegistrationResponse : NSObject <NSCopying, NSSecureCoding>
|
||||
|
||||
/*! @brief The request which was serviced.
|
||||
*/
|
||||
@property(nonatomic, readonly) OIDRegistrationRequest *request;
|
||||
|
||||
/*! @brief The registered client identifier.
|
||||
@remarks client_id
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.1
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString *clientID;
|
||||
|
||||
/*! @brief Timestamp of when the client identifier was issued, if provided.
|
||||
@remarks client_id_issued_at
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSDate *clientIDIssuedAt;
|
||||
|
||||
/*! @brief TThe client secret, which is part of the client credentials, if provided.
|
||||
@remarks client_secret
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *clientSecret;
|
||||
|
||||
/*! @brief Timestamp of when the client credentials expires, if provided.
|
||||
@remarks client_secret_expires_at
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSDate *clientSecretExpiresAt;
|
||||
|
||||
/*! @brief Client registration access token that can be used for subsequent operations upon the
|
||||
client registration.
|
||||
@remarks registration_access_token
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *registrationAccessToken;
|
||||
|
||||
/*! @brief Location of the client configuration endpoint, if provided.
|
||||
@remarks registration_client_uri
|
||||
@see https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *registrationClientURI;
|
||||
|
||||
/*! @brief Client authentication method to use at the token endpoint, if provided.
|
||||
@remarks token_endpoint_auth_method
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *tokenEndpointAuthenticationMethod;
|
||||
|
||||
/*! @brief Additional parameters returned from the token server.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSDictionary<NSString *, NSObject <NSCopying> *>
|
||||
*additionalParameters;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use initWithRequest
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Designated initializer.
|
||||
@param request The serviced request.
|
||||
@param parameters The decoded parameters returned from the Authorization Server.
|
||||
@remarks Known parameters are extracted from the @c parameters parameter and the normative
|
||||
properties are populated. Non-normative parameters are placed in the
|
||||
@c #additionalParameters dictionary.
|
||||
*/
|
||||
- (instancetype)initWithRequest:(OIDRegistrationRequest *)request
|
||||
parameters:(NSDictionary<NSString *, NSObject <NSCopying> *> *)parameters
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,164 +0,0 @@
|
||||
/*! @file OIDRegistrationResponse.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2016 The AppAuth for iOS Authors. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDRegistrationResponse.h"
|
||||
|
||||
#import "OIDClientMetadataParameters.h"
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDFieldMapping.h"
|
||||
#import "OIDRegistrationRequest.h"
|
||||
#import "OIDTokenUtilities.h"
|
||||
|
||||
NSString *const OIDClientIDParam = @"client_id";
|
||||
NSString *const OIDClientIDIssuedAtParam = @"client_id_issued_at";
|
||||
NSString *const OIDClientSecretParam = @"client_secret";
|
||||
NSString *const OIDClientSecretExpirestAtParam = @"client_secret_expires_at";
|
||||
NSString *const OIDRegistrationAccessTokenParam = @"registration_access_token";
|
||||
NSString *const OIDRegistrationClientURIParam = @"registration_client_uri";
|
||||
|
||||
/*! @brief Key used to encode the @c request property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kRequestKey = @"request";
|
||||
|
||||
/*! @brief Key used to encode the @c additionalParameters property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kAdditionalParametersKey = @"additionalParameters";
|
||||
|
||||
@implementation OIDRegistrationResponse
|
||||
|
||||
/*! @brief Returns a mapping of incoming parameters to instance variables.
|
||||
@return A mapping of incoming parameters to instance variables.
|
||||
*/
|
||||
+ (NSDictionary<NSString *, OIDFieldMapping *> *)fieldMap {
|
||||
static NSMutableDictionary<NSString *, OIDFieldMapping *> *fieldMap;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
fieldMap = [NSMutableDictionary dictionary];
|
||||
fieldMap[OIDClientIDParam] = [[OIDFieldMapping alloc] initWithName:@"_clientID"
|
||||
type:[NSString class]];
|
||||
fieldMap[OIDClientIDIssuedAtParam] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_clientIDIssuedAt"
|
||||
type:[NSDate class]
|
||||
conversion:[OIDFieldMapping dateEpochConversion]];
|
||||
fieldMap[OIDClientSecretParam] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_clientSecret"
|
||||
type:[NSString class]];
|
||||
fieldMap[OIDClientSecretExpirestAtParam] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_clientSecretExpiresAt"
|
||||
type:[NSDate class]
|
||||
conversion:[OIDFieldMapping dateEpochConversion]];
|
||||
fieldMap[OIDRegistrationAccessTokenParam] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_registrationAccessToken"
|
||||
type:[NSString class]];
|
||||
fieldMap[OIDRegistrationClientURIParam] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_registrationClientURI"
|
||||
type:[NSURL class]
|
||||
conversion:[OIDFieldMapping URLConversion]];
|
||||
fieldMap[OIDTokenEndpointAuthenticationMethodParam] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_tokenEndpointAuthenticationMethod"
|
||||
type:[NSString class]];
|
||||
});
|
||||
return fieldMap;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Initializers
|
||||
|
||||
- (nonnull instancetype)init
|
||||
OID_UNAVAILABLE_USE_INITIALIZER(@selector(initWithRequest:parameters:))
|
||||
|
||||
- (instancetype)initWithRequest:(OIDRegistrationRequest *)request
|
||||
parameters:(NSDictionary<NSString *, NSObject <NSCopying> *> *)parameters {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_request = [request copy];
|
||||
NSDictionary<NSString *, NSObject <NSCopying> *> *additionalParameters =
|
||||
[OIDFieldMapping remainingParametersWithMap:[[self class] fieldMap]
|
||||
parameters:parameters
|
||||
instance:self];
|
||||
_additionalParameters = additionalParameters;
|
||||
|
||||
if ((_clientSecret && !_clientSecretExpiresAt)
|
||||
|| (!!_registrationClientURI != !!_registrationAccessToken)) {
|
||||
// If client_secret is issued, client_secret_expires_at is REQUIRED,
|
||||
// and the response MUST contain "[...] both a Client Configuration Endpoint
|
||||
// and a Registration Access Token or neither of them"
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
// The documentation for NSCopying specifically advises us to return a reference to the original
|
||||
// instance in the case where instances are immutable (as ours is):
|
||||
// "Implement NSCopying by retaining the original instead of creating a new copy when the class
|
||||
// and its contents are immutable."
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
OIDRegistrationRequest *request = [aDecoder decodeObjectOfClass:[OIDRegistrationRequest class]
|
||||
forKey:kRequestKey];
|
||||
self = [self initWithRequest:request
|
||||
parameters:@{}];
|
||||
if (self) {
|
||||
[OIDFieldMapping decodeWithCoder:aDecoder
|
||||
map:[[self class] fieldMap]
|
||||
instance:self];
|
||||
_additionalParameters = [aDecoder decodeObjectOfClasses:[OIDFieldMapping JSONTypes]
|
||||
forKey:kAdditionalParametersKey];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[OIDFieldMapping encodeWithCoder:aCoder map:[[self class] fieldMap] instance:self];
|
||||
[aCoder encodeObject:_request forKey:kRequestKey];
|
||||
[aCoder encodeObject:_additionalParameters forKey:kAdditionalParametersKey];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject overrides
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, clientID: \"%@\", clientIDIssuedAt: %@, "
|
||||
"clientSecret: %@, clientSecretExpiresAt: \"%@\", "
|
||||
"registrationAccessToken: \"%@\", "
|
||||
"registrationClientURI: \"%@\", "
|
||||
"additionalParameters: %@, request: %@>",
|
||||
NSStringFromClass([self class]),
|
||||
(void *)self,
|
||||
_clientID,
|
||||
_clientIDIssuedAt,
|
||||
[OIDTokenUtilities redact:_clientSecret],
|
||||
_clientSecretExpiresAt,
|
||||
[OIDTokenUtilities redact:_registrationAccessToken],
|
||||
_registrationClientURI,
|
||||
_additionalParameters,
|
||||
_request];
|
||||
}
|
||||
|
||||
@end
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*! @file OIDResponseTypes.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/*! @brief A constant for the standard OAuth2 Response Type of 'code'.
|
||||
*/
|
||||
extern NSString *const OIDResponseTypeCode;
|
||||
|
||||
/*! @brief A constant for the standard OAuth2 Response Type of 'token'.
|
||||
*/
|
||||
extern NSString *const OIDResponseTypeToken;
|
||||
|
||||
/*! @brief A constant for the standard OAuth2 Response Type of 'id_token'.
|
||||
*/
|
||||
extern NSString *const OIDResponseTypeIDToken;
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
/*! @file OIDResponseTypes.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDResponseTypes.h"
|
||||
|
||||
NSString *const OIDResponseTypeCode = @"code";
|
||||
|
||||
NSString *const OIDResponseTypeToken = @"token";
|
||||
|
||||
NSString *const OIDResponseTypeIDToken = @"id_token";
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
/*! @file OIDScopeUtilities.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Provides convenience methods for dealing with scope strings.
|
||||
*/
|
||||
@interface OIDScopeUtilities : NSObject
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. This class should not be initialized.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Converts an array of scope strings to a single scope string per the OAuth 2 spec.
|
||||
@param scopes An array of scope strings.
|
||||
@return A space-delimited string of scopes.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.3
|
||||
*/
|
||||
+ (NSString *)scopesWithArray:(NSArray<NSString *> *)scopes;
|
||||
|
||||
/*! @brief Converts an OAuth 2 spec-compliant scope string to an array of scopes.
|
||||
@param scopes An OAuth 2 spec-compliant scope string.
|
||||
@return An array of scope strings.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.3
|
||||
*/
|
||||
+ (NSArray<NSString *> *)scopesArrayWithString:(NSString *)scopes;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
/*! @file OIDScopeUtilities.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDScopeUtilities.h"
|
||||
|
||||
@implementation OIDScopeUtilities
|
||||
|
||||
/*! @brief A character set with the characters NOT allowed in a scope name.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.3
|
||||
*/
|
||||
+ (NSCharacterSet *)disallowedScopeCharacters {
|
||||
static NSCharacterSet *disallowedCharacters;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSMutableCharacterSet *allowedCharacters;
|
||||
allowedCharacters =
|
||||
[NSMutableCharacterSet characterSetWithRange:NSMakeRange(0x23, 0x5B - 0x23 + 1)];
|
||||
[allowedCharacters addCharactersInRange:NSMakeRange(0x5D, 0x7E - 0x5D + 1)];
|
||||
[allowedCharacters addCharactersInString:@"\x21"];
|
||||
disallowedCharacters = [allowedCharacters invertedSet];
|
||||
});
|
||||
return disallowedCharacters;
|
||||
}
|
||||
|
||||
+ (NSString *)scopesWithArray:(NSArray<NSString *> *)scopes {
|
||||
#if !defined(NS_BLOCK_ASSERTIONS)
|
||||
NSCharacterSet *disallowedCharacters = [self disallowedScopeCharacters];
|
||||
for (NSString *scope in scopes) {
|
||||
NSAssert(scope.length, @"Found illegal empty scope string.");
|
||||
NSAssert([scope rangeOfCharacterFromSet:disallowedCharacters].location == NSNotFound,
|
||||
@"Found illegal character in scope string.");
|
||||
}
|
||||
#endif // !defined(NS_BLOCK_ASSERTIONS)
|
||||
|
||||
NSString *scopeString = [scopes componentsJoinedByString:@" "];
|
||||
return scopeString;
|
||||
}
|
||||
|
||||
+ (NSArray<NSString *> *)scopesArrayWithString:(NSString *)scopes {
|
||||
return [scopes componentsSeparatedByString:@" "];
|
||||
}
|
||||
|
||||
@end
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
/*! @file OIDScopes.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/*! @brief Scope that indicates this request is an OpenID Connect request.
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#AuthRequestValidation
|
||||
*/
|
||||
extern NSString *const OIDScopeOpenID;
|
||||
|
||||
/*! @brief This scope value requests access to the End-User's default profile Claims, which are:
|
||||
name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture,
|
||||
website, gender, birthdate, zoneinfo, locale, and updated_at.
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
|
||||
*/
|
||||
extern NSString *const OIDScopeProfile;
|
||||
|
||||
/*! @brief This scope value requests access to the email and email_verified Claims.
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
|
||||
*/
|
||||
extern NSString *const OIDScopeEmail;
|
||||
|
||||
/*! @brief This scope value requests access to the address Claim.
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
|
||||
*/
|
||||
extern NSString *const OIDScopeAddress;
|
||||
|
||||
/*! @brief This scope value requests access to the phone_number and phone_number_verified Claims.
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
|
||||
*/
|
||||
extern NSString *const OIDScopePhone;
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*! @file OIDScopes.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDScopes.h"
|
||||
|
||||
NSString *const OIDScopeOpenID = @"openid";
|
||||
|
||||
NSString *const OIDScopeProfile = @"profile";
|
||||
|
||||
NSString *const OIDScopeEmail = @"email";
|
||||
|
||||
NSString *const OIDScopeAddress = @"address";
|
||||
|
||||
NSString *const OIDScopePhone = @"phone";
|
||||
@@ -1,118 +0,0 @@
|
||||
/*! @file OIDServiceConfiguration.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class OIDServiceConfiguration;
|
||||
@class OIDServiceDiscovery;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief The type of block called when a @c OIDServiceConfiguration has been created
|
||||
by loading a @c OIDServiceDiscovery from an @c NSURL.
|
||||
*/
|
||||
typedef void (^OIDServiceConfigurationCreated)
|
||||
(OIDServiceConfiguration *_Nullable serviceConfiguration,
|
||||
NSError *_Nullable error);
|
||||
|
||||
/*! @brief Represents the information needed to construct a @c OIDAuthorizationService.
|
||||
*/
|
||||
@interface OIDServiceConfiguration : NSObject <NSCopying, NSSecureCoding>
|
||||
|
||||
/*! @brief The authorization endpoint URI.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSURL *authorizationEndpoint;
|
||||
|
||||
/*! @brief The token exchange and refresh endpoint URI.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSURL *tokenEndpoint;
|
||||
|
||||
/*! @brief The OpenID Connect issuer.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *issuer;
|
||||
|
||||
/*! @brief The dynamic client registration endpoint URI.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *registrationEndpoint;
|
||||
|
||||
/*! @brief The end session logout endpoint URI.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *endSessionEndpoint;
|
||||
|
||||
/*! @brief The discovery document.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) OIDServiceDiscovery *discoveryDocument;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use @c initWithAuthorizationEndpoint:tokenEndpoint: or
|
||||
@c initWithDiscoveryDocument:.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @param authorizationEndpoint The authorization endpoint URI.
|
||||
@param tokenEndpoint The token exchange and refresh endpoint URI.
|
||||
*/
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint;
|
||||
|
||||
/*! @param authorizationEndpoint The authorization endpoint URI.
|
||||
@param tokenEndpoint The token exchange and refresh endpoint URI.
|
||||
@param registrationEndpoint The dynamic client registration endpoint URI.
|
||||
*/
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint
|
||||
registrationEndpoint:(nullable NSURL *)registrationEndpoint;
|
||||
|
||||
/*! @param authorizationEndpoint The authorization endpoint URI.
|
||||
@param tokenEndpoint The token exchange and refresh endpoint URI.
|
||||
@param issuer The OpenID Connect issuer.
|
||||
*/
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint
|
||||
issuer:(nullable NSURL *)issuer;
|
||||
|
||||
/*! @param authorizationEndpoint The authorization endpoint URI.
|
||||
@param tokenEndpoint The token exchange and refresh endpoint URI.
|
||||
@param issuer The OpenID Connect issuer.
|
||||
@param registrationEndpoint The dynamic client registration endpoint URI.
|
||||
*/
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint
|
||||
issuer:(nullable NSURL *)issuer
|
||||
registrationEndpoint:(nullable NSURL *)registrationEndpoint;
|
||||
|
||||
/*! @param authorizationEndpoint The authorization endpoint URI.
|
||||
@param tokenEndpoint The token exchange and refresh endpoint URI.
|
||||
@param issuer The OpenID Connect issuer.
|
||||
@param registrationEndpoint The dynamic client registration endpoint URI.
|
||||
@param endSessionEndpoint The end session endpoint (logout) URI.
|
||||
*/
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint
|
||||
issuer:(nullable NSURL *)issuer
|
||||
registrationEndpoint:(nullable NSURL *)registrationEndpoint
|
||||
endSessionEndpoint:(nullable NSURL *)endSessionEndpoint;
|
||||
|
||||
/*! @param discoveryDocument The discovery document from which to extract the required OAuth
|
||||
configuration.
|
||||
*/
|
||||
- (instancetype)initWithDiscoveryDocument:(OIDServiceDiscovery *)discoveryDocument;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,223 +0,0 @@
|
||||
/*! @file OIDServiceConfiguration.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDServiceConfiguration.h"
|
||||
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDErrorUtilities.h"
|
||||
#import "OIDServiceDiscovery.h"
|
||||
|
||||
/*! @brief The key for the @c authorizationEndpoint property.
|
||||
*/
|
||||
static NSString *const kAuthorizationEndpointKey = @"authorizationEndpoint";
|
||||
|
||||
/*! @brief The key for the @c tokenEndpoint property.
|
||||
*/
|
||||
static NSString *const kTokenEndpointKey = @"tokenEndpoint";
|
||||
|
||||
/*! @brief The key for the @c issuer property.
|
||||
*/
|
||||
static NSString *const kIssuerKey = @"issuer";
|
||||
|
||||
/*! @brief The key for the @c registrationEndpoint property.
|
||||
*/
|
||||
static NSString *const kRegistrationEndpointKey = @"registrationEndpoint";
|
||||
|
||||
/*! @brief The key for the @c endSessionEndpoint property.
|
||||
*/
|
||||
static NSString *const kEndSessionEndpointKey = @"endSessionEndpoint";
|
||||
|
||||
/*! @brief The key for the @c discoveryDocument property.
|
||||
*/
|
||||
static NSString *const kDiscoveryDocumentKey = @"discoveryDocument";
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OIDServiceConfiguration ()
|
||||
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint
|
||||
issuer:(nullable NSURL *)issuer
|
||||
registrationEndpoint:(nullable NSURL *)registrationEndpoint
|
||||
endSessionEndpoint:(nullable NSURL *)endSessionEndpoint
|
||||
discoveryDocument:(nullable OIDServiceDiscovery *)discoveryDocument
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OIDServiceConfiguration
|
||||
|
||||
- (instancetype)init
|
||||
OID_UNAVAILABLE_USE_INITIALIZER(@selector(
|
||||
initWithAuthorizationEndpoint:
|
||||
tokenEndpoint:)
|
||||
)
|
||||
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint
|
||||
issuer:(nullable NSURL *)issuer
|
||||
registrationEndpoint:(nullable NSURL *)registrationEndpoint
|
||||
endSessionEndpoint:(nullable OIDServiceDiscovery *)endSessionEndpoint
|
||||
discoveryDocument:(nullable OIDServiceDiscovery *)discoveryDocument {
|
||||
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_authorizationEndpoint = [authorizationEndpoint copy];
|
||||
_tokenEndpoint = [tokenEndpoint copy];
|
||||
_issuer = [issuer copy];
|
||||
_registrationEndpoint = [registrationEndpoint copy];
|
||||
_endSessionEndpoint = [endSessionEndpoint copy];
|
||||
_discoveryDocument = [discoveryDocument copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint {
|
||||
return [self initWithAuthorizationEndpoint:authorizationEndpoint
|
||||
tokenEndpoint:tokenEndpoint
|
||||
issuer:nil
|
||||
registrationEndpoint:nil
|
||||
endSessionEndpoint:nil
|
||||
discoveryDocument:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint
|
||||
registrationEndpoint:(nullable NSURL *)registrationEndpoint {
|
||||
return [self initWithAuthorizationEndpoint:authorizationEndpoint
|
||||
tokenEndpoint:tokenEndpoint
|
||||
issuer:nil
|
||||
registrationEndpoint:registrationEndpoint
|
||||
endSessionEndpoint:nil
|
||||
discoveryDocument:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint
|
||||
issuer:(nullable NSURL *)issuer {
|
||||
return [self initWithAuthorizationEndpoint:authorizationEndpoint
|
||||
tokenEndpoint:tokenEndpoint
|
||||
issuer:issuer
|
||||
registrationEndpoint:nil
|
||||
endSessionEndpoint:nil
|
||||
discoveryDocument:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint
|
||||
issuer:(nullable NSURL *)issuer
|
||||
registrationEndpoint:(nullable NSURL *)registrationEndpoint {
|
||||
return [self initWithAuthorizationEndpoint:authorizationEndpoint
|
||||
tokenEndpoint:tokenEndpoint
|
||||
issuer:issuer
|
||||
registrationEndpoint:registrationEndpoint
|
||||
endSessionEndpoint:nil
|
||||
discoveryDocument:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithAuthorizationEndpoint:(NSURL *)authorizationEndpoint
|
||||
tokenEndpoint:(NSURL *)tokenEndpoint
|
||||
issuer:(nullable NSURL *)issuer
|
||||
registrationEndpoint:(nullable NSURL *)registrationEndpoint
|
||||
endSessionEndpoint:(nullable NSURL *)endSessionEndpoint {
|
||||
return [self initWithAuthorizationEndpoint:authorizationEndpoint
|
||||
tokenEndpoint:tokenEndpoint
|
||||
issuer:issuer
|
||||
registrationEndpoint:registrationEndpoint
|
||||
endSessionEndpoint:endSessionEndpoint
|
||||
discoveryDocument:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithDiscoveryDocument:(OIDServiceDiscovery *) discoveryDocument {
|
||||
return [self initWithAuthorizationEndpoint:discoveryDocument.authorizationEndpoint
|
||||
tokenEndpoint:discoveryDocument.tokenEndpoint
|
||||
issuer:discoveryDocument.issuer
|
||||
registrationEndpoint:discoveryDocument.registrationEndpoint
|
||||
endSessionEndpoint:discoveryDocument.endSessionEndpoint
|
||||
discoveryDocument:discoveryDocument];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
// The documentation for NSCopying specifically advises us to return a reference to the original
|
||||
// instance in the case where instances are immutable (as ours is):
|
||||
// "Implement NSCopying by retaining the original instead of creating a new copy when the class
|
||||
// and its contents are immutable."
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
NSURL *authorizationEndpoint = [aDecoder decodeObjectOfClass:[NSURL class]
|
||||
forKey:kAuthorizationEndpointKey];
|
||||
NSURL *tokenEndpoint = [aDecoder decodeObjectOfClass:[NSURL class]
|
||||
forKey:kTokenEndpointKey];
|
||||
NSURL *issuer = [aDecoder decodeObjectOfClass:[NSURL class]
|
||||
forKey:kIssuerKey];
|
||||
NSURL *registrationEndpoint = [aDecoder decodeObjectOfClass:[NSURL class]
|
||||
forKey:kRegistrationEndpointKey];
|
||||
NSURL *endSessionEndpoint = [aDecoder decodeObjectOfClass:[NSURL class]
|
||||
forKey:kEndSessionEndpointKey];
|
||||
// We don't accept nil authorizationEndpoints or tokenEndpoints.
|
||||
if (!authorizationEndpoint || !tokenEndpoint) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
OIDServiceDiscovery *discoveryDocument = [aDecoder decodeObjectOfClass:[OIDServiceDiscovery class]
|
||||
forKey:kDiscoveryDocumentKey];
|
||||
|
||||
return [self initWithAuthorizationEndpoint:authorizationEndpoint
|
||||
tokenEndpoint:tokenEndpoint
|
||||
issuer:issuer
|
||||
registrationEndpoint:registrationEndpoint
|
||||
endSessionEndpoint:endSessionEndpoint
|
||||
discoveryDocument:discoveryDocument];
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[aCoder encodeObject:_authorizationEndpoint forKey:kAuthorizationEndpointKey];
|
||||
[aCoder encodeObject:_tokenEndpoint forKey:kTokenEndpointKey];
|
||||
[aCoder encodeObject:_issuer forKey:kIssuerKey];
|
||||
[aCoder encodeObject:_registrationEndpoint forKey:kRegistrationEndpointKey];
|
||||
[aCoder encodeObject:_discoveryDocument forKey:kDiscoveryDocumentKey];
|
||||
[aCoder encodeObject:_endSessionEndpoint forKey:kEndSessionEndpointKey];
|
||||
}
|
||||
|
||||
#pragma mark - description
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:
|
||||
@"OIDServiceConfiguration authorizationEndpoint: %@, tokenEndpoint: %@, "
|
||||
"registrationEndpoint: %@, endSessionEndpoint: %@, discoveryDocument: [%@]",
|
||||
_authorizationEndpoint,
|
||||
_tokenEndpoint,
|
||||
_registrationEndpoint,
|
||||
_endSessionEndpoint,
|
||||
_discoveryDocument];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-358
@@ -1,358 +0,0 @@
|
||||
/*! @file OIDServiceDiscovery.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Represents an OpenID Connect 1.0 Discovery Document
|
||||
@see https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
*/
|
||||
@interface OIDServiceDiscovery : NSObject <NSCopying, NSSecureCoding>
|
||||
|
||||
/*! @brief The decoded OpenID Connect 1.0 Discovery Document as a dictionary.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSDictionary<NSString *, id> *discoveryDictionary;
|
||||
|
||||
/*! @brief REQUIRED. URL using the @c https scheme with no query or fragment component that the OP
|
||||
asserts as its Issuer Identifier. If Issuer discovery is supported, this value MUST be
|
||||
identical to the issuer value returned by WebFinger. This also MUST be identical to the
|
||||
@c iss Claim value in ID Tokens issued from this Issuer.
|
||||
@remarks issuer
|
||||
@seealso https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery
|
||||
*/
|
||||
@property(nonatomic, readonly) NSURL *issuer;
|
||||
|
||||
/*! @brief REQUIRED. URL of the OP's OAuth 2.0 Authorization Endpoint.
|
||||
@remarks authorization_endpoint
|
||||
@seealso http://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint
|
||||
*/
|
||||
@property(nonatomic, readonly) NSURL *authorizationEndpoint;
|
||||
|
||||
/*! @brief URL of the OP's OAuth 2.0 Token Endpoint. This is REQUIRED unless only the Implicit Flow
|
||||
is used.
|
||||
@remarks token_endpoint
|
||||
@seealso http://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
|
||||
*/
|
||||
@property(nonatomic, readonly) NSURL *tokenEndpoint;
|
||||
|
||||
/*! @brief RECOMMENDED. URL of the OP's UserInfo Endpoint. This URL MUST use the https scheme and
|
||||
MAY contain port, path, and query parameter components.
|
||||
@remarks userinfo_endpoint
|
||||
@seealso http://openid.net/specs/openid-connect-core-1_0.html#UserInfo
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *userinfoEndpoint;
|
||||
|
||||
/*! @brief REQUIRED. URL of the OP's JSON Web Key Set document. This contains the signing key(s) the
|
||||
RP uses to validate signatures from the OP. The JWK Set MAY also contain the Server's
|
||||
encryption key(s), which are used by RPs to encrypt requests to the Server. When both
|
||||
signing and encryption keys are made available, a use (Key Use) parameter value is REQUIRED
|
||||
for all keys in the referenced JWK Set to indicate each key's intended usage. Although some
|
||||
algorithms allow the same key to be used for both signatures and encryption, doing so is NOT
|
||||
RECOMMENDED, as it is less secure. The JWK x5c parameter MAY be used to provide X.509
|
||||
representations of keys provided. When used, the bare key values MUST still be present and
|
||||
MUST match those in the certificate.
|
||||
@remarks jwks_uri
|
||||
@seealso http://tools.ietf.org/html/rfc7517
|
||||
*/
|
||||
@property(nonatomic, readonly) NSURL *jwksURL;
|
||||
|
||||
/*! @brief RECOMMENDED. URL of the OP's Dynamic Client Registration Endpoint.
|
||||
@remarks registration_endpoint
|
||||
@seealso http://openid.net/specs/openid-connect-registration-1_0.html
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *registrationEndpoint;
|
||||
|
||||
/* @brief OPTIONAL. URL of the OP's RP-Initiated Logout endpoint.
|
||||
@remarks end_session_endpoint
|
||||
@seealso http://openid.net/specs/openid-connect-session-1_0.html#OPMetadata
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *endSessionEndpoint;
|
||||
|
||||
/*! @brief RECOMMENDED. JSON array containing a list of the OAuth 2.0 [RFC6749] scope values that
|
||||
this server supports. The server MUST support the openid scope value. Servers MAY choose not
|
||||
to advertise some supported scope values even when this parameter is used, although those
|
||||
defined in [OpenID.Core] SHOULD be listed, if supported.
|
||||
@remarks scopes_supported
|
||||
@seealso http://tools.ietf.org/html/rfc6749#section-3.3
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *scopesSupported;
|
||||
|
||||
/*! @brief REQUIRED. JSON array containing a list of the OAuth 2.0 @c response_type values that this
|
||||
OP supports. Dynamic OpenID Providers MUST support the @c code, @c id_token, and the token
|
||||
@c id_token Response Type values.
|
||||
@remarks response_types_supported
|
||||
*/
|
||||
@property(nonatomic, readonly) NSArray<NSString *> *responseTypesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the OAuth 2.0 @c response_mode values that this
|
||||
OP supports, as specified in OAuth 2.0 Multiple Response Type Encoding Practices. If
|
||||
omitted, the default for Dynamic OpenID Providers is @c ["query", "fragment"].
|
||||
@remarks response_modes_supported
|
||||
@seealso http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *responseModesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the OAuth 2.0 Grant Type values that this OP
|
||||
supports. Dynamic OpenID Providers MUST support the @c authorization_code and @c implicit
|
||||
Grant Type values and MAY support other Grant Types. If omitted, the default value is
|
||||
@c ["authorization_code", "implicit"].
|
||||
@remarks grant_types_supported
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *grantTypesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the Authentication Context Class References
|
||||
that this OP supports.
|
||||
@remarks acr_values_supported
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *acrValuesSupported;
|
||||
|
||||
/*! @brief REQUIRED. JSON array containing a list of the Subject Identifier types that this OP
|
||||
supports. Valid types include @c pairwise and @c public.
|
||||
@remarks subject_types_supported
|
||||
*/
|
||||
@property(nonatomic, readonly) NSArray<NSString *> *subjectTypesSupported;
|
||||
|
||||
/*! @brief REQUIRED. JSON array containing a list of the JWS signing algorithms (@c alg values)
|
||||
supported by the OP for the ID Token to encode the Claims in a JWT. The algorithm @c RS256
|
||||
MUST be included. The value @c none MAY be supported, but MUST NOT be used unless the
|
||||
Response Type used returns no ID Token from the Authorization Endpoint (such as when using
|
||||
the Authorization Code Flow).
|
||||
@remarks id_token_signing_alg_values_supported
|
||||
@seealso https://tools.ietf.org/html/rfc7519
|
||||
*/
|
||||
@property(nonatomic, readonly) NSArray<NSString *> *IDTokenSigningAlgorithmValuesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the JWE encryption algorithms (@c alg values)
|
||||
supported by the OP for the ID Token to encode the Claims in a JWT.
|
||||
@remarks id_token_encryption_alg_values_supported
|
||||
@seealso https://tools.ietf.org/html/rfc7519
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSArray<NSString *> *IDTokenEncryptionAlgorithmValuesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the JWE encryption algorithms (@c enc values)
|
||||
supported by the OP for the ID Token to encode the Claims in a JWT.
|
||||
@remarks id_token_encryption_enc_values_supported
|
||||
@seealso https://tools.ietf.org/html/rfc7519
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSArray<NSString *> *IDTokenEncryptionEncodingValuesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the JWS signing algorithms (@c alg values)
|
||||
supported by the UserInfo Endpoint to encode the Claims in a JWT. The value none MAY be
|
||||
included.
|
||||
@remarks userinfo_signing_alg_values_supported
|
||||
@seealso https://tools.ietf.org/html/rfc7515
|
||||
@seealso https://tools.ietf.org/html/rfc7518
|
||||
@seealso https://tools.ietf.org/html/rfc7519
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSArray<NSString *> *userinfoSigningAlgorithmValuesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the JWE encryption algorithms (alg values)
|
||||
supported by the UserInfo Endpoint to encode the Claims in a JWT.
|
||||
@remarks userinfo_encryption_alg_values_supported
|
||||
@seealso https://tools.ietf.org/html/rfc7516
|
||||
@seealso https://tools.ietf.org/html/rfc7518
|
||||
@seealso https://tools.ietf.org/html/rfc7519
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSArray<NSString *> *userinfoEncryptionAlgorithmValuesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the JWE encryption algorithms (@c enc values)
|
||||
supported by the UserInfo Endpoint to encode the Claims in a JWT.
|
||||
@remarks userinfo_encryption_enc_values_supported
|
||||
@seealso https://tools.ietf.org/html/rfc7519
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSArray<NSString *> *userinfoEncryptionEncodingValuesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the JWS signing algorithms (@c alg values)
|
||||
supported by the OP for Request Objects, which are described in Section 6.1 of OpenID
|
||||
Connect Core 1.0. These algorithms are used both when the Request Object is passed by value
|
||||
(using the request parameter) and when it is passed by reference (using the @c request_uri
|
||||
parameter). Servers SHOULD support @c none and @c RS256.
|
||||
@remarks request_object_signing_alg_values_supported
|
||||
@seealso http://openid.net/specs/openid-connect-core-1_0.html
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSArray<NSString *> *requestObjectSigningAlgorithmValuesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the JWE encryption algorithms (@c alg values)
|
||||
supported by the OP for Request Objects. These algorithms are used both when the Request
|
||||
Object is passed by value and when it is passed by reference.
|
||||
@remarks request_object_encryption_alg_values_supported
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSArray<NSString *> *requestObjectEncryptionAlgorithmValuesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the JWE encryption algorithms (@c enc values)
|
||||
supported by the OP for Request Objects. These algorithms are used both when the Request
|
||||
Object is passed by value and when it is passed by reference.
|
||||
@remarks request_object_encryption_enc_values_supported
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSArray<NSString *> *requestObjectEncryptionEncodingValuesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of Client Authentication methods supported by this
|
||||
Token Endpoint. The options are @c client_secret_post, @c client_secret_basic,
|
||||
@c client_secret_jwt, and @c private_key_jwt, as described in Section 9 of OpenID Connect
|
||||
Core 1.0. Other authentication methods MAY be defined by extensions. If omitted, the default
|
||||
is @c client_secret_basic -- the HTTP Basic Authentication Scheme specified in Section 2.3.1
|
||||
of OAuth 2.0.
|
||||
@remarks token_endpoint_auth_methods_supported
|
||||
@seealso http://openid.net/specs/openid-connect-core-1_0.html
|
||||
@seealso http://tools.ietf.org/html/rfc6749#section-2.3.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *tokenEndpointAuthMethodsSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the JWS signing algorithms (@c alg values)
|
||||
supported by the Token Endpoint for the signature on the JWT used to authenticate the Client
|
||||
at the Token Endpoint for the @c private_key_jwt and @c client_secret_jwt authentication
|
||||
methods. Servers SHOULD support @c RS256. The value @c none MUST NOT be used.
|
||||
@remarks token_endpoint_auth_signing_alg_values_supported
|
||||
@seealso https://tools.ietf.org/html/rfc7519
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSArray<NSString *> *tokenEndpointAuthSigningAlgorithmValuesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the @c display parameter values that the OpenID
|
||||
Provider supports. These values are described in Section 3.1.2.1 of OpenID Connect Core 1.0.
|
||||
@remarks display_values_supported
|
||||
@seealso http://openid.net/specs/openid-connect-core-1_0.html
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *displayValuesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. JSON array containing a list of the Claim Types that the OpenID Provider
|
||||
supports. These Claim Types are described in Section 5.6 of OpenID Connect Core 1.0. Values
|
||||
defined by this specification are @c normal, @c aggregated, and @c distributed. If omitted,
|
||||
the implementation supports only @c normal Claims.
|
||||
@remarks claim_types_supported
|
||||
@seealso http://openid.net/specs/openid-connect-core-1_0.html
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *claimTypesSupported;
|
||||
|
||||
/*! @brief RECOMMENDED. JSON array containing a list of the Claim Names of the Claims that the
|
||||
OpenID Provider MAY be able to supply values for. Note that for privacy or other reasons,
|
||||
this might not be an exhaustive list.
|
||||
@remarks claims_supported
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *claimsSupported;
|
||||
|
||||
/*! @brief OPTIONAL. URL of a page containing human-readable information that developers might want
|
||||
or need to know when using the OpenID Provider. In particular, if the OpenID Provider does
|
||||
not support Dynamic Client Registration, then information on how to register Clients needs
|
||||
to be provided in this documentation.
|
||||
@remarks service_documentation
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *serviceDocumentation;
|
||||
|
||||
/*! @brief OPTIONAL. Languages and scripts supported for values in Claims being returned,
|
||||
represented as a JSON array of BCP47 language tag values. Not all languages and scripts are
|
||||
necessarily supported for all Claim values.
|
||||
@remarks claims_locales_supported
|
||||
@seealso http://tools.ietf.org/html/rfc5646
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *claimsLocalesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. Languages and scripts supported for the user interface, represented as a JSON
|
||||
array of BCP47 language tag values.
|
||||
@remarks ui_locales_supported
|
||||
@seealso http://tools.ietf.org/html/rfc5646
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSArray<NSString *> *UILocalesSupported;
|
||||
|
||||
/*! @brief OPTIONAL. Boolean value specifying whether the OP supports use of the claims parameter,
|
||||
with @c true indicating support. If omitted, the default value is @c false.
|
||||
@remarks claims_parameter_supported
|
||||
*/
|
||||
@property(nonatomic, readonly) BOOL claimsParameterSupported;
|
||||
|
||||
/*! @brief OPTIONAL. Boolean value specifying whether the OP supports use of the request parameter,
|
||||
with @c true indicating support. If omitted, the default value is @c false.
|
||||
@remarks request_parameter_supported
|
||||
*/
|
||||
@property(nonatomic, readonly) BOOL requestParameterSupported;
|
||||
|
||||
/*! @brief OPTIONAL. Boolean value specifying whether the OP supports use of the @c request_uri
|
||||
parameter, with true indicating support. If omitted, the default value is @c true.
|
||||
@remarks request_uri_parameter_supported
|
||||
*/
|
||||
@property(nonatomic, readonly) BOOL requestURIParameterSupported;
|
||||
|
||||
/*! @brief OPTIONAL. Boolean value specifying whether the OP requires any @c request_uri values used
|
||||
to be pre-registered using the @c request_uris registration parameter. Pre-registration is
|
||||
REQUIRED when the value is @c true. If omitted, the default value is @c false.
|
||||
@remarks require_request_uri_registration
|
||||
*/
|
||||
@property(nonatomic, readonly) BOOL requireRequestURIRegistration;
|
||||
|
||||
/*! @brief OPTIONAL. URL that the OpenID Provider provides to the person registering the Client to
|
||||
read about the OP's requirements on how the Relying Party can use the data provided by the
|
||||
OP. The registration process SHOULD display this URL to the person registering the Client if
|
||||
it is given.
|
||||
@remarks op_policy_uri
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *OPPolicyURI;
|
||||
|
||||
/*! @brief OPTIONAL. URL that the OpenID Provider provides to the person registering the Client to
|
||||
read about OpenID Provider's terms of service. The registration process SHOULD display this
|
||||
URL to the person registering the Client if it is given.
|
||||
@remarks op_tos_uri
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *OPTosURI;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use @c initWithDictionary:error:, @c initWithJSON:error, or the
|
||||
@c serviceDiscoveryWithURL:callback: factory method.
|
||||
*/
|
||||
- (nonnull instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Decodes a OpenID Connect Discovery 1.0 JSON document.
|
||||
@param serviceDiscoveryJSON An OpenID Connect Service Discovery document.
|
||||
@param error If a required field is missing from the dictionary, an error with domain
|
||||
@c ::OIDGeneralErrorDomain and code @c ::OIDErrorCodeInvalidDiscoveryDocument will be
|
||||
returned.
|
||||
*/
|
||||
- (nullable instancetype)initWithJSON:(NSString *)serviceDiscoveryJSON
|
||||
error:(NSError **_Nullable)error;
|
||||
|
||||
/*! @brief Decodes a OpenID Connect Discovery 1.0 JSON document.
|
||||
@param serviceDiscoveryJSONData An OpenID Connect Service Discovery document.
|
||||
@param error If a required field is missing from the dictionary, an error with domain
|
||||
@c ::OIDGeneralErrorDomain and code @c ::OIDErrorCodeInvalidDiscoveryDocument will be
|
||||
returned.
|
||||
*/
|
||||
- (nullable instancetype)initWithJSONData:(NSData *)serviceDiscoveryJSONData
|
||||
error:(NSError **_Nullable)error;
|
||||
|
||||
/*! @brief Designated initializer. The dictionary keys should match the keys defined in the OpenID
|
||||
Connect Discovery 1.0 standard for OpenID Provider Metadata.
|
||||
@param serviceDiscoveryDictionary A dictionary representing an OpenID Connect Service Discovery
|
||||
document.
|
||||
@param error If a required field is missing from the dictionary, an error with domain
|
||||
@c ::OIDGeneralErrorDomain and code @c ::OIDErrorCodeInvalidDiscoveryDocument will be
|
||||
returned.
|
||||
*/
|
||||
- (nullable instancetype)initWithDictionary:(NSDictionary *)serviceDiscoveryDictionary
|
||||
error:(NSError **_Nullable)error NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-362
@@ -1,362 +0,0 @@
|
||||
/*! @file OIDServiceDiscovery.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDServiceDiscovery.h"
|
||||
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDErrorUtilities.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! Field keys associated with an OpenID Connect Discovery Document. */
|
||||
static NSString *const kIssuerKey = @"issuer";
|
||||
static NSString *const kAuthorizationEndpointKey = @"authorization_endpoint";
|
||||
static NSString *const kTokenEndpointKey = @"token_endpoint";
|
||||
static NSString *const kUserinfoEndpointKey = @"userinfo_endpoint";
|
||||
static NSString *const kJWKSURLKey = @"jwks_uri";
|
||||
static NSString *const kRegistrationEndpointKey = @"registration_endpoint";
|
||||
static NSString *const kEndSessionEndpointKey = @"end_session_endpoint";
|
||||
static NSString *const kScopesSupportedKey = @"scopes_supported";
|
||||
static NSString *const kResponseTypesSupportedKey = @"response_types_supported";
|
||||
static NSString *const kResponseModesSupportedKey = @"response_modes_supported";
|
||||
static NSString *const kGrantTypesSupportedKey = @"grant_types_supported";
|
||||
static NSString *const kACRValuesSupportedKey = @"acr_values_supported";
|
||||
static NSString *const kSubjectTypesSupportedKey = @"subject_types_supported";
|
||||
static NSString *const kIDTokenSigningAlgorithmValuesSupportedKey =
|
||||
@"id_token_signing_alg_values_supported";
|
||||
static NSString *const kIDTokenEncryptionAlgorithmValuesSupportedKey =
|
||||
@"id_token_encryption_alg_values_supported";
|
||||
static NSString *const kIDTokenEncryptionEncodingValuesSupportedKey =
|
||||
@"id_token_encryption_enc_values_supported";
|
||||
static NSString *const kUserinfoSigningAlgorithmValuesSupportedKey =
|
||||
@"userinfo_signing_alg_values_supported";
|
||||
static NSString *const kUserinfoEncryptionAlgorithmValuesSupportedKey =
|
||||
@"userinfo_encryption_alg_values_supported";
|
||||
static NSString *const kUserinfoEncryptionEncodingValuesSupportedKey =
|
||||
@"userinfo_encryption_enc_values_supported";
|
||||
static NSString *const kRequestObjectSigningAlgorithmValuesSupportedKey =
|
||||
@"request_object_signing_alg_values_supported";
|
||||
static NSString *const kRequestObjectEncryptionAlgorithmValuesSupportedKey =
|
||||
@"request_object_encryption_alg_values_supported";
|
||||
static NSString *const kRequestObjectEncryptionEncodingValuesSupported =
|
||||
@"request_object_encryption_enc_values_supported";
|
||||
static NSString *const kTokenEndpointAuthMethodsSupportedKey =
|
||||
@"token_endpoint_auth_methods_supported";
|
||||
static NSString *const kTokenEndpointAuthSigningAlgorithmValuesSupportedKey =
|
||||
@"token_endpoint_auth_signing_alg_values_supported";
|
||||
static NSString *const kDisplayValuesSupportedKey = @"display_values_supported";
|
||||
static NSString *const kClaimTypesSupportedKey = @"claim_types_supported";
|
||||
static NSString *const kClaimsSupportedKey = @"claims_supported";
|
||||
static NSString *const kServiceDocumentationKey = @"service_documentation";
|
||||
static NSString *const kClaimsLocalesSupportedKey = @"claims_locales_supported";
|
||||
static NSString *const kUILocalesSupportedKey = @"ui_locales_supported";
|
||||
static NSString *const kClaimsParameterSupportedKey = @"claims_parameter_supported";
|
||||
static NSString *const kRequestParameterSupportedKey = @"request_parameter_supported";
|
||||
static NSString *const kRequestURIParameterSupportedKey = @"request_uri_parameter_supported";
|
||||
static NSString *const kRequireRequestURIRegistrationKey = @"require_request_uri_registration";
|
||||
static NSString *const kOPPolicyURIKey = @"op_policy_uri";
|
||||
static NSString *const kOPTosURIKey = @"op_tos_uri";
|
||||
|
||||
@implementation OIDServiceDiscovery {
|
||||
NSDictionary *_discoveryDictionary;
|
||||
}
|
||||
|
||||
- (nonnull instancetype)init OID_UNAVAILABLE_USE_INITIALIZER(@selector(initWithDictionary:error:))
|
||||
|
||||
- (nullable instancetype)initWithJSON:(NSString *)serviceDiscoveryJSON error:(NSError **)error {
|
||||
NSData *jsonData = [serviceDiscoveryJSON dataUsingEncoding:NSUTF8StringEncoding];
|
||||
return [self initWithJSONData:jsonData error:error];
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithJSONData:(NSData *)serviceDiscoveryJSONData
|
||||
error:(NSError **_Nullable)error {
|
||||
NSError *jsonError;
|
||||
NSDictionary *json =
|
||||
[NSJSONSerialization JSONObjectWithData:serviceDiscoveryJSONData options:0 error:&jsonError];
|
||||
if (!json || jsonError) {
|
||||
*error = [OIDErrorUtilities errorWithCode:OIDErrorCodeJSONDeserializationError
|
||||
underlyingError:jsonError
|
||||
description:jsonError.localizedDescription];
|
||||
return nil;
|
||||
}
|
||||
if (![json isKindOfClass:[NSDictionary class]]) {
|
||||
*error = [OIDErrorUtilities errorWithCode:OIDErrorCodeInvalidDiscoveryDocument
|
||||
underlyingError:nil
|
||||
description:@"Discovery document isn't a dictionary"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [self initWithDictionary:json error:error];
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithDictionary:(NSDictionary *)serviceDiscoveryDictionary
|
||||
error:(NSError **_Nullable)error {
|
||||
if (![[self class] dictionaryHasRequiredFields:serviceDiscoveryDictionary error:error]) {
|
||||
return nil;
|
||||
}
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_discoveryDictionary = [serviceDiscoveryDictionary copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/*! @brief Checks to see if the specified dictionary contains the required fields.
|
||||
@discussion This test is not meant to provide semantic analysis of the document (eg. fields
|
||||
where the value @c none is not an allowed option would not cause this method to fail if
|
||||
their value was @c none.) We are just testing to make sure we can meet the nullability
|
||||
contract we promised in the header.
|
||||
*/
|
||||
+ (BOOL)dictionaryHasRequiredFields:(NSDictionary<NSString *, id> *)dictionary
|
||||
error:(NSError **_Nullable)error {
|
||||
static NSString *const kMissingFieldErrorText = @"Missing field: %@";
|
||||
static NSString *const kInvalidURLFieldErrorText = @"Invalid URL: %@";
|
||||
|
||||
NSArray *requiredFields = @[
|
||||
kIssuerKey,
|
||||
kAuthorizationEndpointKey,
|
||||
kTokenEndpointKey,
|
||||
kJWKSURLKey,
|
||||
kResponseTypesSupportedKey,
|
||||
kSubjectTypesSupportedKey,
|
||||
kIDTokenSigningAlgorithmValuesSupportedKey
|
||||
];
|
||||
|
||||
for (NSString *field in requiredFields) {
|
||||
if (!dictionary[field]) {
|
||||
if (error) {
|
||||
NSString *errorText = [NSString stringWithFormat:kMissingFieldErrorText, field];
|
||||
*error = [OIDErrorUtilities errorWithCode:OIDErrorCodeInvalidDiscoveryDocument
|
||||
underlyingError:nil
|
||||
description:errorText];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
// Check required URL fields are valid URLs.
|
||||
NSArray *requiredURLFields = @[
|
||||
kIssuerKey,
|
||||
kTokenEndpointKey,
|
||||
kJWKSURLKey
|
||||
];
|
||||
|
||||
for (NSString *field in requiredURLFields) {
|
||||
if (![NSURL URLWithString:dictionary[field]]) {
|
||||
if (error) {
|
||||
NSString *errorText = [NSString stringWithFormat:kInvalidURLFieldErrorText, field];
|
||||
*error = [OIDErrorUtilities errorWithCode:OIDErrorCodeInvalidDiscoveryDocument
|
||||
underlyingError:nil
|
||||
description:errorText];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
// The documentation for NSCopying specifically advises us to return a reference to the original
|
||||
// instance in the case where instances are immutable (as ours is):
|
||||
// "Implement NSCopying by retaining the original instead of creating a new copy when the class
|
||||
// and its contents are immutable."
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
NSError *error;
|
||||
NSDictionary *dictionary = [[NSDictionary alloc] initWithCoder:aDecoder];
|
||||
self = [self initWithDictionary:dictionary error:&error];
|
||||
if (error) {
|
||||
return nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[_discoveryDictionary encodeWithCoder:aCoder];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (NSDictionary<NSString *, NSString *> *)discoveryDictionary {
|
||||
return _discoveryDictionary;
|
||||
}
|
||||
|
||||
- (NSURL *)issuer {
|
||||
return [NSURL URLWithString:_discoveryDictionary[kIssuerKey]];
|
||||
}
|
||||
|
||||
- (NSURL *)authorizationEndpoint {
|
||||
return [NSURL URLWithString:_discoveryDictionary[kAuthorizationEndpointKey]];
|
||||
}
|
||||
|
||||
- (NSURL *)tokenEndpoint {
|
||||
return [NSURL URLWithString:_discoveryDictionary[kTokenEndpointKey]];
|
||||
}
|
||||
|
||||
- (nullable NSURL *)userinfoEndpoint {
|
||||
return [NSURL URLWithString:_discoveryDictionary[kUserinfoEndpointKey]];
|
||||
}
|
||||
|
||||
- (NSURL *)jwksURL {
|
||||
return [NSURL URLWithString:_discoveryDictionary[kJWKSURLKey]];
|
||||
}
|
||||
|
||||
- (nullable NSURL *)registrationEndpoint {
|
||||
return [NSURL URLWithString:_discoveryDictionary[kRegistrationEndpointKey]];
|
||||
}
|
||||
|
||||
- (nullable NSURL *)endSessionEndpoint {
|
||||
return [NSURL URLWithString:_discoveryDictionary[kEndSessionEndpointKey]];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)scopesSupported {
|
||||
return _discoveryDictionary[kScopesSupportedKey];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)responseTypesSupported {
|
||||
return _discoveryDictionary[kResponseTypesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)responseModesSupported {
|
||||
return _discoveryDictionary[kResponseModesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)grantTypesSupported {
|
||||
return _discoveryDictionary[kGrantTypesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)acrValuesSupported {
|
||||
return _discoveryDictionary[kACRValuesSupportedKey];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)subjectTypesSupported {
|
||||
return _discoveryDictionary[kSubjectTypesSupportedKey];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *) IDTokenSigningAlgorithmValuesSupported {
|
||||
return _discoveryDictionary[kIDTokenSigningAlgorithmValuesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)IDTokenEncryptionAlgorithmValuesSupported {
|
||||
return _discoveryDictionary[kIDTokenEncryptionAlgorithmValuesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)IDTokenEncryptionEncodingValuesSupported {
|
||||
return _discoveryDictionary[kIDTokenEncryptionEncodingValuesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)userinfoSigningAlgorithmValuesSupported {
|
||||
return _discoveryDictionary[kUserinfoSigningAlgorithmValuesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)userinfoEncryptionAlgorithmValuesSupported {
|
||||
return _discoveryDictionary[kUserinfoEncryptionAlgorithmValuesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)userinfoEncryptionEncodingValuesSupported {
|
||||
return _discoveryDictionary[kUserinfoEncryptionEncodingValuesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)requestObjectSigningAlgorithmValuesSupported {
|
||||
return _discoveryDictionary[kRequestObjectSigningAlgorithmValuesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *) requestObjectEncryptionAlgorithmValuesSupported {
|
||||
return _discoveryDictionary[kRequestObjectEncryptionAlgorithmValuesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *) requestObjectEncryptionEncodingValuesSupported {
|
||||
return _discoveryDictionary[kRequestObjectEncryptionEncodingValuesSupported];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)tokenEndpointAuthMethodsSupported {
|
||||
return _discoveryDictionary[kTokenEndpointAuthMethodsSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)tokenEndpointAuthSigningAlgorithmValuesSupported {
|
||||
return _discoveryDictionary[kTokenEndpointAuthSigningAlgorithmValuesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)displayValuesSupported {
|
||||
return _discoveryDictionary[kDisplayValuesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)claimTypesSupported {
|
||||
return _discoveryDictionary[kClaimTypesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)claimsSupported {
|
||||
return _discoveryDictionary[kClaimsSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSURL *)serviceDocumentation {
|
||||
return [NSURL URLWithString:_discoveryDictionary[kServiceDocumentationKey]];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)claimsLocalesSupported {
|
||||
return _discoveryDictionary[kClaimsLocalesSupportedKey];
|
||||
}
|
||||
|
||||
- (nullable NSArray<NSString *> *)UILocalesSupported {
|
||||
return _discoveryDictionary[kUILocalesSupportedKey];
|
||||
}
|
||||
|
||||
- (BOOL)claimsParameterSupported {
|
||||
return [_discoveryDictionary[kClaimsParameterSupportedKey] boolValue];
|
||||
}
|
||||
|
||||
- (BOOL)requestParameterSupported {
|
||||
return [_discoveryDictionary[kRequestParameterSupportedKey] boolValue];
|
||||
}
|
||||
|
||||
- (BOOL)requestURIParameterSupported {
|
||||
// Default is true/YES.
|
||||
if (!_discoveryDictionary[kRequestURIParameterSupportedKey]) {
|
||||
return YES;
|
||||
}
|
||||
return [_discoveryDictionary[kRequestURIParameterSupportedKey] boolValue];
|
||||
}
|
||||
|
||||
- (BOOL)requireRequestURIRegistration {
|
||||
return [_discoveryDictionary[kRequireRequestURIRegistrationKey] boolValue];
|
||||
}
|
||||
|
||||
- (nullable NSURL *)OPPolicyURI {
|
||||
return [NSURL URLWithString:_discoveryDictionary[kOPPolicyURIKey]];
|
||||
}
|
||||
|
||||
- (nullable NSURL *)OPTosURI {
|
||||
return [NSURL URLWithString:_discoveryDictionary[kOPTosURIKey]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-162
@@ -1,162 +0,0 @@
|
||||
/*! @file OIDTokenRequest.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// This file only declares string constants useful for constructing a @c OIDTokenRequest, so it is
|
||||
// imported here for convenience.
|
||||
#import "OIDGrantTypes.h"
|
||||
|
||||
@class OIDAuthorizationResponse;
|
||||
@class OIDServiceConfiguration;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Represents a token request.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.2
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
*/
|
||||
@interface OIDTokenRequest : NSObject <NSCopying, NSSecureCoding>
|
||||
|
||||
/*! @brief The service's configuration.
|
||||
@remarks This configuration specifies how to connect to a particular OAuth provider.
|
||||
Configurations may be created manually, or via an OpenID Connect Discovery Document.
|
||||
*/
|
||||
@property(nonatomic, readonly) OIDServiceConfiguration *configuration;
|
||||
|
||||
/*! @brief The type of token being sent to the token endpoint, i.e. "authorization_code" for the
|
||||
authorization code exchange, or "refresh_token" for an access token refresh request.
|
||||
@remarks grant_type
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
@see https://www.google.com/url?sa=D&q=https%3A%2F%2Ftools.ietf.org%2Fhtml%2Frfc6749%23section-6
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString *grantType;
|
||||
|
||||
/*! @brief The authorization code received from the authorization server.
|
||||
@remarks code
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *authorizationCode;
|
||||
|
||||
/*! @brief The client's redirect URI.
|
||||
@remarks redirect_uri
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSURL *redirectURL;
|
||||
|
||||
/*! @brief The client identifier.
|
||||
@remarks client_id
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
*/
|
||||
@property(nonatomic, readonly) NSString *clientID;
|
||||
|
||||
/*! @brief The client secret.
|
||||
@remarks client_secret
|
||||
@see https://tools.ietf.org/html/rfc6749#section-2.3.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *clientSecret;
|
||||
|
||||
/*! @brief The value of the scope parameter is expressed as a list of space-delimited,
|
||||
case-sensitive strings.
|
||||
@remarks scope
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.3
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *scope;
|
||||
|
||||
/*! @brief The refresh token, which can be used to obtain new access tokens using the same
|
||||
authorization grant.
|
||||
@remarks refresh_token
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *refreshToken;
|
||||
|
||||
/*! @brief The PKCE code verifier used to redeem the authorization code.
|
||||
@remarks code_verifier
|
||||
@see https://tools.ietf.org/html/rfc7636#section-4.3
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *codeVerifier;
|
||||
|
||||
/*! @brief The client's additional token request parameters.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSDictionary<NSString *, NSString *> *additionalParameters;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use
|
||||
initWithConfiguration:grantType:code:redirectURL:clientID:additionalParameters:.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @param configuration The service's configuration.
|
||||
@param grantType the type of token being sent to the token endpoint, i.e. "authorization_code"
|
||||
for the authorization code exchange, or "refresh_token" for an access token refresh request.
|
||||
@see OIDGrantTypes.h
|
||||
@param code The authorization code received from the authorization server.
|
||||
@param redirectURL The client's redirect URI.
|
||||
@param clientID The client identifier.
|
||||
@param clientSecret The client secret.
|
||||
@param scopes An array of scopes to combine into a single scope string per the OAuth2 spec.
|
||||
@param refreshToken The refresh token.
|
||||
@param codeVerifier The PKCE code verifier.
|
||||
@param additionalParameters The client's additional token request parameters.
|
||||
*/
|
||||
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
grantType:(NSString *)grantType
|
||||
authorizationCode:(nullable NSString *)code
|
||||
redirectURL:(nullable NSURL *)redirectURL
|
||||
clientID:(NSString *)clientID
|
||||
clientSecret:(nullable NSString *)clientSecret
|
||||
scopes:(nullable NSArray<NSString *> *)scopes
|
||||
refreshToken:(nullable NSString *)refreshToken
|
||||
codeVerifier:(nullable NSString *)codeVerifier
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters;
|
||||
|
||||
/*! @brief Designated initializer.
|
||||
@param configuration The service's configuration.
|
||||
@param grantType the type of token being sent to the token endpoint, i.e. "authorization_code"
|
||||
for the authorization code exchange, or "refresh_token" for an access token refresh request.
|
||||
@see OIDGrantTypes.h
|
||||
@param code The authorization code received from the authorization server.
|
||||
@param redirectURL The client's redirect URI.
|
||||
@param clientID The client identifier.
|
||||
@param clientSecret The client secret.
|
||||
@param scope The value of the scope parameter is expressed as a list of space-delimited,
|
||||
case-sensitive strings.
|
||||
@param refreshToken The refresh token.
|
||||
@param codeVerifier The PKCE code verifier.
|
||||
@param additionalParameters The client's additional token request parameters.
|
||||
*/
|
||||
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
grantType:(NSString *)grantType
|
||||
authorizationCode:(nullable NSString *)code
|
||||
redirectURL:(nullable NSURL *)redirectURL
|
||||
clientID:(NSString *)clientID
|
||||
clientSecret:(nullable NSString *)clientSecret
|
||||
scope:(nullable NSString *)scope
|
||||
refreshToken:(nullable NSString *)refreshToken
|
||||
codeVerifier:(nullable NSString *)codeVerifier
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/*! @brief Constructs an @c NSURLRequest representing the token request.
|
||||
@return An @c NSURLRequest representing the token request.
|
||||
*/
|
||||
- (NSURLRequest *)URLRequest;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-307
@@ -1,307 +0,0 @@
|
||||
/*! @file OIDTokenRequest.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDTokenRequest.h"
|
||||
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDError.h"
|
||||
#import "OIDScopeUtilities.h"
|
||||
#import "OIDServiceConfiguration.h"
|
||||
#import "OIDURLQueryComponent.h"
|
||||
#import "OIDTokenUtilities.h"
|
||||
|
||||
/*! @brief The key for the @c configuration property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kConfigurationKey = @"configuration";
|
||||
|
||||
/*! @brief Key used to encode the @c grantType property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kGrantTypeKey = @"grant_type";
|
||||
|
||||
/*! @brief The key for the @c authorizationCode property for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kAuthorizationCodeKey = @"code";
|
||||
|
||||
/*! @brief Key used to encode the @c clientID property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kClientIDKey = @"client_id";
|
||||
|
||||
/*! @brief Key used to encode the @c clientSecret property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kClientSecretKey = @"client_secret";
|
||||
|
||||
/*! @brief Key used to encode the @c redirectURL property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kRedirectURLKey = @"redirect_uri";
|
||||
|
||||
/*! @brief Key used to encode the @c scopes property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kScopeKey = @"scope";
|
||||
|
||||
/*! @brief Key used to encode the @c refreshToken property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kRefreshTokenKey = @"refresh_token";
|
||||
|
||||
/*! @brief Key used to encode the @c codeVerifier property for @c NSSecureCoding and to build the
|
||||
request URL.
|
||||
*/
|
||||
static NSString *const kCodeVerifierKey = @"code_verifier";
|
||||
|
||||
/*! @brief Key used to encode the @c additionalParameters property for
|
||||
@c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kAdditionalParametersKey = @"additionalParameters";
|
||||
|
||||
@implementation OIDTokenRequest
|
||||
|
||||
- (instancetype)init
|
||||
OID_UNAVAILABLE_USE_INITIALIZER(
|
||||
@selector(initWithConfiguration:
|
||||
grantType:
|
||||
authorizationCode:
|
||||
redirectURL:
|
||||
clientID:
|
||||
clientSecret:
|
||||
scope:
|
||||
refreshToken:
|
||||
codeVerifier:
|
||||
additionalParameters:)
|
||||
)
|
||||
|
||||
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
grantType:(NSString *)grantType
|
||||
authorizationCode:(nullable NSString *)code
|
||||
redirectURL:(nullable NSURL *)redirectURL
|
||||
clientID:(NSString *)clientID
|
||||
clientSecret:(nullable NSString *)clientSecret
|
||||
scopes:(nullable NSArray<NSString *> *)scopes
|
||||
refreshToken:(nullable NSString *)refreshToken
|
||||
codeVerifier:(nullable NSString *)codeVerifier
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters {
|
||||
return [self initWithConfiguration:configuration
|
||||
grantType:grantType
|
||||
authorizationCode:code
|
||||
redirectURL:redirectURL
|
||||
clientID:clientID
|
||||
clientSecret:clientSecret
|
||||
scope:[OIDScopeUtilities scopesWithArray:scopes]
|
||||
refreshToken:refreshToken
|
||||
codeVerifier:(NSString *)codeVerifier
|
||||
additionalParameters:additionalParameters];
|
||||
}
|
||||
|
||||
- (instancetype)initWithConfiguration:(OIDServiceConfiguration *)configuration
|
||||
grantType:(NSString *)grantType
|
||||
authorizationCode:(nullable NSString *)code
|
||||
redirectURL:(nullable NSURL *)redirectURL
|
||||
clientID:(NSString *)clientID
|
||||
clientSecret:(nullable NSString *)clientSecret
|
||||
scope:(nullable NSString *)scope
|
||||
refreshToken:(nullable NSString *)refreshToken
|
||||
codeVerifier:(nullable NSString *)codeVerifier
|
||||
additionalParameters:(nullable NSDictionary<NSString *, NSString *> *)additionalParameters {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_configuration = [configuration copy];
|
||||
_grantType = [grantType copy];
|
||||
_authorizationCode = [code copy];
|
||||
_redirectURL = [redirectURL copy];
|
||||
_clientID = [clientID copy];
|
||||
_clientSecret = [clientSecret copy];
|
||||
_scope = [scope copy];
|
||||
_refreshToken = [refreshToken copy];
|
||||
_codeVerifier = [codeVerifier copy];
|
||||
_additionalParameters =
|
||||
[[NSDictionary alloc] initWithDictionary:additionalParameters copyItems:YES];
|
||||
|
||||
// Additional validation for the authorization_code grant type
|
||||
if ([_grantType isEqual:OIDGrantTypeAuthorizationCode]) {
|
||||
// redirect URI must not be nil
|
||||
if (!_redirectURL) {
|
||||
[NSException raise:OIDOAuthExceptionInvalidTokenRequestNullRedirectURL
|
||||
format:@"%@", OIDOAuthExceptionInvalidTokenRequestNullRedirectURL, nil];
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
// The documentation for NSCopying specifically advises us to return a reference to the original
|
||||
// instance in the case where instances are immutable (as ours is):
|
||||
// "Implement NSCopying by retaining the original instead of creating a new copy when the class
|
||||
// and its contents are immutable."
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
OIDServiceConfiguration *configuration =
|
||||
[aDecoder decodeObjectOfClass:[OIDServiceConfiguration class]
|
||||
forKey:kConfigurationKey];
|
||||
NSString *grantType = [aDecoder decodeObjectOfClass:[NSString class] forKey:kGrantTypeKey];
|
||||
NSString *code = [aDecoder decodeObjectOfClass:[NSString class] forKey:kAuthorizationCodeKey];
|
||||
NSString *clientID = [aDecoder decodeObjectOfClass:[NSString class] forKey:kClientIDKey];
|
||||
NSString *clientSecret = [aDecoder decodeObjectOfClass:[NSString class] forKey:kClientSecretKey];
|
||||
NSString *scope = [aDecoder decodeObjectOfClass:[NSString class] forKey:kScopeKey];
|
||||
NSString *refreshToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:kRefreshTokenKey];
|
||||
NSString *codeVerifier = [aDecoder decodeObjectOfClass:[NSString class] forKey:kCodeVerifierKey];
|
||||
NSURL *redirectURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:kRedirectURLKey];
|
||||
NSSet *additionalParameterCodingClasses = [NSSet setWithArray:@[
|
||||
[NSDictionary class],
|
||||
[NSString class]
|
||||
]];
|
||||
NSDictionary *additionalParameters =
|
||||
[aDecoder decodeObjectOfClasses:additionalParameterCodingClasses
|
||||
forKey:kAdditionalParametersKey];
|
||||
self = [self initWithConfiguration:configuration
|
||||
grantType:grantType
|
||||
authorizationCode:code
|
||||
redirectURL:redirectURL
|
||||
clientID:clientID
|
||||
clientSecret:clientSecret
|
||||
scope:scope
|
||||
refreshToken:refreshToken
|
||||
codeVerifier:codeVerifier
|
||||
additionalParameters:additionalParameters];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[aCoder encodeObject:_configuration forKey:kConfigurationKey];
|
||||
[aCoder encodeObject:_grantType forKey:kGrantTypeKey];
|
||||
[aCoder encodeObject:_authorizationCode forKey:kAuthorizationCodeKey];
|
||||
[aCoder encodeObject:_clientID forKey:kClientIDKey];
|
||||
[aCoder encodeObject:_clientSecret forKey:kClientSecretKey];
|
||||
[aCoder encodeObject:_redirectURL forKey:kRedirectURLKey];
|
||||
[aCoder encodeObject:_scope forKey:kScopeKey];
|
||||
[aCoder encodeObject:_refreshToken forKey:kRefreshTokenKey];
|
||||
[aCoder encodeObject:_codeVerifier forKey:kCodeVerifierKey];
|
||||
[aCoder encodeObject:_additionalParameters forKey:kAdditionalParametersKey];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject overrides
|
||||
|
||||
- (NSString *)description {
|
||||
NSURLRequest *request = self.URLRequest;
|
||||
NSString *requestBody =
|
||||
[[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding];
|
||||
return [NSString stringWithFormat:@"<%@: %p, request: <URL: %@, HTTPBody: %@>>",
|
||||
NSStringFromClass([self class]),
|
||||
(void *)self,
|
||||
request.URL,
|
||||
requestBody];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/*! @brief Constructs the request URI.
|
||||
@return A URL representing the token request.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
*/
|
||||
- (NSURL *)tokenRequestURL {
|
||||
return _configuration.tokenEndpoint;
|
||||
}
|
||||
|
||||
/*! @brief Constructs the request body data by combining the request parameters using the
|
||||
"application/x-www-form-urlencoded" format.
|
||||
@return The data to pass to the token request URL.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
*/
|
||||
- (OIDURLQueryComponent *)tokenRequestBody {
|
||||
OIDURLQueryComponent *query = [[OIDURLQueryComponent alloc] init];
|
||||
|
||||
// Add parameters, as applicable.
|
||||
if (_grantType) {
|
||||
[query addParameter:kGrantTypeKey value:_grantType];
|
||||
}
|
||||
if (_scope) {
|
||||
[query addParameter:kScopeKey value:_scope];
|
||||
}
|
||||
if (_redirectURL) {
|
||||
[query addParameter:kRedirectURLKey value:_redirectURL.absoluteString];
|
||||
}
|
||||
if (_refreshToken) {
|
||||
[query addParameter:kRefreshTokenKey value:_refreshToken];
|
||||
}
|
||||
if (_authorizationCode) {
|
||||
[query addParameter:kAuthorizationCodeKey value:_authorizationCode];
|
||||
}
|
||||
if (_codeVerifier) {
|
||||
[query addParameter:kCodeVerifierKey value:_codeVerifier];
|
||||
}
|
||||
|
||||
// Add any additional parameters the client has specified.
|
||||
[query addParameters:_additionalParameters];
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
- (NSURLRequest *)URLRequest {
|
||||
static NSString *const kHTTPPost = @"POST";
|
||||
static NSString *const kHTTPContentTypeHeaderKey = @"Content-Type";
|
||||
static NSString *const kHTTPContentTypeHeaderValue =
|
||||
@"application/x-www-form-urlencoded; charset=UTF-8";
|
||||
|
||||
NSURL *tokenRequestURL = [self tokenRequestURL];
|
||||
NSMutableURLRequest *URLRequest = [[NSURLRequest requestWithURL:tokenRequestURL] mutableCopy];
|
||||
URLRequest.HTTPMethod = kHTTPPost;
|
||||
[URLRequest setValue:kHTTPContentTypeHeaderValue forHTTPHeaderField:kHTTPContentTypeHeaderKey];
|
||||
|
||||
OIDURLQueryComponent *bodyParameters = [self tokenRequestBody];
|
||||
NSMutableDictionary *httpHeaders = [[NSMutableDictionary alloc] init];
|
||||
|
||||
if (_clientSecret) {
|
||||
// The client id and secret are encoded using the "application/x-www-form-urlencoded"
|
||||
// encoding algorithm per RFC 6749 Section 2.3.1.
|
||||
// https://tools.ietf.org/html/rfc6749#section-2.3.1
|
||||
NSString *encodedClientID = [OIDTokenUtilities formUrlEncode:_clientID];
|
||||
NSString *encodedClientSecret = [OIDTokenUtilities formUrlEncode:_clientSecret];
|
||||
|
||||
NSString *credentials =
|
||||
[NSString stringWithFormat:@"%@:%@", encodedClientID, encodedClientSecret];
|
||||
NSData *plainData = [credentials dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSString *basicAuth = [plainData base64EncodedStringWithOptions:kNilOptions];
|
||||
|
||||
NSString *authValue = [NSString stringWithFormat:@"Basic %@", basicAuth];
|
||||
[httpHeaders setObject:authValue forKey:@"Authorization"];
|
||||
} else {
|
||||
[bodyParameters addParameter:kClientIDKey value:_clientID];
|
||||
}
|
||||
|
||||
// Constructs request with the body string and headers.
|
||||
NSString *bodyString = [bodyParameters URLEncodedParameters];
|
||||
NSData *body = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
URLRequest.HTTPBody = body;
|
||||
|
||||
for (id header in httpHeaders) {
|
||||
[URLRequest setValue:httpHeaders[header] forHTTPHeaderField:header];
|
||||
}
|
||||
|
||||
return URLRequest;
|
||||
}
|
||||
|
||||
@end
|
||||
-110
@@ -1,110 +0,0 @@
|
||||
/*! @file OIDTokenResponse.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class OIDTokenRequest;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Represents the response to an token request.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-3.2
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
*/
|
||||
@interface OIDTokenResponse : NSObject <NSCopying, NSSecureCoding>
|
||||
|
||||
/*! @brief The request which was serviced.
|
||||
*/
|
||||
@property(nonatomic, readonly) OIDTokenRequest *request;
|
||||
|
||||
/*! @brief The access token generated by the authorization server.
|
||||
@remarks access_token
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.4
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *accessToken;
|
||||
|
||||
/*! @brief The approximate expiration date & time of the access token.
|
||||
@remarks expires_in
|
||||
@seealso OIDTokenResponse.accessToken
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.4
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSDate *accessTokenExpirationDate;
|
||||
|
||||
/*! @brief Typically "Bearer" when present. Otherwise, another token_type value that the Client has
|
||||
negotiated with the Authorization Server.
|
||||
@remarks token_type
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.4
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *tokenType;
|
||||
|
||||
/*! @brief ID Token value associated with the authenticated session. Always present for the
|
||||
authorization code grant exchange when OpenID Connect is used, optional for responses to
|
||||
access token refresh requests. Note that AppAuth does NOT verify the JWT signature. Users
|
||||
of AppAuth are encouraged to verifying the JWT signature using the validation library of
|
||||
their choosing.
|
||||
@remarks id_token
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#TokenResponse
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#RefreshTokenResponse
|
||||
@see http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
||||
@see https://jwt.io
|
||||
@discussion @c OIDIDToken can be used to parse the ID Token and extract the claims. As noted,
|
||||
this class does not verify the JWT signature.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *idToken;
|
||||
|
||||
/*! @brief The refresh token, which can be used to obtain new access tokens using the same
|
||||
authorization grant
|
||||
@remarks refresh_token
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *refreshToken;
|
||||
|
||||
/*! @brief The scope of the access token. OPTIONAL, if identical to the scopes requested, otherwise,
|
||||
REQUIRED.
|
||||
@remarks scope
|
||||
@see https://tools.ietf.org/html/rfc6749#section-5.1
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable) NSString *scope;
|
||||
|
||||
/*! @brief Additional parameters returned from the token server.
|
||||
*/
|
||||
@property(nonatomic, readonly, nullable)
|
||||
NSDictionary<NSString *, NSObject<NSCopying> *> *additionalParameters;
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. Please use initWithParameters:.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Designated initializer.
|
||||
@param request The serviced request.
|
||||
@param parameters The decoded parameters returned from the Authorization Server.
|
||||
@remarks Known parameters are extracted from the @c parameters parameter and the normative
|
||||
properties are populated. Non-normative parameters are placed in the
|
||||
@c #additionalParameters dictionary.
|
||||
*/
|
||||
- (instancetype)initWithRequest:(OIDTokenRequest *)request
|
||||
parameters:(NSDictionary<NSString *, NSObject<NSCopying> *> *)parameters
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-163
@@ -1,163 +0,0 @@
|
||||
/*! @file OIDTokenResponse.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDTokenResponse.h"
|
||||
|
||||
#import "OIDDefines.h"
|
||||
#import "OIDFieldMapping.h"
|
||||
#import "OIDTokenRequest.h"
|
||||
#import "OIDTokenUtilities.h"
|
||||
|
||||
/*! @brief Key used to encode the @c request property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kRequestKey = @"request";
|
||||
|
||||
/*! @brief The key for the @c accessToken property in the incoming parameters and for
|
||||
@c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kAccessTokenKey = @"access_token";
|
||||
|
||||
/*! @brief The key for the @c accessTokenExpirationDate property in the incoming parameters and for
|
||||
@c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kExpiresInKey = @"expires_in";
|
||||
|
||||
/*! @brief The key for the @c tokenType property in the incoming parameters and for
|
||||
@c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kTokenTypeKey = @"token_type";
|
||||
|
||||
/*! @brief The key for the @c idToken property in the incoming parameters and for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kIDTokenKey = @"id_token";
|
||||
|
||||
/*! @brief The key for the @c refreshToken property in the incoming parameters and for
|
||||
@c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kRefreshTokenKey = @"refresh_token";
|
||||
|
||||
/*! @brief The key for the @c scope property in the incoming parameters and for @c NSSecureCoding.
|
||||
*/
|
||||
static NSString *const kScopeKey = @"scope";
|
||||
|
||||
/*! @brief Key used to encode the @c additionalParameters property for @c NSSecureCoding
|
||||
*/
|
||||
static NSString *const kAdditionalParametersKey = @"additionalParameters";
|
||||
|
||||
@implementation OIDTokenResponse
|
||||
|
||||
/*! @brief Returns a mapping of incoming parameters to instance variables.
|
||||
@return A mapping of incoming parameters to instance variables.
|
||||
*/
|
||||
+ (NSDictionary<NSString *, OIDFieldMapping *> *)fieldMap {
|
||||
static NSMutableDictionary<NSString *, OIDFieldMapping *> *fieldMap;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
fieldMap = [NSMutableDictionary dictionary];
|
||||
fieldMap[kAccessTokenKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_accessToken" type:[NSString class]];
|
||||
fieldMap[kExpiresInKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_accessTokenExpirationDate"
|
||||
type:[NSDate class]
|
||||
conversion:[OIDFieldMapping dateSinceNowConversion]];
|
||||
fieldMap[kTokenTypeKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_tokenType" type:[NSString class]];
|
||||
fieldMap[kIDTokenKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_idToken" type:[NSString class]];
|
||||
fieldMap[kRefreshTokenKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_refreshToken" type:[NSString class]];
|
||||
fieldMap[kScopeKey] =
|
||||
[[OIDFieldMapping alloc] initWithName:@"_scope" type:[NSString class]];
|
||||
});
|
||||
return fieldMap;
|
||||
}
|
||||
|
||||
#pragma mark - Initializers
|
||||
|
||||
- (instancetype)init
|
||||
OID_UNAVAILABLE_USE_INITIALIZER(@selector(initWithRequest:parameters:))
|
||||
|
||||
- (instancetype)initWithRequest:(OIDTokenRequest *)request
|
||||
parameters:(NSDictionary<NSString *, NSObject<NSCopying> *> *)parameters {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_request = [request copy];
|
||||
NSDictionary<NSString *, NSObject<NSCopying> *> *additionalParameters =
|
||||
[OIDFieldMapping remainingParametersWithMap:[[self class] fieldMap]
|
||||
parameters:parameters
|
||||
instance:self];
|
||||
_additionalParameters = additionalParameters;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
// The documentation for NSCopying specifically advises us to return a reference to the original
|
||||
// instance in the case where instances are immutable (as ours is):
|
||||
// "Implement NSCopying by retaining the original instead of creating a new copy when the class
|
||||
// and its contents are immutable."
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
OIDTokenRequest *request =
|
||||
[aDecoder decodeObjectOfClass:[OIDTokenRequest class] forKey:kRequestKey];
|
||||
self = [self initWithRequest:request parameters:@{ }];
|
||||
if (self) {
|
||||
[OIDFieldMapping decodeWithCoder:aDecoder map:[[self class] fieldMap] instance:self];
|
||||
_additionalParameters = [aDecoder decodeObjectOfClasses:[OIDFieldMapping JSONTypes]
|
||||
forKey:kAdditionalParametersKey];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[OIDFieldMapping encodeWithCoder:aCoder map:[[self class] fieldMap] instance:self];
|
||||
[aCoder encodeObject:_request forKey:kRequestKey];
|
||||
[aCoder encodeObject:_additionalParameters forKey:kAdditionalParametersKey];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject overrides
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, accessToken: \"%@\", accessTokenExpirationDate: %@, "
|
||||
"tokenType: %@, idToken: \"%@\", refreshToken: \"%@\", "
|
||||
"scope: \"%@\", additionalParameters: %@, request: %@>",
|
||||
NSStringFromClass([self class]),
|
||||
(void *)self,
|
||||
[OIDTokenUtilities redact:_accessToken],
|
||||
_accessTokenExpirationDate,
|
||||
_tokenType,
|
||||
[OIDTokenUtilities redact:_idToken],
|
||||
[OIDTokenUtilities redact:_refreshToken],
|
||||
_scope,
|
||||
_additionalParameters,
|
||||
_request];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@end
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
/*! @file OIDTokenUtilities.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief Provides data encoding/decoding methods, random string generators, etc.
|
||||
*/
|
||||
@interface OIDTokenUtilities : NSObject
|
||||
|
||||
/*! @internal
|
||||
@brief Unavailable. This class should not be initialized.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/*! @brief Base64url-nopadding encodes the given data.
|
||||
@param data The input data.
|
||||
@return The base64url encoded data as a NSString.
|
||||
@discussion Base64url-nopadding is used in several identity specs such as PKCE and
|
||||
OpenID Connect.
|
||||
*/
|
||||
+ (NSString *)encodeBase64urlNoPadding:(NSData *)data;
|
||||
|
||||
/*! @brief Generates a URL-safe string of random data.
|
||||
@param size The number of random bytes to encode. NB. the length of the output string will be
|
||||
greater than the number of random bytes, due to the URL-safe encoding.
|
||||
@return Random data encoded with base64url.
|
||||
*/
|
||||
+ (nullable NSString *)randomURLSafeStringWithSize:(NSUInteger)size;
|
||||
|
||||
/*! @brief SHA256 hashes the input string.
|
||||
@param inputString The input string.
|
||||
@return The SHA256 data.
|
||||
*/
|
||||
+ (NSData *)sha256:(NSString *)inputString;
|
||||
|
||||
/*! @brief Truncated intput string after first 6 characters followed by ellipses
|
||||
@param inputString The input string.
|
||||
@return Truncated string.
|
||||
*/
|
||||
+ (nullable NSString *)redact:(nullable NSString *)inputString;
|
||||
|
||||
/*! @brief Form url encode the input string by applying application/x-www-form-urlencoded algorithm
|
||||
@param inputString The input string.
|
||||
@return The encoded string.
|
||||
*/
|
||||
+ (NSString*)formUrlEncode:(NSString*)inputString;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
/*! @file OIDTokenUtilities.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDTokenUtilities.h"
|
||||
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
|
||||
/*! @brief String representing the set of characters that are allowed as is for the
|
||||
application/x-www-form-urlencoded encoding algorithm.
|
||||
*/
|
||||
static NSString *const kFormUrlEncodedAllowedCharacters =
|
||||
@" *-._0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
@implementation OIDTokenUtilities
|
||||
|
||||
+ (NSString *)encodeBase64urlNoPadding:(NSData *)data {
|
||||
NSString *base64string = [data base64EncodedStringWithOptions:0];
|
||||
// converts base64 to base64url
|
||||
base64string = [base64string stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
|
||||
base64string = [base64string stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
|
||||
// strips padding
|
||||
base64string = [base64string stringByReplacingOccurrencesOfString:@"=" withString:@""];
|
||||
return base64string;
|
||||
}
|
||||
|
||||
+ (nullable NSString *)randomURLSafeStringWithSize:(NSUInteger)size {
|
||||
NSMutableData *randomData = [NSMutableData dataWithLength:size];
|
||||
int result = SecRandomCopyBytes(kSecRandomDefault, randomData.length, randomData.mutableBytes);
|
||||
if (result != 0) {
|
||||
return nil;
|
||||
}
|
||||
return [[self class] encodeBase64urlNoPadding:randomData];
|
||||
}
|
||||
|
||||
+ (NSData *)sha256:(NSString *)inputString {
|
||||
NSData *verifierData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSMutableData *sha256Verifier = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
|
||||
CC_SHA256(verifierData.bytes, (CC_LONG)verifierData.length, sha256Verifier.mutableBytes);
|
||||
return sha256Verifier;
|
||||
}
|
||||
|
||||
+ (NSString *)redact:(NSString *)inputString {
|
||||
if (inputString == nil) {
|
||||
return nil;
|
||||
}
|
||||
switch(inputString.length){
|
||||
case 0:
|
||||
return @"";
|
||||
case 1 ... 8:
|
||||
return @"[redacted]";
|
||||
case 9:
|
||||
default:
|
||||
return [[inputString substringToIndex:6] stringByAppendingString:@"...[redacted]"];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSString*)formUrlEncode:(NSString*)inputString {
|
||||
// https://www.w3.org/TR/html5/sec-forms.html#application-x-www-form-urlencoded-encoding-algorithm
|
||||
// Following the spec from the above link, application/x-www-form-urlencoded percent encode all
|
||||
// the characters except *-._A-Za-z0-9
|
||||
// Space character is replaced by + in the resulting bytes sequence
|
||||
if (inputString.length == 0) {
|
||||
return inputString;
|
||||
}
|
||||
NSCharacterSet *allowedCharacters =
|
||||
[NSCharacterSet characterSetWithCharactersInString:kFormUrlEncodedAllowedCharacters];
|
||||
// Percent encode all characters not present in the provided set.
|
||||
NSString *encodedString =
|
||||
[inputString stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
|
||||
// Replace occurences of space by '+' character
|
||||
return [encodedString stringByReplacingOccurrencesOfString:@" " withString:@"+"];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,93 +0,0 @@
|
||||
/*! @file OIDURLQueryComponent.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class OIDAuthorizationRequest;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief If set to YES, will force the iOS 7-only code for @c OIDURLQueryComponent to be used,
|
||||
even on non-iOS 7 devices and simulators. Useful for testing the iOS 7 code paths on the
|
||||
simulator. Defaults to NO.
|
||||
*/
|
||||
extern BOOL gOIDURLQueryComponentForceIOS7Handling;
|
||||
|
||||
/*! @brief A utility class for creating and parsing URL query components encoded with the
|
||||
application/x-www-form-urlencoded format.
|
||||
@description Supports application/x-www-form-urlencoded encoding and decoding, specifically
|
||||
'+' is replaced with space before percent decoding. For encoding, simply percent encodes
|
||||
space, as this is valid application/x-www-form-urlencoded.
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.2
|
||||
@see https://tools.ietf.org/html/rfc6749#section-4.1.3
|
||||
@see https://tools.ietf.org/html/rfc6749#appendix-B
|
||||
@see https://url.spec.whatwg.org/#urlencoded-parsing
|
||||
*/
|
||||
@interface OIDURLQueryComponent : NSObject
|
||||
|
||||
/*! @brief The parameter names in the query.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSArray<NSString *> *parameters;
|
||||
|
||||
/*! @brief The parameters represented as a dictionary.
|
||||
@remarks All values are @c NSString except for parameters which contain multiple values, in
|
||||
which case the value is an @c NSArray<NSString *> *.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSDictionary<NSString *, NSObject<NSCopying> *> *dictionaryValue;
|
||||
|
||||
/*! @brief Creates an @c OIDURLQueryComponent by parsing the query string in a URL.
|
||||
@param URL The URL from which to extract a query component.
|
||||
*/
|
||||
- (nullable instancetype)initWithURL:(NSURL *)URL;
|
||||
|
||||
/*! @brief The value (or values) for a named parameter in the query.
|
||||
@param parameter The parameter name. Case sensitive.
|
||||
@return The value (or values) for a named parameter in the query.
|
||||
*/
|
||||
- (NSArray<NSString *> *)valuesForParameter:(NSString *)parameter;
|
||||
|
||||
/*! @brief Adds a parameter value to the query.
|
||||
@param parameter The name of the parameter. Case sensitive.
|
||||
@param value The value to add.
|
||||
*/
|
||||
- (void)addParameter:(NSString *)parameter value:(NSString *)value;
|
||||
|
||||
/*! @brief Adds multiple parameters with associated values to the query.
|
||||
@param parameters The parameter name value pairs to add to the query.
|
||||
*/
|
||||
- (void)addParameters:(NSDictionary<NSString *, NSString *> *)parameters;
|
||||
|
||||
/*! @param URL The URL to add the query component to.
|
||||
@return The original URL with the query component replaced by the parameters from this query.
|
||||
*/
|
||||
- (NSURL *)URLByReplacingQueryInURL:(NSURL *)URL;
|
||||
|
||||
/*! @brief Builds an x-www-form-urlencoded string representing the parameters.
|
||||
@return The x-www-form-urlencoded string representing the parameters.
|
||||
*/
|
||||
- (NSString *)URLEncodedParameters;
|
||||
|
||||
/*! @brief A NSMutableCharacterSet containing allowed characters in URL parameter values (that is
|
||||
the "value" part of "?key=value"). This has less allowed characters than
|
||||
@c URLQueryAllowedCharacterSet, as the query component includes both the key & value.
|
||||
*/
|
||||
+ (NSMutableCharacterSet *)URLParamValueAllowedCharacters;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
-219
@@ -1,219 +0,0 @@
|
||||
/*! @file OIDURLQueryComponent.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDURLQueryComponent.h"
|
||||
|
||||
BOOL gOIDURLQueryComponentForceIOS7Handling = NO;
|
||||
|
||||
/*! @brief String representing the set of characters that are valid for the URL query
|
||||
(per @ NSCharacterSet.URLQueryAllowedCharacterSet), but are disallowed in URL query
|
||||
parameters and values.
|
||||
*/
|
||||
static NSString *const kQueryStringParamAdditionalDisallowedCharacters = @"=&+";
|
||||
|
||||
@implementation OIDURLQueryComponent {
|
||||
/*! @brief A dictionary of parameter names and values representing the contents of the query.
|
||||
*/
|
||||
NSMutableDictionary<NSString *, NSMutableArray<NSString *> *> *_parameters;
|
||||
}
|
||||
|
||||
- (nullable instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_parameters = [NSMutableDictionary dictionary];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithURL:(NSURL *)URL {
|
||||
self = [self init];
|
||||
if (self) {
|
||||
if (@available(iOS 8.0, macOS 10.10, *)) {
|
||||
// If NSURLQueryItem is available, use it for deconstructing the new URL. (iOS 8+)
|
||||
if (!gOIDURLQueryComponentForceIOS7Handling) {
|
||||
NSURLComponents *components =
|
||||
[NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO];
|
||||
// As OAuth uses application/x-www-form-urlencoded encoding, interprets '+' as a space
|
||||
// in addition to regular percent decoding. https://url.spec.whatwg.org/#urlencoded-parsing
|
||||
components.percentEncodedQuery =
|
||||
[components.percentEncodedQuery stringByReplacingOccurrencesOfString:@"+"
|
||||
withString:@"%20"];
|
||||
// NB. @c queryItems are already percent decoded
|
||||
NSArray<NSURLQueryItem *> *queryItems = components.queryItems;
|
||||
for (NSURLQueryItem *queryItem in queryItems) {
|
||||
[self addParameter:queryItem.name value:queryItem.value];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback for iOS 7
|
||||
NSString *query = URL.query;
|
||||
// As OAuth uses application/x-www-form-urlencoded encoding, interprets '+' as a space
|
||||
// in addition to regular percent decoding. https://url.spec.whatwg.org/#urlencoded-parsing
|
||||
query = [query stringByReplacingOccurrencesOfString:@"+" withString:@"%20"];
|
||||
|
||||
NSArray<NSString *> *queryParts = [query componentsSeparatedByString:@"&"];
|
||||
for (NSString *queryPart in queryParts) {
|
||||
NSRange equalsRange = [queryPart rangeOfString:@"="];
|
||||
if (equalsRange.location == NSNotFound) {
|
||||
continue;
|
||||
}
|
||||
NSString *name = [queryPart substringToIndex:equalsRange.location];
|
||||
name = name.stringByRemovingPercentEncoding;
|
||||
NSString *value = [queryPart substringFromIndex:equalsRange.location + equalsRange.length];
|
||||
value = value.stringByRemovingPercentEncoding;
|
||||
[self addParameter:name value:value];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)parameters {
|
||||
return _parameters.allKeys;
|
||||
}
|
||||
|
||||
- (NSDictionary<NSString *, NSObject<NSCopying> *> *)dictionaryValue {
|
||||
// This method will flatten arrays in our @c _parameters' values if only one value exists.
|
||||
NSMutableDictionary<NSString *, NSObject<NSCopying> *> *values = [NSMutableDictionary dictionary];
|
||||
for (NSString *parameter in _parameters.allKeys) {
|
||||
NSArray<NSString *> *value = _parameters[parameter];
|
||||
if (value.count == 1) {
|
||||
values[parameter] = [value.firstObject copy];
|
||||
} else {
|
||||
values[parameter] = [value copy];
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)valuesForParameter:(NSString *)parameter {
|
||||
return _parameters[parameter];
|
||||
}
|
||||
|
||||
- (void)addParameter:(NSString *)parameter value:(NSString *)value {
|
||||
NSMutableArray<NSString *> *parameterValues = _parameters[parameter];
|
||||
if (!parameterValues) {
|
||||
parameterValues = [NSMutableArray array];
|
||||
_parameters[parameter] = parameterValues;
|
||||
}
|
||||
[parameterValues addObject:value];
|
||||
}
|
||||
|
||||
- (void)addParameters:(NSDictionary<NSString *, NSString *> *)parameters {
|
||||
for (NSString *parameterName in parameters.allKeys) {
|
||||
[self addParameter:parameterName value:parameters[parameterName]];
|
||||
}
|
||||
}
|
||||
|
||||
/*! @brief Builds a query items array that can be set to @c NSURLComponents.queryItems
|
||||
@discussion The parameter names and values are NOT URL encoded.
|
||||
@return An array of unencoded @c NSURLQueryItem objects.
|
||||
*/
|
||||
- (NSMutableArray<NSURLQueryItem *> *)queryItems NS_AVAILABLE(10.10, 8.0) {
|
||||
NSMutableArray<NSURLQueryItem *> *queryParameters = [NSMutableArray array];
|
||||
for (NSString *parameterName in _parameters.allKeys) {
|
||||
NSArray<NSString *> *values = _parameters[parameterName];
|
||||
for (NSString *value in values) {
|
||||
NSURLQueryItem *item = [NSURLQueryItem queryItemWithName:parameterName value:value];
|
||||
[queryParameters addObject:item];
|
||||
}
|
||||
}
|
||||
return queryParameters;
|
||||
}
|
||||
|
||||
+ (NSMutableCharacterSet *)URLParamValueAllowedCharacters {
|
||||
// Starts with the standard URL-allowed character set.
|
||||
NSMutableCharacterSet *allowedParamCharacters =
|
||||
[[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
|
||||
// Removes additional characters we don't want to see in the query component.
|
||||
[allowedParamCharacters removeCharactersInString:kQueryStringParamAdditionalDisallowedCharacters];
|
||||
return allowedParamCharacters;
|
||||
}
|
||||
|
||||
/*! @brief Builds a query string that can be set to @c NSURLComponents.percentEncodedQuery
|
||||
@discussion This string is percent encoded, and shouldn't be used with
|
||||
@c NSURLComponents.query.
|
||||
@return An percentage encoded query string.
|
||||
*/
|
||||
- (NSString *)percentEncodedQueryString {
|
||||
NSMutableArray<NSString *> *parameterizedValues = [NSMutableArray array];
|
||||
|
||||
// Starts with the standard URL-allowed character set.
|
||||
NSMutableCharacterSet *allowedParamCharacters = [[self class] URLParamValueAllowedCharacters];
|
||||
|
||||
for (NSString *parameterName in _parameters.allKeys) {
|
||||
NSString *encodedParameterName =
|
||||
[parameterName stringByAddingPercentEncodingWithAllowedCharacters:allowedParamCharacters];
|
||||
|
||||
NSArray<NSString *> *values = _parameters[parameterName];
|
||||
for (NSString *value in values) {
|
||||
NSString *encodedValue =
|
||||
[value stringByAddingPercentEncodingWithAllowedCharacters:allowedParamCharacters];
|
||||
NSString *parameterizedValue =
|
||||
[NSString stringWithFormat:@"%@=%@", encodedParameterName, encodedValue];
|
||||
[parameterizedValues addObject:parameterizedValue];
|
||||
}
|
||||
}
|
||||
|
||||
NSString *queryString = [parameterizedValues componentsJoinedByString:@"&"];
|
||||
return queryString;
|
||||
}
|
||||
|
||||
- (NSString *)URLEncodedParameters {
|
||||
// If NSURLQueryItem is available, uses it for constructing the encoded parameters. (iOS 8+)
|
||||
if (@available(iOS 8.0, macOS 10.10, *)) {
|
||||
if (!gOIDURLQueryComponentForceIOS7Handling) {
|
||||
NSURLComponents *components = [[NSURLComponents alloc] init];
|
||||
components.queryItems = [self queryItems];
|
||||
NSString *encodedQuery = components.percentEncodedQuery;
|
||||
// NSURLComponents.percentEncodedQuery creates a validly escaped URL query component, but
|
||||
// doesn't encode the '+' leading to potential ambiguity with application/x-www-form-urlencoded
|
||||
// encoding. Percent encodes '+' to avoid this ambiguity.
|
||||
encodedQuery = [encodedQuery stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"];
|
||||
return encodedQuery;
|
||||
}
|
||||
}
|
||||
|
||||
// else, falls back to building query string manually (iOS 7)
|
||||
return [self percentEncodedQueryString];
|
||||
}
|
||||
|
||||
- (NSURL *)URLByReplacingQueryInURL:(NSURL *)URL {
|
||||
NSURLComponents *components =
|
||||
[NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO];
|
||||
|
||||
// Replaces encodedQuery component
|
||||
NSString *queryString = [self URLEncodedParameters];
|
||||
components.percentEncodedQuery = queryString;
|
||||
|
||||
NSURL *URLWithParameters = components.URL;
|
||||
return URLWithParameters;
|
||||
}
|
||||
|
||||
#pragma mark - NSObject overrides
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, parameters: %@>",
|
||||
NSStringFromClass([self class]),
|
||||
(void *)self,
|
||||
_parameters];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,40 +0,0 @@
|
||||
/*! @file OIDURLSessionProvider.h
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*! @brief A NSURLSession provider that allows clients to provide custom implementation
|
||||
for NSURLSession
|
||||
*/
|
||||
@interface OIDURLSessionProvider : NSObject
|
||||
|
||||
/*! @brief Obtains the current @c NSURLSession; using the +[NSURLSession sharedSession] if
|
||||
no custom implementation is provided.
|
||||
@return NSURLSession object to be used for making network requests.
|
||||
*/
|
||||
+ (NSURLSession *)session;
|
||||
|
||||
/*! @brief Allows library consumers to change the @c NSURLSession instance used to make
|
||||
network requests.
|
||||
@param session The @c NSURLSession instance that should be used for making network requests.
|
||||
*/
|
||||
+ (void)setSession:(NSURLSession *)session;
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,39 +0,0 @@
|
||||
/*! @file OIDURLSessionProvider.m
|
||||
@brief AppAuth iOS SDK
|
||||
@copyright
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
@copydetails
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "OIDURLSessionProvider.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
static NSURLSession *__nullable gURLSession;
|
||||
|
||||
@implementation OIDURLSessionProvider
|
||||
|
||||
+ (NSURLSession *)session {
|
||||
if (!gURLSession) {
|
||||
gURLSession = [NSURLSession sharedSession];
|
||||
}
|
||||
return gURLSession;
|
||||
}
|
||||
|
||||
+ (void)setSession:(NSURLSession *)session {
|
||||
NSAssert(session, @"Parameter: |session| must be non-nil.");
|
||||
gURLSession = session;
|
||||
}
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
Generated
-251
@@ -1,251 +0,0 @@
|
||||
BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL
|
||||
licensing. Files that are completely new have a Google copyright and an ISC
|
||||
license. This license is reproduced at the bottom of this file.
|
||||
|
||||
Contributors to BoringSSL are required to follow the CLA rules for Chromium:
|
||||
https://cla.developers.google.com/clas
|
||||
|
||||
Files in third_party/ have their own licenses, as described therein. The MIT
|
||||
license, for third_party/fiat, which, unlike other third_party directories, is
|
||||
compiled into non-test libraries, is included below.
|
||||
|
||||
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
|
||||
OpenSSL License and the original SSLeay license apply to the toolkit. See below
|
||||
for the actual license texts. Actually both licenses are BSD-style Open Source
|
||||
licenses. In case of any license issues related to OpenSSL please contact
|
||||
openssl-core@openssl.org.
|
||||
|
||||
The following are Google-internal bug numbers where explicit permission from
|
||||
some authors is recorded for use of their work. (This is purely for our own
|
||||
record keeping.)
|
||||
27287199
|
||||
27287880
|
||||
27287883
|
||||
|
||||
OpenSSL License
|
||||
---------------
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
Original SSLeay License
|
||||
-----------------------
|
||||
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
|
||||
ISC license used for completely new code in BoringSSL:
|
||||
|
||||
/* Copyright (c) 2015, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
|
||||
The code in third_party/fiat carries the MIT license:
|
||||
|
||||
Copyright (c) 2015-2016 the fiat-crypto authors (see
|
||||
https://github.com/mit-plv/fiat-crypto/blob/master/AUTHORS).
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
Licenses for support code
|
||||
-------------------------
|
||||
|
||||
Parts of the TLS test suite are under the Go license. This code is not included
|
||||
in BoringSSL (i.e. libcrypto and libssl) when compiled, however, so
|
||||
distributing code linked against BoringSSL does not trigger this license:
|
||||
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
BoringSSL uses the Chromium test infrastructure to run a continuous build,
|
||||
trybots etc. The scripts which manage this, and the script for generating build
|
||||
metadata, are under the Chromium license. Distributing code linked against
|
||||
BoringSSL does not trigger this license.
|
||||
|
||||
Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Generated
-1407
File diff suppressed because it is too large
Load Diff
Generated
-1407
File diff suppressed because it is too large
Load Diff
-271
@@ -1,271 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
|
||||
{
|
||||
return M_ASN1_BIT_STRING_set(x, d, len);
|
||||
}
|
||||
|
||||
int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
|
||||
{
|
||||
int ret, j, bits, len;
|
||||
unsigned char *p, *d;
|
||||
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
|
||||
len = a->length;
|
||||
|
||||
if (len > 0) {
|
||||
if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
|
||||
bits = (int)a->flags & 0x07;
|
||||
} else {
|
||||
for (; len > 0; len--) {
|
||||
if (a->data[len - 1])
|
||||
break;
|
||||
}
|
||||
j = a->data[len - 1];
|
||||
if (j & 0x01)
|
||||
bits = 0;
|
||||
else if (j & 0x02)
|
||||
bits = 1;
|
||||
else if (j & 0x04)
|
||||
bits = 2;
|
||||
else if (j & 0x08)
|
||||
bits = 3;
|
||||
else if (j & 0x10)
|
||||
bits = 4;
|
||||
else if (j & 0x20)
|
||||
bits = 5;
|
||||
else if (j & 0x40)
|
||||
bits = 6;
|
||||
else if (j & 0x80)
|
||||
bits = 7;
|
||||
else
|
||||
bits = 0; /* should not happen */
|
||||
}
|
||||
} else
|
||||
bits = 0;
|
||||
|
||||
ret = 1 + len;
|
||||
if (pp == NULL)
|
||||
return (ret);
|
||||
|
||||
p = *pp;
|
||||
|
||||
*(p++) = (unsigned char)bits;
|
||||
d = a->data;
|
||||
OPENSSL_memcpy(p, d, len);
|
||||
p += len;
|
||||
if (len > 0)
|
||||
p[-1] &= (0xff << bits);
|
||||
*pp = p;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
|
||||
const unsigned char **pp, long len)
|
||||
{
|
||||
ASN1_BIT_STRING *ret = NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *s;
|
||||
int padding;
|
||||
|
||||
if (len < 1) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (len > INT_MAX) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((a == NULL) || ((*a) == NULL)) {
|
||||
if ((ret = M_ASN1_BIT_STRING_new()) == NULL)
|
||||
return (NULL);
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
p = *pp;
|
||||
padding = *(p++);
|
||||
if (padding > 7) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* We do this to preserve the settings. If we modify the settings, via
|
||||
* the _set_bit function, we will recalculate on output
|
||||
*/
|
||||
ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
|
||||
ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding); /* set */
|
||||
|
||||
if (len-- > 1) { /* using one because of the bits left byte */
|
||||
s = (unsigned char *)OPENSSL_malloc((int)len);
|
||||
if (s == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_memcpy(s, p, (int)len);
|
||||
s[len - 1] &= (0xff << padding);
|
||||
p += len;
|
||||
} else
|
||||
s = NULL;
|
||||
|
||||
ret->length = (int)len;
|
||||
if (ret->data != NULL)
|
||||
OPENSSL_free(ret->data);
|
||||
ret->data = s;
|
||||
ret->type = V_ASN1_BIT_STRING;
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_BIT_STRING_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
|
||||
*/
|
||||
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
|
||||
{
|
||||
int w, v, iv;
|
||||
unsigned char *c;
|
||||
|
||||
w = n / 8;
|
||||
v = 1 << (7 - (n & 0x07));
|
||||
iv = ~v;
|
||||
if (!value)
|
||||
v = 0;
|
||||
|
||||
if (a == NULL)
|
||||
return 0;
|
||||
|
||||
a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
|
||||
|
||||
if ((a->length < (w + 1)) || (a->data == NULL)) {
|
||||
if (!value)
|
||||
return (1); /* Don't need to set */
|
||||
if (a->data == NULL)
|
||||
c = (unsigned char *)OPENSSL_malloc(w + 1);
|
||||
else
|
||||
c = (unsigned char *)OPENSSL_realloc(a->data, w + 1);
|
||||
if (c == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (w + 1 - a->length > 0)
|
||||
OPENSSL_memset(c + a->length, 0, w + 1 - a->length);
|
||||
a->data = c;
|
||||
a->length = w + 1;
|
||||
}
|
||||
a->data[w] = ((a->data[w]) & iv) | v;
|
||||
while ((a->length > 0) && (a->data[a->length - 1] == 0))
|
||||
a->length--;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
|
||||
{
|
||||
int w, v;
|
||||
|
||||
w = n / 8;
|
||||
v = 1 << (7 - (n & 0x07));
|
||||
if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
|
||||
return (0);
|
||||
return ((a->data[w] & v) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if the given bit string contains only bits specified by
|
||||
* the flags vector. Returns 0 if there is at least one bit set in 'a'
|
||||
* which is not specified in 'flags', 1 otherwise.
|
||||
* 'len' is the length of 'flags'.
|
||||
*/
|
||||
int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
|
||||
unsigned char *flags, int flags_len)
|
||||
{
|
||||
int i, ok;
|
||||
/* Check if there is one bit set at all. */
|
||||
if (!a || !a->data)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Check each byte of the internal representation of the bit string.
|
||||
*/
|
||||
ok = 1;
|
||||
for (i = 0; i < a->length && ok; ++i) {
|
||||
unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
|
||||
/* We are done if there is an unneeded bit set. */
|
||||
ok = (a->data[i] & mask) == 0;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
@@ -1,271 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
|
||||
{
|
||||
return M_ASN1_BIT_STRING_set(x, d, len);
|
||||
}
|
||||
|
||||
int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
|
||||
{
|
||||
int ret, j, bits, len;
|
||||
unsigned char *p, *d;
|
||||
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
|
||||
len = a->length;
|
||||
|
||||
if (len > 0) {
|
||||
if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
|
||||
bits = (int)a->flags & 0x07;
|
||||
} else {
|
||||
for (; len > 0; len--) {
|
||||
if (a->data[len - 1])
|
||||
break;
|
||||
}
|
||||
j = a->data[len - 1];
|
||||
if (j & 0x01)
|
||||
bits = 0;
|
||||
else if (j & 0x02)
|
||||
bits = 1;
|
||||
else if (j & 0x04)
|
||||
bits = 2;
|
||||
else if (j & 0x08)
|
||||
bits = 3;
|
||||
else if (j & 0x10)
|
||||
bits = 4;
|
||||
else if (j & 0x20)
|
||||
bits = 5;
|
||||
else if (j & 0x40)
|
||||
bits = 6;
|
||||
else if (j & 0x80)
|
||||
bits = 7;
|
||||
else
|
||||
bits = 0; /* should not happen */
|
||||
}
|
||||
} else
|
||||
bits = 0;
|
||||
|
||||
ret = 1 + len;
|
||||
if (pp == NULL)
|
||||
return (ret);
|
||||
|
||||
p = *pp;
|
||||
|
||||
*(p++) = (unsigned char)bits;
|
||||
d = a->data;
|
||||
OPENSSL_memcpy(p, d, len);
|
||||
p += len;
|
||||
if (len > 0)
|
||||
p[-1] &= (0xff << bits);
|
||||
*pp = p;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
|
||||
const unsigned char **pp, long len)
|
||||
{
|
||||
ASN1_BIT_STRING *ret = NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *s;
|
||||
int padding;
|
||||
|
||||
if (len < 1) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (len > INT_MAX) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((a == NULL) || ((*a) == NULL)) {
|
||||
if ((ret = M_ASN1_BIT_STRING_new()) == NULL)
|
||||
return (NULL);
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
p = *pp;
|
||||
padding = *(p++);
|
||||
if (padding > 7) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* We do this to preserve the settings. If we modify the settings, via
|
||||
* the _set_bit function, we will recalculate on output
|
||||
*/
|
||||
ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
|
||||
ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding); /* set */
|
||||
|
||||
if (len-- > 1) { /* using one because of the bits left byte */
|
||||
s = (unsigned char *)OPENSSL_malloc((int)len);
|
||||
if (s == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_memcpy(s, p, (int)len);
|
||||
s[len - 1] &= (0xff << padding);
|
||||
p += len;
|
||||
} else
|
||||
s = NULL;
|
||||
|
||||
ret->length = (int)len;
|
||||
if (ret->data != NULL)
|
||||
OPENSSL_free(ret->data);
|
||||
ret->data = s;
|
||||
ret->type = V_ASN1_BIT_STRING;
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_BIT_STRING_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
|
||||
*/
|
||||
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
|
||||
{
|
||||
int w, v, iv;
|
||||
unsigned char *c;
|
||||
|
||||
w = n / 8;
|
||||
v = 1 << (7 - (n & 0x07));
|
||||
iv = ~v;
|
||||
if (!value)
|
||||
v = 0;
|
||||
|
||||
if (a == NULL)
|
||||
return 0;
|
||||
|
||||
a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
|
||||
|
||||
if ((a->length < (w + 1)) || (a->data == NULL)) {
|
||||
if (!value)
|
||||
return (1); /* Don't need to set */
|
||||
if (a->data == NULL)
|
||||
c = (unsigned char *)OPENSSL_malloc(w + 1);
|
||||
else
|
||||
c = (unsigned char *)OPENSSL_realloc(a->data, w + 1);
|
||||
if (c == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (w + 1 - a->length > 0)
|
||||
OPENSSL_memset(c + a->length, 0, w + 1 - a->length);
|
||||
a->data = c;
|
||||
a->length = w + 1;
|
||||
}
|
||||
a->data[w] = ((a->data[w]) & iv) | v;
|
||||
while ((a->length > 0) && (a->data[a->length - 1] == 0))
|
||||
a->length--;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
|
||||
{
|
||||
int w, v;
|
||||
|
||||
w = n / 8;
|
||||
v = 1 << (7 - (n & 0x07));
|
||||
if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
|
||||
return (0);
|
||||
return ((a->data[w] & v) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if the given bit string contains only bits specified by
|
||||
* the flags vector. Returns 0 if there is at least one bit set in 'a'
|
||||
* which is not specified in 'flags', 1 otherwise.
|
||||
* 'len' is the length of 'flags'.
|
||||
*/
|
||||
int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
|
||||
unsigned char *flags, int flags_len)
|
||||
{
|
||||
int i, ok;
|
||||
/* Check if there is one bit set at all. */
|
||||
if (!a || !a->data)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Check each byte of the internal representation of the bit string.
|
||||
*/
|
||||
ok = 1;
|
||||
for (i = 0; i < a->length && ok; ++i) {
|
||||
unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
|
||||
/* We are done if there is an unneeded bit set. */
|
||||
ok = (a->data[i] & mask) == 0;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
-123
@@ -1,123 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
int i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
|
||||
{
|
||||
int r;
|
||||
unsigned char *p, *allocated = NULL;
|
||||
|
||||
r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN);
|
||||
if (pp == NULL)
|
||||
return (r);
|
||||
|
||||
if (*pp == NULL) {
|
||||
if ((p = allocated = OPENSSL_malloc(r)) == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
p = *pp;
|
||||
}
|
||||
|
||||
ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL);
|
||||
*p = (unsigned char)a;
|
||||
|
||||
/*
|
||||
* If a new buffer was allocated, just return it back.
|
||||
* If not, return the incremented buffer pointer.
|
||||
*/
|
||||
*pp = allocated != NULL ? allocated : p + 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
|
||||
{
|
||||
int ret = -1;
|
||||
const unsigned char *p;
|
||||
long len;
|
||||
int inf, tag, xclass;
|
||||
int i = 0;
|
||||
|
||||
p = *pp;
|
||||
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
|
||||
if (inf & 0x80) {
|
||||
i = ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tag != V_ASN1_BOOLEAN) {
|
||||
i = ASN1_R_EXPECTING_A_BOOLEAN;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (len != 1) {
|
||||
i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
|
||||
goto err;
|
||||
}
|
||||
ret = (int)*(p++);
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
OPENSSL_PUT_ERROR(ASN1, i);
|
||||
return (ret);
|
||||
}
|
||||
-123
@@ -1,123 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
int i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
|
||||
{
|
||||
int r;
|
||||
unsigned char *p, *allocated = NULL;
|
||||
|
||||
r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN);
|
||||
if (pp == NULL)
|
||||
return (r);
|
||||
|
||||
if (*pp == NULL) {
|
||||
if ((p = allocated = OPENSSL_malloc(r)) == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
p = *pp;
|
||||
}
|
||||
|
||||
ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL);
|
||||
*p = (unsigned char)a;
|
||||
|
||||
/*
|
||||
* If a new buffer was allocated, just return it back.
|
||||
* If not, return the incremented buffer pointer.
|
||||
*/
|
||||
*pp = allocated != NULL ? allocated : p + 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
|
||||
{
|
||||
int ret = -1;
|
||||
const unsigned char *p;
|
||||
long len;
|
||||
int inf, tag, xclass;
|
||||
int i = 0;
|
||||
|
||||
p = *pp;
|
||||
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
|
||||
if (inf & 0x80) {
|
||||
i = ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tag != V_ASN1_BOOLEAN) {
|
||||
i = ASN1_R_EXPECTING_A_BOOLEAN;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (len != 1) {
|
||||
i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
|
||||
goto err;
|
||||
}
|
||||
ret = (int)*(p++);
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
OPENSSL_PUT_ERROR(ASN1, i);
|
||||
return (ret);
|
||||
}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <openssl_grpc/bio.h>
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
|
||||
void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
|
||||
{
|
||||
uint8_t *data;
|
||||
size_t len;
|
||||
// Historically, this function did not impose a limit in OpenSSL and is used
|
||||
// to read CRLs, so we leave this without an external bound.
|
||||
if (!BIO_read_asn1(in, &data, &len, INT_MAX)) {
|
||||
return NULL;
|
||||
}
|
||||
const uint8_t *ptr = data;
|
||||
void *ret = ASN1_item_d2i(x, &ptr, len, it);
|
||||
OPENSSL_free(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
|
||||
{
|
||||
BIO *b = BIO_new_fp(in, BIO_NOCLOSE);
|
||||
if (b == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
|
||||
return NULL;
|
||||
}
|
||||
void *ret = ASN1_item_d2i_bio(it, b, x);
|
||||
BIO_free(b);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
@@ -1,93 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
|
||||
{
|
||||
uint8_t *data;
|
||||
size_t len;
|
||||
// Historically, this function did not impose a limit in OpenSSL and is used
|
||||
// to read CRLs, so we leave this without an external bound.
|
||||
if (!BIO_read_asn1(in, &data, &len, INT_MAX)) {
|
||||
return NULL;
|
||||
}
|
||||
const uint8_t *ptr = data;
|
||||
void *ret = ASN1_item_d2i(x, &ptr, len, it);
|
||||
OPENSSL_free(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
|
||||
{
|
||||
BIO *b = BIO_new_fp(in, BIO_NOCLOSE);
|
||||
if (b == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
|
||||
return NULL;
|
||||
}
|
||||
void *ret = ASN1_item_d2i_bio(it, b, x);
|
||||
BIO_free(b);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
/*
|
||||
* ASN1_ITEM version of dup: this follows the model above except we don't
|
||||
* need to allocate the buffer. At some point this could be rewritten to
|
||||
* directly dup the underlying structure instead of doing and encode and
|
||||
* decode.
|
||||
*/
|
||||
void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
|
||||
{
|
||||
unsigned char *b = NULL;
|
||||
const unsigned char *p;
|
||||
long i;
|
||||
void *ret;
|
||||
|
||||
if (x == NULL)
|
||||
return (NULL);
|
||||
|
||||
i = ASN1_item_i2d(x, &b, it);
|
||||
if (b == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
p = b;
|
||||
ret = ASN1_item_d2i(NULL, &p, i, it);
|
||||
OPENSSL_free(b);
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
/*
|
||||
* ASN1_ITEM version of dup: this follows the model above except we don't
|
||||
* need to allocate the buffer. At some point this could be rewritten to
|
||||
* directly dup the underlying structure instead of doing and encode and
|
||||
* decode.
|
||||
*/
|
||||
void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
|
||||
{
|
||||
unsigned char *b = NULL;
|
||||
const unsigned char *p;
|
||||
long i;
|
||||
void *ret;
|
||||
|
||||
if (x == NULL)
|
||||
return (NULL);
|
||||
|
||||
i = ASN1_item_i2d(x, &b, it);
|
||||
if (b == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
p = b;
|
||||
ret = ASN1_item_d2i(NULL, &p, i, it);
|
||||
OPENSSL_free(b);
|
||||
return (ret);
|
||||
}
|
||||
-195
@@ -1,195 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Code for ENUMERATED type: identical to INTEGER apart from a different tag.
|
||||
* for comments on encoding see a_int.c
|
||||
*/
|
||||
|
||||
int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
|
||||
{
|
||||
int j, k;
|
||||
unsigned int i;
|
||||
unsigned char buf[sizeof(long) + 1];
|
||||
long d;
|
||||
|
||||
a->type = V_ASN1_ENUMERATED;
|
||||
if (a->length < (int)(sizeof(long) + 1)) {
|
||||
if (a->data != NULL)
|
||||
OPENSSL_free(a->data);
|
||||
if ((a->data =
|
||||
(unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
|
||||
OPENSSL_memset((char *)a->data, 0, sizeof(long) + 1);
|
||||
}
|
||||
if (a->data == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
d = v;
|
||||
if (d < 0) {
|
||||
d = -d;
|
||||
a->type = V_ASN1_NEG_ENUMERATED;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(long); i++) {
|
||||
if (d == 0)
|
||||
break;
|
||||
buf[i] = (int)d & 0xff;
|
||||
d >>= 8;
|
||||
}
|
||||
j = 0;
|
||||
for (k = i - 1; k >= 0; k--)
|
||||
a->data[j++] = buf[k];
|
||||
a->length = j;
|
||||
return (1);
|
||||
}
|
||||
|
||||
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
||||
{
|
||||
int neg = 0, i;
|
||||
|
||||
if (a == NULL)
|
||||
return (0L);
|
||||
i = a->type;
|
||||
if (i == V_ASN1_NEG_ENUMERATED)
|
||||
neg = 1;
|
||||
else if (i != V_ASN1_ENUMERATED)
|
||||
return -1;
|
||||
|
||||
OPENSSL_STATIC_ASSERT(sizeof(uint64_t) >= sizeof(long),
|
||||
"long larger than uint64_t");
|
||||
|
||||
if (a->length > (int)sizeof(uint64_t)) {
|
||||
/* hmm... a bit ugly */
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t r64 = 0;
|
||||
if (a->data != NULL) {
|
||||
for (i = 0; i < a->length; i++) {
|
||||
r64 <<= 8;
|
||||
r64 |= (unsigned char)a->data[i];
|
||||
}
|
||||
|
||||
if (r64 > LONG_MAX) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long r = (long) r64;
|
||||
if (neg)
|
||||
r = -r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
|
||||
{
|
||||
ASN1_ENUMERATED *ret;
|
||||
int len, j;
|
||||
|
||||
if (ai == NULL)
|
||||
ret = M_ASN1_ENUMERATED_new();
|
||||
else
|
||||
ret = ai;
|
||||
if (ret == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_negative(bn))
|
||||
ret->type = V_ASN1_NEG_ENUMERATED;
|
||||
else
|
||||
ret->type = V_ASN1_ENUMERATED;
|
||||
j = BN_num_bits(bn);
|
||||
len = ((j == 0) ? 0 : ((j / 8) + 1));
|
||||
if (ret->length < len + 4) {
|
||||
unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
|
||||
if (!new_data) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ret->data = new_data;
|
||||
}
|
||||
|
||||
ret->length = BN_bn2bin(bn, ret->data);
|
||||
return (ret);
|
||||
err:
|
||||
if (ret != ai)
|
||||
M_ASN1_ENUMERATED_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
|
||||
{
|
||||
BIGNUM *ret;
|
||||
|
||||
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
|
||||
else if (ai->type == V_ASN1_NEG_ENUMERATED)
|
||||
BN_set_negative(ret, 1);
|
||||
return (ret);
|
||||
}
|
||||
-195
@@ -1,195 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Code for ENUMERATED type: identical to INTEGER apart from a different tag.
|
||||
* for comments on encoding see a_int.c
|
||||
*/
|
||||
|
||||
int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
|
||||
{
|
||||
int j, k;
|
||||
unsigned int i;
|
||||
unsigned char buf[sizeof(long) + 1];
|
||||
long d;
|
||||
|
||||
a->type = V_ASN1_ENUMERATED;
|
||||
if (a->length < (int)(sizeof(long) + 1)) {
|
||||
if (a->data != NULL)
|
||||
OPENSSL_free(a->data);
|
||||
if ((a->data =
|
||||
(unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
|
||||
OPENSSL_memset((char *)a->data, 0, sizeof(long) + 1);
|
||||
}
|
||||
if (a->data == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
d = v;
|
||||
if (d < 0) {
|
||||
d = -d;
|
||||
a->type = V_ASN1_NEG_ENUMERATED;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(long); i++) {
|
||||
if (d == 0)
|
||||
break;
|
||||
buf[i] = (int)d & 0xff;
|
||||
d >>= 8;
|
||||
}
|
||||
j = 0;
|
||||
for (k = i - 1; k >= 0; k--)
|
||||
a->data[j++] = buf[k];
|
||||
a->length = j;
|
||||
return (1);
|
||||
}
|
||||
|
||||
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
||||
{
|
||||
int neg = 0, i;
|
||||
|
||||
if (a == NULL)
|
||||
return (0L);
|
||||
i = a->type;
|
||||
if (i == V_ASN1_NEG_ENUMERATED)
|
||||
neg = 1;
|
||||
else if (i != V_ASN1_ENUMERATED)
|
||||
return -1;
|
||||
|
||||
OPENSSL_STATIC_ASSERT(sizeof(uint64_t) >= sizeof(long),
|
||||
"long larger than uint64_t");
|
||||
|
||||
if (a->length > (int)sizeof(uint64_t)) {
|
||||
/* hmm... a bit ugly */
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t r64 = 0;
|
||||
if (a->data != NULL) {
|
||||
for (i = 0; i < a->length; i++) {
|
||||
r64 <<= 8;
|
||||
r64 |= (unsigned char)a->data[i];
|
||||
}
|
||||
|
||||
if (r64 > LONG_MAX) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long r = (long) r64;
|
||||
if (neg)
|
||||
r = -r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
|
||||
{
|
||||
ASN1_ENUMERATED *ret;
|
||||
int len, j;
|
||||
|
||||
if (ai == NULL)
|
||||
ret = M_ASN1_ENUMERATED_new();
|
||||
else
|
||||
ret = ai;
|
||||
if (ret == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_negative(bn))
|
||||
ret->type = V_ASN1_NEG_ENUMERATED;
|
||||
else
|
||||
ret->type = V_ASN1_ENUMERATED;
|
||||
j = BN_num_bits(bn);
|
||||
len = ((j == 0) ? 0 : ((j / 8) + 1));
|
||||
if (ret->length < len + 4) {
|
||||
unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
|
||||
if (!new_data) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ret->data = new_data;
|
||||
}
|
||||
|
||||
ret->length = BN_bn2bin(bn, ret->data);
|
||||
return (ret);
|
||||
err:
|
||||
if (ret != ai)
|
||||
M_ASN1_ENUMERATED_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
|
||||
{
|
||||
BIGNUM *ret;
|
||||
|
||||
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
|
||||
else if (ai->type == V_ASN1_NEG_ENUMERATED)
|
||||
BN_set_negative(ret, 1);
|
||||
return (ret);
|
||||
}
|
||||
-261
@@ -1,261 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
#include "asn1_locl.h"
|
||||
|
||||
int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
|
||||
{
|
||||
static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
|
||||
static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
|
||||
char *a;
|
||||
int n, i, l, o;
|
||||
|
||||
if (d->type != V_ASN1_GENERALIZEDTIME)
|
||||
return (0);
|
||||
l = d->length;
|
||||
a = (char *)d->data;
|
||||
o = 0;
|
||||
/*
|
||||
* GENERALIZEDTIME is similar to UTCTIME except the year is represented
|
||||
* as YYYY. This stuff treats everything as a two digit field so make
|
||||
* first two fields 00 to 99
|
||||
*/
|
||||
if (l < 13)
|
||||
goto err;
|
||||
for (i = 0; i < 7; i++) {
|
||||
if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
|
||||
i++;
|
||||
if (tm)
|
||||
tm->tm_sec = 0;
|
||||
break;
|
||||
}
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = a[o] - '0';
|
||||
if (++o > l)
|
||||
goto err;
|
||||
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = (n * 10) + a[o] - '0';
|
||||
if (++o > l)
|
||||
goto err;
|
||||
|
||||
if ((n < min[i]) || (n > max[i]))
|
||||
goto err;
|
||||
if (tm) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
tm->tm_year = n * 100 - 1900;
|
||||
break;
|
||||
case 1:
|
||||
tm->tm_year += n;
|
||||
break;
|
||||
case 2:
|
||||
tm->tm_mon = n - 1;
|
||||
break;
|
||||
case 3:
|
||||
tm->tm_mday = n;
|
||||
break;
|
||||
case 4:
|
||||
tm->tm_hour = n;
|
||||
break;
|
||||
case 5:
|
||||
tm->tm_min = n;
|
||||
break;
|
||||
case 6:
|
||||
tm->tm_sec = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Optional fractional seconds: decimal point followed by one or more
|
||||
* digits.
|
||||
*/
|
||||
if (a[o] == '.') {
|
||||
if (++o > l)
|
||||
goto err;
|
||||
i = o;
|
||||
while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
|
||||
o++;
|
||||
/* Must have at least one digit after decimal point */
|
||||
if (i == o)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (a[o] == 'Z')
|
||||
o++;
|
||||
else if ((a[o] == '+') || (a[o] == '-')) {
|
||||
int offsign = a[o] == '-' ? 1 : -1, offset = 0;
|
||||
o++;
|
||||
if (o + 4 > l)
|
||||
goto err;
|
||||
for (i = 7; i < 9; i++) {
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = a[o] - '0';
|
||||
o++;
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = (n * 10) + a[o] - '0';
|
||||
if ((n < min[i]) || (n > max[i]))
|
||||
goto err;
|
||||
if (tm) {
|
||||
if (i == 7)
|
||||
offset = n * 3600;
|
||||
else if (i == 8)
|
||||
offset += n * 60;
|
||||
}
|
||||
o++;
|
||||
}
|
||||
if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
|
||||
return 0;
|
||||
} else if (a[o]) {
|
||||
/* Missing time zone information. */
|
||||
goto err;
|
||||
}
|
||||
return (o == l);
|
||||
err:
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
|
||||
{
|
||||
return asn1_generalizedtime_to_tm(NULL, d);
|
||||
}
|
||||
|
||||
int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME t;
|
||||
|
||||
t.type = V_ASN1_GENERALIZEDTIME;
|
||||
t.length = strlen(str);
|
||||
t.data = (unsigned char *)str;
|
||||
if (ASN1_GENERALIZEDTIME_check(&t)) {
|
||||
if (s != NULL) {
|
||||
if (!ASN1_STRING_set((ASN1_STRING *)s,
|
||||
(unsigned char *)str, t.length))
|
||||
return 0;
|
||||
s->type = V_ASN1_GENERALIZEDTIME;
|
||||
}
|
||||
return (1);
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
|
||||
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
|
||||
time_t t)
|
||||
{
|
||||
return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
|
||||
}
|
||||
|
||||
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
|
||||
time_t t, int offset_day,
|
||||
long offset_sec)
|
||||
{
|
||||
char *p;
|
||||
struct tm *ts;
|
||||
struct tm data;
|
||||
size_t len = 20;
|
||||
ASN1_GENERALIZEDTIME *tmps = NULL;
|
||||
|
||||
if (s == NULL)
|
||||
tmps = ASN1_GENERALIZEDTIME_new();
|
||||
else
|
||||
tmps = s;
|
||||
if (tmps == NULL)
|
||||
return NULL;
|
||||
|
||||
ts = OPENSSL_gmtime(&t, &data);
|
||||
if (ts == NULL)
|
||||
goto err;
|
||||
|
||||
if (offset_day || offset_sec) {
|
||||
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
|
||||
goto err;
|
||||
}
|
||||
|
||||
p = (char *)tmps->data;
|
||||
if ((p == NULL) || ((size_t)tmps->length < len)) {
|
||||
p = OPENSSL_malloc(len);
|
||||
if (p == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_free(tmps->data);
|
||||
tmps->data = (unsigned char *)p;
|
||||
}
|
||||
|
||||
BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900,
|
||||
ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
|
||||
ts->tm_sec);
|
||||
tmps->length = strlen(p);
|
||||
tmps->type = V_ASN1_GENERALIZEDTIME;
|
||||
return tmps;
|
||||
err:
|
||||
if (s == NULL)
|
||||
ASN1_GENERALIZEDTIME_free(tmps);
|
||||
return NULL;
|
||||
}
|
||||
-261
@@ -1,261 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "asn1_locl.h"
|
||||
|
||||
int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
|
||||
{
|
||||
static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
|
||||
static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
|
||||
char *a;
|
||||
int n, i, l, o;
|
||||
|
||||
if (d->type != V_ASN1_GENERALIZEDTIME)
|
||||
return (0);
|
||||
l = d->length;
|
||||
a = (char *)d->data;
|
||||
o = 0;
|
||||
/*
|
||||
* GENERALIZEDTIME is similar to UTCTIME except the year is represented
|
||||
* as YYYY. This stuff treats everything as a two digit field so make
|
||||
* first two fields 00 to 99
|
||||
*/
|
||||
if (l < 13)
|
||||
goto err;
|
||||
for (i = 0; i < 7; i++) {
|
||||
if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
|
||||
i++;
|
||||
if (tm)
|
||||
tm->tm_sec = 0;
|
||||
break;
|
||||
}
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = a[o] - '0';
|
||||
if (++o > l)
|
||||
goto err;
|
||||
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = (n * 10) + a[o] - '0';
|
||||
if (++o > l)
|
||||
goto err;
|
||||
|
||||
if ((n < min[i]) || (n > max[i]))
|
||||
goto err;
|
||||
if (tm) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
tm->tm_year = n * 100 - 1900;
|
||||
break;
|
||||
case 1:
|
||||
tm->tm_year += n;
|
||||
break;
|
||||
case 2:
|
||||
tm->tm_mon = n - 1;
|
||||
break;
|
||||
case 3:
|
||||
tm->tm_mday = n;
|
||||
break;
|
||||
case 4:
|
||||
tm->tm_hour = n;
|
||||
break;
|
||||
case 5:
|
||||
tm->tm_min = n;
|
||||
break;
|
||||
case 6:
|
||||
tm->tm_sec = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Optional fractional seconds: decimal point followed by one or more
|
||||
* digits.
|
||||
*/
|
||||
if (a[o] == '.') {
|
||||
if (++o > l)
|
||||
goto err;
|
||||
i = o;
|
||||
while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
|
||||
o++;
|
||||
/* Must have at least one digit after decimal point */
|
||||
if (i == o)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (a[o] == 'Z')
|
||||
o++;
|
||||
else if ((a[o] == '+') || (a[o] == '-')) {
|
||||
int offsign = a[o] == '-' ? 1 : -1, offset = 0;
|
||||
o++;
|
||||
if (o + 4 > l)
|
||||
goto err;
|
||||
for (i = 7; i < 9; i++) {
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = a[o] - '0';
|
||||
o++;
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = (n * 10) + a[o] - '0';
|
||||
if ((n < min[i]) || (n > max[i]))
|
||||
goto err;
|
||||
if (tm) {
|
||||
if (i == 7)
|
||||
offset = n * 3600;
|
||||
else if (i == 8)
|
||||
offset += n * 60;
|
||||
}
|
||||
o++;
|
||||
}
|
||||
if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
|
||||
return 0;
|
||||
} else if (a[o]) {
|
||||
/* Missing time zone information. */
|
||||
goto err;
|
||||
}
|
||||
return (o == l);
|
||||
err:
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
|
||||
{
|
||||
return asn1_generalizedtime_to_tm(NULL, d);
|
||||
}
|
||||
|
||||
int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME t;
|
||||
|
||||
t.type = V_ASN1_GENERALIZEDTIME;
|
||||
t.length = strlen(str);
|
||||
t.data = (unsigned char *)str;
|
||||
if (ASN1_GENERALIZEDTIME_check(&t)) {
|
||||
if (s != NULL) {
|
||||
if (!ASN1_STRING_set((ASN1_STRING *)s,
|
||||
(unsigned char *)str, t.length))
|
||||
return 0;
|
||||
s->type = V_ASN1_GENERALIZEDTIME;
|
||||
}
|
||||
return (1);
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
|
||||
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
|
||||
time_t t)
|
||||
{
|
||||
return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
|
||||
}
|
||||
|
||||
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
|
||||
time_t t, int offset_day,
|
||||
long offset_sec)
|
||||
{
|
||||
char *p;
|
||||
struct tm *ts;
|
||||
struct tm data;
|
||||
size_t len = 20;
|
||||
ASN1_GENERALIZEDTIME *tmps = NULL;
|
||||
|
||||
if (s == NULL)
|
||||
tmps = ASN1_GENERALIZEDTIME_new();
|
||||
else
|
||||
tmps = s;
|
||||
if (tmps == NULL)
|
||||
return NULL;
|
||||
|
||||
ts = OPENSSL_gmtime(&t, &data);
|
||||
if (ts == NULL)
|
||||
goto err;
|
||||
|
||||
if (offset_day || offset_sec) {
|
||||
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
|
||||
goto err;
|
||||
}
|
||||
|
||||
p = (char *)tmps->data;
|
||||
if ((p == NULL) || ((size_t)tmps->length < len)) {
|
||||
p = OPENSSL_malloc(len);
|
||||
if (p == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_free(tmps->data);
|
||||
tmps->data = (unsigned char *)p;
|
||||
}
|
||||
|
||||
BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900,
|
||||
ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
|
||||
ts->tm_sec);
|
||||
tmps->length = strlen(p);
|
||||
tmps->type = V_ASN1_GENERALIZEDTIME;
|
||||
return tmps;
|
||||
err:
|
||||
if (s == NULL)
|
||||
ASN1_GENERALIZEDTIME_free(tmps);
|
||||
return NULL;
|
||||
}
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <openssl_grpc/bio.h>
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
|
||||
int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
|
||||
{
|
||||
BIO *b = BIO_new_fp(out, BIO_NOCLOSE);
|
||||
if (b == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
int ret = ASN1_item_i2d_bio(it, b, x);
|
||||
BIO_free(b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
|
||||
{
|
||||
unsigned char *b = NULL;
|
||||
int n = ASN1_item_i2d(x, &b, it);
|
||||
if (b == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = BIO_write_all(out, b, n);
|
||||
OPENSSL_free(b);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
|
||||
{
|
||||
BIO *b = BIO_new_fp(out, BIO_NOCLOSE);
|
||||
if (b == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
int ret = ASN1_item_i2d_bio(it, b, x);
|
||||
BIO_free(b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
|
||||
{
|
||||
unsigned char *b = NULL;
|
||||
int n = ASN1_item_i2d(x, &b, it);
|
||||
if (b == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = BIO_write_all(out, b, n);
|
||||
OPENSSL_free(b);
|
||||
return ret;
|
||||
}
|
||||
-420
@@ -1,420 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
|
||||
{
|
||||
return M_ASN1_INTEGER_dup(x);
|
||||
}
|
||||
|
||||
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
|
||||
{
|
||||
int neg, ret;
|
||||
/* Compare signs */
|
||||
neg = x->type & V_ASN1_NEG;
|
||||
if (neg != (y->type & V_ASN1_NEG)) {
|
||||
if (neg)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = ASN1_STRING_cmp(x, y);
|
||||
|
||||
if (neg)
|
||||
return -ret;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This converts an ASN1 INTEGER into its content encoding.
|
||||
* The internal representation is an ASN1_STRING whose data is a big endian
|
||||
* representation of the value, ignoring the sign. The sign is determined by
|
||||
* the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
|
||||
*
|
||||
* Positive integers are no problem: they are almost the same as the DER
|
||||
* encoding, except if the first byte is >= 0x80 we need to add a zero pad.
|
||||
*
|
||||
* Negative integers are a bit trickier...
|
||||
* The DER representation of negative integers is in 2s complement form.
|
||||
* The internal form is converted by complementing each octet and finally
|
||||
* adding one to the result. This can be done less messily with a little trick.
|
||||
* If the internal form has trailing zeroes then they will become FF by the
|
||||
* complement and 0 by the add one (due to carry) so just copy as many trailing
|
||||
* zeros to the destination as there are in the source. The carry will add one
|
||||
* to the last none zero octet: so complement this octet and add one and finally
|
||||
* complement any left over until you get to the start of the string.
|
||||
*
|
||||
* Padding is a little trickier too. If the first bytes is > 0x80 then we pad
|
||||
* with 0xff. However if the first byte is 0x80 and one of the following bytes
|
||||
* is non-zero we pad with 0xff. The reason for this distinction is that 0x80
|
||||
* followed by optional zeros isn't padded.
|
||||
*/
|
||||
|
||||
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
|
||||
{
|
||||
int pad = 0, ret, i, neg;
|
||||
unsigned char *p, *n, pb = 0;
|
||||
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
neg = a->type & V_ASN1_NEG;
|
||||
if (a->length == 0)
|
||||
ret = 1;
|
||||
else {
|
||||
ret = a->length;
|
||||
i = a->data[0];
|
||||
if (ret == 1 && i == 0)
|
||||
neg = 0;
|
||||
if (!neg && (i > 127)) {
|
||||
pad = 1;
|
||||
pb = 0;
|
||||
} else if (neg) {
|
||||
if (i > 128) {
|
||||
pad = 1;
|
||||
pb = 0xFF;
|
||||
} else if (i == 128) {
|
||||
/*
|
||||
* Special case: if any other bytes non zero we pad:
|
||||
* otherwise we don't.
|
||||
*/
|
||||
for (i = 1; i < a->length; i++)
|
||||
if (a->data[i]) {
|
||||
pad = 1;
|
||||
pb = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret += pad;
|
||||
}
|
||||
if (pp == NULL)
|
||||
return (ret);
|
||||
p = *pp;
|
||||
|
||||
if (pad)
|
||||
*(p++) = pb;
|
||||
if (a->length == 0)
|
||||
*(p++) = 0;
|
||||
else if (!neg)
|
||||
OPENSSL_memcpy(p, a->data, (unsigned int)a->length);
|
||||
else {
|
||||
/* Begin at the end of the encoding */
|
||||
n = a->data + a->length - 1;
|
||||
p += a->length - 1;
|
||||
i = a->length;
|
||||
/* Copy zeros to destination as long as source is zero */
|
||||
while (!*n && i > 1) {
|
||||
*(p--) = 0;
|
||||
n--;
|
||||
i--;
|
||||
}
|
||||
/* Complement and increment next octet */
|
||||
*(p--) = ((*(n--)) ^ 0xff) + 1;
|
||||
i--;
|
||||
/* Complement any octets left */
|
||||
for (; i > 0; i--)
|
||||
*(p--) = *(n--) ^ 0xff;
|
||||
}
|
||||
|
||||
*pp += ret;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
|
||||
|
||||
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
|
||||
long len)
|
||||
{
|
||||
ASN1_INTEGER *ret = NULL;
|
||||
const unsigned char *p, *pend;
|
||||
unsigned char *to, *s;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* This function can handle lengths up to INT_MAX - 1, but the rest of the
|
||||
* legacy ASN.1 code mixes integer types, so avoid exposing it to
|
||||
* ASN1_INTEGERS with larger lengths.
|
||||
*/
|
||||
if (len < 0 || len > INT_MAX / 2) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((a == NULL) || ((*a) == NULL)) {
|
||||
if ((ret = M_ASN1_INTEGER_new()) == NULL)
|
||||
return (NULL);
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
p = *pp;
|
||||
pend = p + len;
|
||||
|
||||
/*
|
||||
* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
|
||||
* a missing NULL parameter.
|
||||
*/
|
||||
s = (unsigned char *)OPENSSL_malloc((int)len + 1);
|
||||
if (s == NULL) {
|
||||
i = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
to = s;
|
||||
if (!len) {
|
||||
/*
|
||||
* Strictly speaking this is an illegal INTEGER but we tolerate it.
|
||||
*/
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
} else if (*p & 0x80) { /* a negative number */
|
||||
ret->type = V_ASN1_NEG_INTEGER;
|
||||
if ((*p == 0xff) && (len != 1)) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
i = len;
|
||||
p += i - 1;
|
||||
to += i - 1;
|
||||
while ((!*p) && i) {
|
||||
*(to--) = 0;
|
||||
i--;
|
||||
p--;
|
||||
}
|
||||
/*
|
||||
* Special case: if all zeros then the number will be of the form FF
|
||||
* followed by n zero bytes: this corresponds to 1 followed by n zero
|
||||
* bytes. We've already written n zeros so we just append an extra
|
||||
* one and set the first byte to a 1. This is treated separately
|
||||
* because it is the only case where the number of bytes is larger
|
||||
* than len.
|
||||
*/
|
||||
if (!i) {
|
||||
*s = 1;
|
||||
s[len] = 0;
|
||||
len++;
|
||||
} else {
|
||||
*(to--) = (*(p--) ^ 0xff) + 1;
|
||||
i--;
|
||||
for (; i > 0; i--)
|
||||
*(to--) = *(p--) ^ 0xff;
|
||||
}
|
||||
} else {
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
if ((*p == 0) && (len != 1)) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
OPENSSL_memcpy(s, p, (int)len);
|
||||
}
|
||||
|
||||
if (ret->data != NULL)
|
||||
OPENSSL_free(ret->data);
|
||||
ret->data = s;
|
||||
ret->length = (int)len;
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = pend;
|
||||
return (ret);
|
||||
err:
|
||||
OPENSSL_PUT_ERROR(ASN1, i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_INTEGER_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
|
||||
{
|
||||
if (v >= 0) {
|
||||
return ASN1_INTEGER_set_uint64(a, (uint64_t) v);
|
||||
}
|
||||
|
||||
if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t) v)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
a->type = V_ASN1_NEG_INTEGER;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v)
|
||||
{
|
||||
uint8_t *const newdata = OPENSSL_malloc(sizeof(uint64_t));
|
||||
if (newdata == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
OPENSSL_free(out->data);
|
||||
out->data = newdata;
|
||||
v = CRYPTO_bswap8(v);
|
||||
memcpy(out->data, &v, sizeof(v));
|
||||
|
||||
out->type = V_ASN1_INTEGER;
|
||||
|
||||
size_t leading_zeros;
|
||||
for (leading_zeros = 0; leading_zeros < sizeof(uint64_t) - 1;
|
||||
leading_zeros++) {
|
||||
if (out->data[leading_zeros] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out->length = sizeof(uint64_t) - leading_zeros;
|
||||
OPENSSL_memmove(out->data, out->data + leading_zeros, out->length);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
|
||||
{
|
||||
int neg = 0, i;
|
||||
|
||||
if (a == NULL)
|
||||
return (0L);
|
||||
i = a->type;
|
||||
if (i == V_ASN1_NEG_INTEGER)
|
||||
neg = 1;
|
||||
else if (i != V_ASN1_INTEGER)
|
||||
return -1;
|
||||
|
||||
OPENSSL_STATIC_ASSERT(sizeof(uint64_t) >= sizeof(long),
|
||||
"long larger than uint64_t");
|
||||
|
||||
if (a->length > (int)sizeof(uint64_t)) {
|
||||
/* hmm... a bit ugly, return all ones */
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t r64 = 0;
|
||||
if (a->data != NULL) {
|
||||
for (i = 0; i < a->length; i++) {
|
||||
r64 <<= 8;
|
||||
r64 |= (unsigned char)a->data[i];
|
||||
}
|
||||
|
||||
if (r64 > LONG_MAX) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long r = (long) r64;
|
||||
if (neg)
|
||||
r = -r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
|
||||
{
|
||||
ASN1_INTEGER *ret;
|
||||
int len, j;
|
||||
|
||||
if (ai == NULL)
|
||||
ret = M_ASN1_INTEGER_new();
|
||||
else
|
||||
ret = ai;
|
||||
if (ret == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_negative(bn) && !BN_is_zero(bn))
|
||||
ret->type = V_ASN1_NEG_INTEGER;
|
||||
else
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
j = BN_num_bits(bn);
|
||||
len = ((j == 0) ? 0 : ((j / 8) + 1));
|
||||
if (ret->length < len + 4) {
|
||||
unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
|
||||
if (!new_data) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ret->data = new_data;
|
||||
}
|
||||
ret->length = BN_bn2bin(bn, ret->data);
|
||||
/* Correct zero case */
|
||||
if (!ret->length) {
|
||||
ret->data[0] = 0;
|
||||
ret->length = 1;
|
||||
}
|
||||
return (ret);
|
||||
err:
|
||||
if (ret != ai)
|
||||
M_ASN1_INTEGER_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
|
||||
{
|
||||
BIGNUM *ret;
|
||||
|
||||
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
|
||||
else if (ai->type == V_ASN1_NEG_INTEGER)
|
||||
BN_set_negative(ret, 1);
|
||||
return (ret);
|
||||
}
|
||||
-420
@@ -1,420 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
|
||||
{
|
||||
return M_ASN1_INTEGER_dup(x);
|
||||
}
|
||||
|
||||
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
|
||||
{
|
||||
int neg, ret;
|
||||
/* Compare signs */
|
||||
neg = x->type & V_ASN1_NEG;
|
||||
if (neg != (y->type & V_ASN1_NEG)) {
|
||||
if (neg)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = ASN1_STRING_cmp(x, y);
|
||||
|
||||
if (neg)
|
||||
return -ret;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This converts an ASN1 INTEGER into its content encoding.
|
||||
* The internal representation is an ASN1_STRING whose data is a big endian
|
||||
* representation of the value, ignoring the sign. The sign is determined by
|
||||
* the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
|
||||
*
|
||||
* Positive integers are no problem: they are almost the same as the DER
|
||||
* encoding, except if the first byte is >= 0x80 we need to add a zero pad.
|
||||
*
|
||||
* Negative integers are a bit trickier...
|
||||
* The DER representation of negative integers is in 2s complement form.
|
||||
* The internal form is converted by complementing each octet and finally
|
||||
* adding one to the result. This can be done less messily with a little trick.
|
||||
* If the internal form has trailing zeroes then they will become FF by the
|
||||
* complement and 0 by the add one (due to carry) so just copy as many trailing
|
||||
* zeros to the destination as there are in the source. The carry will add one
|
||||
* to the last none zero octet: so complement this octet and add one and finally
|
||||
* complement any left over until you get to the start of the string.
|
||||
*
|
||||
* Padding is a little trickier too. If the first bytes is > 0x80 then we pad
|
||||
* with 0xff. However if the first byte is 0x80 and one of the following bytes
|
||||
* is non-zero we pad with 0xff. The reason for this distinction is that 0x80
|
||||
* followed by optional zeros isn't padded.
|
||||
*/
|
||||
|
||||
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
|
||||
{
|
||||
int pad = 0, ret, i, neg;
|
||||
unsigned char *p, *n, pb = 0;
|
||||
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
neg = a->type & V_ASN1_NEG;
|
||||
if (a->length == 0)
|
||||
ret = 1;
|
||||
else {
|
||||
ret = a->length;
|
||||
i = a->data[0];
|
||||
if (ret == 1 && i == 0)
|
||||
neg = 0;
|
||||
if (!neg && (i > 127)) {
|
||||
pad = 1;
|
||||
pb = 0;
|
||||
} else if (neg) {
|
||||
if (i > 128) {
|
||||
pad = 1;
|
||||
pb = 0xFF;
|
||||
} else if (i == 128) {
|
||||
/*
|
||||
* Special case: if any other bytes non zero we pad:
|
||||
* otherwise we don't.
|
||||
*/
|
||||
for (i = 1; i < a->length; i++)
|
||||
if (a->data[i]) {
|
||||
pad = 1;
|
||||
pb = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret += pad;
|
||||
}
|
||||
if (pp == NULL)
|
||||
return (ret);
|
||||
p = *pp;
|
||||
|
||||
if (pad)
|
||||
*(p++) = pb;
|
||||
if (a->length == 0)
|
||||
*(p++) = 0;
|
||||
else if (!neg)
|
||||
OPENSSL_memcpy(p, a->data, (unsigned int)a->length);
|
||||
else {
|
||||
/* Begin at the end of the encoding */
|
||||
n = a->data + a->length - 1;
|
||||
p += a->length - 1;
|
||||
i = a->length;
|
||||
/* Copy zeros to destination as long as source is zero */
|
||||
while (!*n && i > 1) {
|
||||
*(p--) = 0;
|
||||
n--;
|
||||
i--;
|
||||
}
|
||||
/* Complement and increment next octet */
|
||||
*(p--) = ((*(n--)) ^ 0xff) + 1;
|
||||
i--;
|
||||
/* Complement any octets left */
|
||||
for (; i > 0; i--)
|
||||
*(p--) = *(n--) ^ 0xff;
|
||||
}
|
||||
|
||||
*pp += ret;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
|
||||
|
||||
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
|
||||
long len)
|
||||
{
|
||||
ASN1_INTEGER *ret = NULL;
|
||||
const unsigned char *p, *pend;
|
||||
unsigned char *to, *s;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* This function can handle lengths up to INT_MAX - 1, but the rest of the
|
||||
* legacy ASN.1 code mixes integer types, so avoid exposing it to
|
||||
* ASN1_INTEGERS with larger lengths.
|
||||
*/
|
||||
if (len < 0 || len > INT_MAX / 2) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((a == NULL) || ((*a) == NULL)) {
|
||||
if ((ret = M_ASN1_INTEGER_new()) == NULL)
|
||||
return (NULL);
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
p = *pp;
|
||||
pend = p + len;
|
||||
|
||||
/*
|
||||
* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
|
||||
* a missing NULL parameter.
|
||||
*/
|
||||
s = (unsigned char *)OPENSSL_malloc((int)len + 1);
|
||||
if (s == NULL) {
|
||||
i = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
to = s;
|
||||
if (!len) {
|
||||
/*
|
||||
* Strictly speaking this is an illegal INTEGER but we tolerate it.
|
||||
*/
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
} else if (*p & 0x80) { /* a negative number */
|
||||
ret->type = V_ASN1_NEG_INTEGER;
|
||||
if ((*p == 0xff) && (len != 1)) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
i = len;
|
||||
p += i - 1;
|
||||
to += i - 1;
|
||||
while ((!*p) && i) {
|
||||
*(to--) = 0;
|
||||
i--;
|
||||
p--;
|
||||
}
|
||||
/*
|
||||
* Special case: if all zeros then the number will be of the form FF
|
||||
* followed by n zero bytes: this corresponds to 1 followed by n zero
|
||||
* bytes. We've already written n zeros so we just append an extra
|
||||
* one and set the first byte to a 1. This is treated separately
|
||||
* because it is the only case where the number of bytes is larger
|
||||
* than len.
|
||||
*/
|
||||
if (!i) {
|
||||
*s = 1;
|
||||
s[len] = 0;
|
||||
len++;
|
||||
} else {
|
||||
*(to--) = (*(p--) ^ 0xff) + 1;
|
||||
i--;
|
||||
for (; i > 0; i--)
|
||||
*(to--) = *(p--) ^ 0xff;
|
||||
}
|
||||
} else {
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
if ((*p == 0) && (len != 1)) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
OPENSSL_memcpy(s, p, (int)len);
|
||||
}
|
||||
|
||||
if (ret->data != NULL)
|
||||
OPENSSL_free(ret->data);
|
||||
ret->data = s;
|
||||
ret->length = (int)len;
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = pend;
|
||||
return (ret);
|
||||
err:
|
||||
OPENSSL_PUT_ERROR(ASN1, i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_INTEGER_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
|
||||
{
|
||||
if (v >= 0) {
|
||||
return ASN1_INTEGER_set_uint64(a, (uint64_t) v);
|
||||
}
|
||||
|
||||
if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t) v)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
a->type = V_ASN1_NEG_INTEGER;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v)
|
||||
{
|
||||
uint8_t *const newdata = OPENSSL_malloc(sizeof(uint64_t));
|
||||
if (newdata == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
OPENSSL_free(out->data);
|
||||
out->data = newdata;
|
||||
v = CRYPTO_bswap8(v);
|
||||
memcpy(out->data, &v, sizeof(v));
|
||||
|
||||
out->type = V_ASN1_INTEGER;
|
||||
|
||||
size_t leading_zeros;
|
||||
for (leading_zeros = 0; leading_zeros < sizeof(uint64_t) - 1;
|
||||
leading_zeros++) {
|
||||
if (out->data[leading_zeros] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out->length = sizeof(uint64_t) - leading_zeros;
|
||||
OPENSSL_memmove(out->data, out->data + leading_zeros, out->length);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
|
||||
{
|
||||
int neg = 0, i;
|
||||
|
||||
if (a == NULL)
|
||||
return (0L);
|
||||
i = a->type;
|
||||
if (i == V_ASN1_NEG_INTEGER)
|
||||
neg = 1;
|
||||
else if (i != V_ASN1_INTEGER)
|
||||
return -1;
|
||||
|
||||
OPENSSL_STATIC_ASSERT(sizeof(uint64_t) >= sizeof(long),
|
||||
"long larger than uint64_t");
|
||||
|
||||
if (a->length > (int)sizeof(uint64_t)) {
|
||||
/* hmm... a bit ugly, return all ones */
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t r64 = 0;
|
||||
if (a->data != NULL) {
|
||||
for (i = 0; i < a->length; i++) {
|
||||
r64 <<= 8;
|
||||
r64 |= (unsigned char)a->data[i];
|
||||
}
|
||||
|
||||
if (r64 > LONG_MAX) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
long r = (long) r64;
|
||||
if (neg)
|
||||
r = -r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
|
||||
{
|
||||
ASN1_INTEGER *ret;
|
||||
int len, j;
|
||||
|
||||
if (ai == NULL)
|
||||
ret = M_ASN1_INTEGER_new();
|
||||
else
|
||||
ret = ai;
|
||||
if (ret == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_negative(bn) && !BN_is_zero(bn))
|
||||
ret->type = V_ASN1_NEG_INTEGER;
|
||||
else
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
j = BN_num_bits(bn);
|
||||
len = ((j == 0) ? 0 : ((j / 8) + 1));
|
||||
if (ret->length < len + 4) {
|
||||
unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
|
||||
if (!new_data) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ret->data = new_data;
|
||||
}
|
||||
ret->length = BN_bn2bin(bn, ret->data);
|
||||
/* Correct zero case */
|
||||
if (!ret->length) {
|
||||
ret->data[0] = 0;
|
||||
ret->length = 1;
|
||||
}
|
||||
return (ret);
|
||||
err:
|
||||
if (ret != ai)
|
||||
M_ASN1_INTEGER_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
|
||||
{
|
||||
BIGNUM *ret;
|
||||
|
||||
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
|
||||
else if (ai->type == V_ASN1_NEG_INTEGER)
|
||||
BN_set_negative(ret, 1);
|
||||
return (ret);
|
||||
}
|
||||
-305
@@ -1,305 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl_grpc/bytestring.h>
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
#include "asn1_locl.h"
|
||||
#include "../bytestring/internal.h"
|
||||
|
||||
static int is_printable(uint32_t value);
|
||||
|
||||
/*
|
||||
* These functions take a string in UTF8, ASCII or multibyte form and a mask
|
||||
* of permissible ASN1 string types. It then works out the minimal type
|
||||
* (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and
|
||||
* creates a string of the correct type with the supplied data. Yes this is
|
||||
* horrible: it has to be :-( The 'ncopy' form checks minimum and maximum
|
||||
* size limits too.
|
||||
*/
|
||||
|
||||
int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
|
||||
int inform, unsigned long mask)
|
||||
{
|
||||
return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
|
||||
}
|
||||
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_BMPSTRING)
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_UNIVERSALSTRING)
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_UTF8STRING)
|
||||
|
||||
int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
|
||||
int inform, unsigned long mask,
|
||||
long minsize, long maxsize)
|
||||
{
|
||||
int str_type;
|
||||
char free_out;
|
||||
ASN1_STRING *dest;
|
||||
size_t nchar = 0;
|
||||
char strbuf[32];
|
||||
if (len == -1)
|
||||
len = strlen((const char *)in);
|
||||
if (!mask)
|
||||
mask = DIRSTRING_TYPE;
|
||||
|
||||
int (*decode_func)(CBS *, uint32_t*);
|
||||
int error;
|
||||
switch (inform) {
|
||||
case MBSTRING_BMP:
|
||||
decode_func = cbs_get_ucs2_be;
|
||||
error = ASN1_R_INVALID_BMPSTRING;
|
||||
break;
|
||||
|
||||
case MBSTRING_UNIV:
|
||||
decode_func = cbs_get_utf32_be;
|
||||
error = ASN1_R_INVALID_UNIVERSALSTRING;
|
||||
break;
|
||||
|
||||
case MBSTRING_UTF8:
|
||||
decode_func = cbs_get_utf8;
|
||||
error = ASN1_R_INVALID_UTF8STRING;
|
||||
break;
|
||||
|
||||
case MBSTRING_ASC:
|
||||
decode_func = cbs_get_latin1;
|
||||
error = ERR_R_INTERNAL_ERROR; // Latin-1 inputs are never invalid.
|
||||
break;
|
||||
|
||||
default:
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check |minsize| and |maxsize| and work out the minimal type, if any. */
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, in, len);
|
||||
size_t utf8_len = 0;
|
||||
while (CBS_len(&cbs) != 0) {
|
||||
uint32_t c;
|
||||
if (!decode_func(&cbs, &c)) {
|
||||
OPENSSL_PUT_ERROR(ASN1, error);
|
||||
return -1;
|
||||
}
|
||||
if (nchar == 0 &&
|
||||
(inform == MBSTRING_BMP || inform == MBSTRING_UNIV) &&
|
||||
c == 0xfeff) {
|
||||
/* Reject byte-order mark. We could drop it but that would mean
|
||||
* adding ambiguity around whether a BOM was included or not when
|
||||
* matching strings.
|
||||
*
|
||||
* For a little-endian UCS-2 string, the BOM will appear as 0xfffe
|
||||
* and will be rejected as noncharacter, below. */
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Update which output formats are still possible. */
|
||||
if ((mask & B_ASN1_PRINTABLESTRING) && !is_printable(c)) {
|
||||
mask &= ~B_ASN1_PRINTABLESTRING;
|
||||
}
|
||||
if ((mask & B_ASN1_IA5STRING) && (c > 127)) {
|
||||
mask &= ~B_ASN1_IA5STRING;
|
||||
}
|
||||
if ((mask & B_ASN1_T61STRING) && (c > 0xff)) {
|
||||
mask &= ~B_ASN1_T61STRING;
|
||||
}
|
||||
if ((mask & B_ASN1_BMPSTRING) && (c > 0xffff)) {
|
||||
mask &= ~B_ASN1_BMPSTRING;
|
||||
}
|
||||
if (!mask) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nchar++;
|
||||
utf8_len += cbb_get_utf8_len(c);
|
||||
}
|
||||
|
||||
if (minsize > 0 && nchar < (size_t)minsize) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
|
||||
BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
|
||||
ERR_add_error_data(2, "minsize=", strbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (maxsize > 0 && nchar > (size_t)maxsize) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
|
||||
BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
|
||||
ERR_add_error_data(2, "maxsize=", strbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now work out output format and string type */
|
||||
int (*encode_func)(CBB *, uint32_t) = cbb_add_latin1;
|
||||
size_t size_estimate = nchar;
|
||||
int outform = MBSTRING_ASC;
|
||||
if (mask & B_ASN1_PRINTABLESTRING) {
|
||||
str_type = V_ASN1_PRINTABLESTRING;
|
||||
} else if (mask & B_ASN1_IA5STRING) {
|
||||
str_type = V_ASN1_IA5STRING;
|
||||
} else if (mask & B_ASN1_T61STRING) {
|
||||
str_type = V_ASN1_T61STRING;
|
||||
} else if (mask & B_ASN1_BMPSTRING) {
|
||||
str_type = V_ASN1_BMPSTRING;
|
||||
outform = MBSTRING_BMP;
|
||||
encode_func = cbb_add_ucs2_be;
|
||||
size_estimate = 2 * nchar;
|
||||
} else if (mask & B_ASN1_UNIVERSALSTRING) {
|
||||
str_type = V_ASN1_UNIVERSALSTRING;
|
||||
encode_func = cbb_add_utf32_be;
|
||||
size_estimate = 4 * nchar;
|
||||
outform = MBSTRING_UNIV;
|
||||
} else {
|
||||
str_type = V_ASN1_UTF8STRING;
|
||||
outform = MBSTRING_UTF8;
|
||||
encode_func = cbb_add_utf8;
|
||||
size_estimate = utf8_len;
|
||||
}
|
||||
|
||||
if (!out)
|
||||
return str_type;
|
||||
if (*out) {
|
||||
free_out = 0;
|
||||
dest = *out;
|
||||
if (dest->data) {
|
||||
dest->length = 0;
|
||||
OPENSSL_free(dest->data);
|
||||
dest->data = NULL;
|
||||
}
|
||||
dest->type = str_type;
|
||||
} else {
|
||||
free_out = 1;
|
||||
dest = ASN1_STRING_type_new(str_type);
|
||||
if (!dest) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
*out = dest;
|
||||
}
|
||||
|
||||
/* If both the same type just copy across */
|
||||
if (inform == outform) {
|
||||
if (!ASN1_STRING_set(dest, in, len)) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
return str_type;
|
||||
}
|
||||
|
||||
CBB cbb;
|
||||
if (!CBB_init(&cbb, size_estimate + 1)) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
CBS_init(&cbs, in, len);
|
||||
while (CBS_len(&cbs) != 0) {
|
||||
uint32_t c;
|
||||
if (!decode_func(&cbs, &c) ||
|
||||
!encode_func(&cbb, c)) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
uint8_t *data = NULL;
|
||||
size_t data_len;
|
||||
if (/* OpenSSL historically NUL-terminated this value with a single byte,
|
||||
* even for |MBSTRING_BMP| and |MBSTRING_UNIV|. */
|
||||
!CBB_add_u8(&cbb, 0) ||
|
||||
!CBB_finish(&cbb, &data, &data_len) ||
|
||||
data_len < 1 ||
|
||||
data_len > INT_MAX) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_free(data);
|
||||
goto err;
|
||||
}
|
||||
dest->length = (int)(data_len - 1);
|
||||
dest->data = data;
|
||||
return str_type;
|
||||
|
||||
err:
|
||||
if (free_out)
|
||||
ASN1_STRING_free(dest);
|
||||
CBB_cleanup(&cbb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return 1 if the character is permitted in a PrintableString */
|
||||
static int is_printable(uint32_t value)
|
||||
{
|
||||
int ch;
|
||||
if (value > 0x7f)
|
||||
return 0;
|
||||
ch = (int)value;
|
||||
/*
|
||||
* Note: we can't use 'isalnum' because certain accented characters may
|
||||
* count as alphanumeric in some environments.
|
||||
*/
|
||||
if ((ch >= 'a') && (ch <= 'z'))
|
||||
return 1;
|
||||
if ((ch >= 'A') && (ch <= 'Z'))
|
||||
return 1;
|
||||
if ((ch >= '0') && (ch <= '9'))
|
||||
return 1;
|
||||
if ((ch == ' ') || strchr("'()+,-./:=?", ch))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
-305
@@ -1,305 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "asn1_locl.h"
|
||||
#include "../bytestring/internal.h"
|
||||
|
||||
static int is_printable(uint32_t value);
|
||||
|
||||
/*
|
||||
* These functions take a string in UTF8, ASCII or multibyte form and a mask
|
||||
* of permissible ASN1 string types. It then works out the minimal type
|
||||
* (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and
|
||||
* creates a string of the correct type with the supplied data. Yes this is
|
||||
* horrible: it has to be :-( The 'ncopy' form checks minimum and maximum
|
||||
* size limits too.
|
||||
*/
|
||||
|
||||
int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
|
||||
int inform, unsigned long mask)
|
||||
{
|
||||
return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
|
||||
}
|
||||
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_BMPSTRING)
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_UNIVERSALSTRING)
|
||||
OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_UTF8STRING)
|
||||
|
||||
int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
|
||||
int inform, unsigned long mask,
|
||||
long minsize, long maxsize)
|
||||
{
|
||||
int str_type;
|
||||
char free_out;
|
||||
ASN1_STRING *dest;
|
||||
size_t nchar = 0;
|
||||
char strbuf[32];
|
||||
if (len == -1)
|
||||
len = strlen((const char *)in);
|
||||
if (!mask)
|
||||
mask = DIRSTRING_TYPE;
|
||||
|
||||
int (*decode_func)(CBS *, uint32_t*);
|
||||
int error;
|
||||
switch (inform) {
|
||||
case MBSTRING_BMP:
|
||||
decode_func = cbs_get_ucs2_be;
|
||||
error = ASN1_R_INVALID_BMPSTRING;
|
||||
break;
|
||||
|
||||
case MBSTRING_UNIV:
|
||||
decode_func = cbs_get_utf32_be;
|
||||
error = ASN1_R_INVALID_UNIVERSALSTRING;
|
||||
break;
|
||||
|
||||
case MBSTRING_UTF8:
|
||||
decode_func = cbs_get_utf8;
|
||||
error = ASN1_R_INVALID_UTF8STRING;
|
||||
break;
|
||||
|
||||
case MBSTRING_ASC:
|
||||
decode_func = cbs_get_latin1;
|
||||
error = ERR_R_INTERNAL_ERROR; // Latin-1 inputs are never invalid.
|
||||
break;
|
||||
|
||||
default:
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check |minsize| and |maxsize| and work out the minimal type, if any. */
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, in, len);
|
||||
size_t utf8_len = 0;
|
||||
while (CBS_len(&cbs) != 0) {
|
||||
uint32_t c;
|
||||
if (!decode_func(&cbs, &c)) {
|
||||
OPENSSL_PUT_ERROR(ASN1, error);
|
||||
return -1;
|
||||
}
|
||||
if (nchar == 0 &&
|
||||
(inform == MBSTRING_BMP || inform == MBSTRING_UNIV) &&
|
||||
c == 0xfeff) {
|
||||
/* Reject byte-order mark. We could drop it but that would mean
|
||||
* adding ambiguity around whether a BOM was included or not when
|
||||
* matching strings.
|
||||
*
|
||||
* For a little-endian UCS-2 string, the BOM will appear as 0xfffe
|
||||
* and will be rejected as noncharacter, below. */
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Update which output formats are still possible. */
|
||||
if ((mask & B_ASN1_PRINTABLESTRING) && !is_printable(c)) {
|
||||
mask &= ~B_ASN1_PRINTABLESTRING;
|
||||
}
|
||||
if ((mask & B_ASN1_IA5STRING) && (c > 127)) {
|
||||
mask &= ~B_ASN1_IA5STRING;
|
||||
}
|
||||
if ((mask & B_ASN1_T61STRING) && (c > 0xff)) {
|
||||
mask &= ~B_ASN1_T61STRING;
|
||||
}
|
||||
if ((mask & B_ASN1_BMPSTRING) && (c > 0xffff)) {
|
||||
mask &= ~B_ASN1_BMPSTRING;
|
||||
}
|
||||
if (!mask) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nchar++;
|
||||
utf8_len += cbb_get_utf8_len(c);
|
||||
}
|
||||
|
||||
if (minsize > 0 && nchar < (size_t)minsize) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
|
||||
BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
|
||||
ERR_add_error_data(2, "minsize=", strbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (maxsize > 0 && nchar > (size_t)maxsize) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
|
||||
BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
|
||||
ERR_add_error_data(2, "maxsize=", strbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now work out output format and string type */
|
||||
int (*encode_func)(CBB *, uint32_t) = cbb_add_latin1;
|
||||
size_t size_estimate = nchar;
|
||||
int outform = MBSTRING_ASC;
|
||||
if (mask & B_ASN1_PRINTABLESTRING) {
|
||||
str_type = V_ASN1_PRINTABLESTRING;
|
||||
} else if (mask & B_ASN1_IA5STRING) {
|
||||
str_type = V_ASN1_IA5STRING;
|
||||
} else if (mask & B_ASN1_T61STRING) {
|
||||
str_type = V_ASN1_T61STRING;
|
||||
} else if (mask & B_ASN1_BMPSTRING) {
|
||||
str_type = V_ASN1_BMPSTRING;
|
||||
outform = MBSTRING_BMP;
|
||||
encode_func = cbb_add_ucs2_be;
|
||||
size_estimate = 2 * nchar;
|
||||
} else if (mask & B_ASN1_UNIVERSALSTRING) {
|
||||
str_type = V_ASN1_UNIVERSALSTRING;
|
||||
encode_func = cbb_add_utf32_be;
|
||||
size_estimate = 4 * nchar;
|
||||
outform = MBSTRING_UNIV;
|
||||
} else {
|
||||
str_type = V_ASN1_UTF8STRING;
|
||||
outform = MBSTRING_UTF8;
|
||||
encode_func = cbb_add_utf8;
|
||||
size_estimate = utf8_len;
|
||||
}
|
||||
|
||||
if (!out)
|
||||
return str_type;
|
||||
if (*out) {
|
||||
free_out = 0;
|
||||
dest = *out;
|
||||
if (dest->data) {
|
||||
dest->length = 0;
|
||||
OPENSSL_free(dest->data);
|
||||
dest->data = NULL;
|
||||
}
|
||||
dest->type = str_type;
|
||||
} else {
|
||||
free_out = 1;
|
||||
dest = ASN1_STRING_type_new(str_type);
|
||||
if (!dest) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
*out = dest;
|
||||
}
|
||||
|
||||
/* If both the same type just copy across */
|
||||
if (inform == outform) {
|
||||
if (!ASN1_STRING_set(dest, in, len)) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
return str_type;
|
||||
}
|
||||
|
||||
CBB cbb;
|
||||
if (!CBB_init(&cbb, size_estimate + 1)) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
CBS_init(&cbs, in, len);
|
||||
while (CBS_len(&cbs) != 0) {
|
||||
uint32_t c;
|
||||
if (!decode_func(&cbs, &c) ||
|
||||
!encode_func(&cbb, c)) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
uint8_t *data = NULL;
|
||||
size_t data_len;
|
||||
if (/* OpenSSL historically NUL-terminated this value with a single byte,
|
||||
* even for |MBSTRING_BMP| and |MBSTRING_UNIV|. */
|
||||
!CBB_add_u8(&cbb, 0) ||
|
||||
!CBB_finish(&cbb, &data, &data_len) ||
|
||||
data_len < 1 ||
|
||||
data_len > INT_MAX) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_free(data);
|
||||
goto err;
|
||||
}
|
||||
dest->length = (int)(data_len - 1);
|
||||
dest->data = data;
|
||||
return str_type;
|
||||
|
||||
err:
|
||||
if (free_out)
|
||||
ASN1_STRING_free(dest);
|
||||
CBB_cleanup(&cbb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return 1 if the character is permitted in a PrintableString */
|
||||
static int is_printable(uint32_t value)
|
||||
{
|
||||
int ch;
|
||||
if (value > 0x7f)
|
||||
return 0;
|
||||
ch = (int)value;
|
||||
/*
|
||||
* Note: we can't use 'isalnum' because certain accented characters may
|
||||
* count as alphanumeric in some environments.
|
||||
*/
|
||||
if ((ch >= 'a') && (ch <= 'z'))
|
||||
return 1;
|
||||
if ((ch >= 'A') && (ch <= 'Z'))
|
||||
return 1;
|
||||
if ((ch >= '0') && (ch <= '9'))
|
||||
return 1;
|
||||
if ((ch == ' ') || strchr("'()+,-./:=?", ch))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
-286
@@ -1,286 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
#include <openssl_grpc/obj.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
|
||||
{
|
||||
unsigned char *p, *allocated = NULL;
|
||||
int objsize;
|
||||
|
||||
if ((a == NULL) || (a->data == NULL))
|
||||
return (0);
|
||||
|
||||
objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
|
||||
if (pp == NULL || objsize == -1)
|
||||
return objsize;
|
||||
|
||||
if (*pp == NULL) {
|
||||
if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
p = *pp;
|
||||
}
|
||||
|
||||
ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
|
||||
OPENSSL_memcpy(p, a->data, a->length);
|
||||
|
||||
/*
|
||||
* If a new buffer was allocated, just return it back.
|
||||
* If not, return the incremented buffer pointer.
|
||||
*/
|
||||
*pp = allocated != NULL ? allocated : p + a->length;
|
||||
return objsize;
|
||||
}
|
||||
|
||||
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
|
||||
{
|
||||
return OBJ_obj2txt(buf, buf_len, a, 0);
|
||||
}
|
||||
|
||||
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
|
||||
{
|
||||
char buf[80], *p = buf;
|
||||
int i;
|
||||
|
||||
if ((a == NULL) || (a->data == NULL))
|
||||
return (BIO_write(bp, "NULL", 4));
|
||||
i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
|
||||
if (i > (int)(sizeof(buf) - 1)) {
|
||||
p = OPENSSL_malloc(i + 1);
|
||||
if (!p)
|
||||
return -1;
|
||||
i2t_ASN1_OBJECT(p, i + 1, a);
|
||||
}
|
||||
if (i <= 0)
|
||||
return BIO_write(bp, "<INVALID>", 9);
|
||||
BIO_write(bp, p, i);
|
||||
if (p != buf)
|
||||
OPENSSL_free(p);
|
||||
return (i);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
|
||||
long length)
|
||||
{
|
||||
const unsigned char *p;
|
||||
long len;
|
||||
int tag, xclass;
|
||||
int inf, i;
|
||||
ASN1_OBJECT *ret = NULL;
|
||||
p = *pp;
|
||||
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
|
||||
if (inf & 0x80) {
|
||||
i = ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tag != V_ASN1_OBJECT) {
|
||||
i = ASN1_R_EXPECTING_AN_OBJECT;
|
||||
goto err;
|
||||
}
|
||||
ret = c2i_ASN1_OBJECT(a, &p, len);
|
||||
if (ret)
|
||||
*pp = p;
|
||||
return ret;
|
||||
err:
|
||||
OPENSSL_PUT_ERROR(ASN1, i);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
|
||||
long len)
|
||||
{
|
||||
ASN1_OBJECT *ret = NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *data;
|
||||
int i, length;
|
||||
|
||||
/*
|
||||
* Sanity check OID encoding. Need at least one content octet. MSB must
|
||||
* be clear in the last octet. can't have leading 0x80 in subidentifiers,
|
||||
* see: X.690 8.19.2
|
||||
*/
|
||||
if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
|
||||
p[len - 1] & 0x80) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
|
||||
return NULL;
|
||||
}
|
||||
/* Now 0 < len <= INT_MAX, so the cast is safe. */
|
||||
length = (int)len;
|
||||
for (i = 0; i < length; i++, p++) {
|
||||
if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* only the ASN1_OBJECTs from the 'table' will have values for ->sn or
|
||||
* ->ln
|
||||
*/
|
||||
if ((a == NULL) || ((*a) == NULL) ||
|
||||
!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
|
||||
if ((ret = ASN1_OBJECT_new()) == NULL)
|
||||
return (NULL);
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
p = *pp;
|
||||
/* detach data from object */
|
||||
data = (unsigned char *)ret->data;
|
||||
ret->data = NULL;
|
||||
/* once detached we can change it */
|
||||
if ((data == NULL) || (ret->length < length)) {
|
||||
ret->length = 0;
|
||||
if (data != NULL)
|
||||
OPENSSL_free(data);
|
||||
data = (unsigned char *)OPENSSL_malloc(length);
|
||||
if (data == NULL) {
|
||||
i = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
|
||||
}
|
||||
OPENSSL_memcpy(data, p, length);
|
||||
/* reattach data to object, after which it remains const */
|
||||
ret->data = data;
|
||||
ret->length = length;
|
||||
ret->sn = NULL;
|
||||
ret->ln = NULL;
|
||||
/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
|
||||
p += length;
|
||||
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
OPENSSL_PUT_ERROR(ASN1, i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
ASN1_OBJECT_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *ASN1_OBJECT_new(void)
|
||||
{
|
||||
ASN1_OBJECT *ret;
|
||||
|
||||
ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
|
||||
if (ret == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
ret->length = 0;
|
||||
ret->data = NULL;
|
||||
ret->nid = 0;
|
||||
ret->sn = NULL;
|
||||
ret->ln = NULL;
|
||||
ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void ASN1_OBJECT_free(ASN1_OBJECT *a)
|
||||
{
|
||||
if (a == NULL)
|
||||
return;
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
|
||||
#ifndef CONST_STRICT /* disable purely for compile-time strict
|
||||
* const checking. Doing this on a "real"
|
||||
* compile will cause memory leaks */
|
||||
if (a->sn != NULL)
|
||||
OPENSSL_free((void *)a->sn);
|
||||
if (a->ln != NULL)
|
||||
OPENSSL_free((void *)a->ln);
|
||||
#endif
|
||||
a->sn = a->ln = NULL;
|
||||
}
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
|
||||
if (a->data != NULL)
|
||||
OPENSSL_free((void *)a->data);
|
||||
a->data = NULL;
|
||||
a->length = 0;
|
||||
}
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
|
||||
OPENSSL_free(a);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
|
||||
const char *sn, const char *ln)
|
||||
{
|
||||
ASN1_OBJECT o;
|
||||
|
||||
o.sn = sn;
|
||||
o.ln = ln;
|
||||
o.data = data;
|
||||
o.nid = nid;
|
||||
o.length = len;
|
||||
o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
|
||||
ASN1_OBJECT_FLAG_DYNAMIC_DATA;
|
||||
return (OBJ_dup(&o));
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/obj.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
|
||||
{
|
||||
unsigned char *p, *allocated = NULL;
|
||||
int objsize;
|
||||
|
||||
if ((a == NULL) || (a->data == NULL))
|
||||
return (0);
|
||||
|
||||
objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
|
||||
if (pp == NULL || objsize == -1)
|
||||
return objsize;
|
||||
|
||||
if (*pp == NULL) {
|
||||
if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
p = *pp;
|
||||
}
|
||||
|
||||
ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
|
||||
OPENSSL_memcpy(p, a->data, a->length);
|
||||
|
||||
/*
|
||||
* If a new buffer was allocated, just return it back.
|
||||
* If not, return the incremented buffer pointer.
|
||||
*/
|
||||
*pp = allocated != NULL ? allocated : p + a->length;
|
||||
return objsize;
|
||||
}
|
||||
|
||||
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
|
||||
{
|
||||
return OBJ_obj2txt(buf, buf_len, a, 0);
|
||||
}
|
||||
|
||||
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
|
||||
{
|
||||
char buf[80], *p = buf;
|
||||
int i;
|
||||
|
||||
if ((a == NULL) || (a->data == NULL))
|
||||
return (BIO_write(bp, "NULL", 4));
|
||||
i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
|
||||
if (i > (int)(sizeof(buf) - 1)) {
|
||||
p = OPENSSL_malloc(i + 1);
|
||||
if (!p)
|
||||
return -1;
|
||||
i2t_ASN1_OBJECT(p, i + 1, a);
|
||||
}
|
||||
if (i <= 0)
|
||||
return BIO_write(bp, "<INVALID>", 9);
|
||||
BIO_write(bp, p, i);
|
||||
if (p != buf)
|
||||
OPENSSL_free(p);
|
||||
return (i);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
|
||||
long length)
|
||||
{
|
||||
const unsigned char *p;
|
||||
long len;
|
||||
int tag, xclass;
|
||||
int inf, i;
|
||||
ASN1_OBJECT *ret = NULL;
|
||||
p = *pp;
|
||||
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
|
||||
if (inf & 0x80) {
|
||||
i = ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tag != V_ASN1_OBJECT) {
|
||||
i = ASN1_R_EXPECTING_AN_OBJECT;
|
||||
goto err;
|
||||
}
|
||||
ret = c2i_ASN1_OBJECT(a, &p, len);
|
||||
if (ret)
|
||||
*pp = p;
|
||||
return ret;
|
||||
err:
|
||||
OPENSSL_PUT_ERROR(ASN1, i);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
|
||||
long len)
|
||||
{
|
||||
ASN1_OBJECT *ret = NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *data;
|
||||
int i, length;
|
||||
|
||||
/*
|
||||
* Sanity check OID encoding. Need at least one content octet. MSB must
|
||||
* be clear in the last octet. can't have leading 0x80 in subidentifiers,
|
||||
* see: X.690 8.19.2
|
||||
*/
|
||||
if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
|
||||
p[len - 1] & 0x80) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
|
||||
return NULL;
|
||||
}
|
||||
/* Now 0 < len <= INT_MAX, so the cast is safe. */
|
||||
length = (int)len;
|
||||
for (i = 0; i < length; i++, p++) {
|
||||
if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* only the ASN1_OBJECTs from the 'table' will have values for ->sn or
|
||||
* ->ln
|
||||
*/
|
||||
if ((a == NULL) || ((*a) == NULL) ||
|
||||
!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
|
||||
if ((ret = ASN1_OBJECT_new()) == NULL)
|
||||
return (NULL);
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
p = *pp;
|
||||
/* detach data from object */
|
||||
data = (unsigned char *)ret->data;
|
||||
ret->data = NULL;
|
||||
/* once detached we can change it */
|
||||
if ((data == NULL) || (ret->length < length)) {
|
||||
ret->length = 0;
|
||||
if (data != NULL)
|
||||
OPENSSL_free(data);
|
||||
data = (unsigned char *)OPENSSL_malloc(length);
|
||||
if (data == NULL) {
|
||||
i = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
|
||||
}
|
||||
OPENSSL_memcpy(data, p, length);
|
||||
/* reattach data to object, after which it remains const */
|
||||
ret->data = data;
|
||||
ret->length = length;
|
||||
ret->sn = NULL;
|
||||
ret->ln = NULL;
|
||||
/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
|
||||
p += length;
|
||||
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
OPENSSL_PUT_ERROR(ASN1, i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
ASN1_OBJECT_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *ASN1_OBJECT_new(void)
|
||||
{
|
||||
ASN1_OBJECT *ret;
|
||||
|
||||
ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
|
||||
if (ret == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
ret->length = 0;
|
||||
ret->data = NULL;
|
||||
ret->nid = 0;
|
||||
ret->sn = NULL;
|
||||
ret->ln = NULL;
|
||||
ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void ASN1_OBJECT_free(ASN1_OBJECT *a)
|
||||
{
|
||||
if (a == NULL)
|
||||
return;
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
|
||||
#ifndef CONST_STRICT /* disable purely for compile-time strict
|
||||
* const checking. Doing this on a "real"
|
||||
* compile will cause memory leaks */
|
||||
if (a->sn != NULL)
|
||||
OPENSSL_free((void *)a->sn);
|
||||
if (a->ln != NULL)
|
||||
OPENSSL_free((void *)a->ln);
|
||||
#endif
|
||||
a->sn = a->ln = NULL;
|
||||
}
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
|
||||
if (a->data != NULL)
|
||||
OPENSSL_free((void *)a->data);
|
||||
a->data = NULL;
|
||||
a->length = 0;
|
||||
}
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
|
||||
OPENSSL_free(a);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
|
||||
const char *sn, const char *ln)
|
||||
{
|
||||
ASN1_OBJECT o;
|
||||
|
||||
o.sn = sn;
|
||||
o.ln = ln;
|
||||
o.data = data;
|
||||
o.nid = nid;
|
||||
o.length = len;
|
||||
o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
|
||||
ASN1_OBJECT_FLAG_DYNAMIC_DATA;
|
||||
return (OBJ_dup(&o));
|
||||
}
|
||||
-77
@@ -1,77 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
|
||||
{
|
||||
return M_ASN1_OCTET_STRING_dup(x);
|
||||
}
|
||||
|
||||
int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
|
||||
const ASN1_OCTET_STRING *b)
|
||||
{
|
||||
return M_ASN1_OCTET_STRING_cmp(a, b);
|
||||
}
|
||||
|
||||
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d,
|
||||
int len)
|
||||
{
|
||||
return M_ASN1_OCTET_STRING_set(x, d, len);
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
|
||||
{
|
||||
return M_ASN1_OCTET_STRING_dup(x);
|
||||
}
|
||||
|
||||
int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
|
||||
const ASN1_OCTET_STRING *b)
|
||||
{
|
||||
return M_ASN1_OCTET_STRING_cmp(a, b);
|
||||
}
|
||||
|
||||
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d,
|
||||
int len)
|
||||
{
|
||||
return M_ASN1_OCTET_STRING_set(x, d, len);
|
||||
}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
int ASN1_PRINTABLE_type(const unsigned char *s, int len)
|
||||
{
|
||||
int c;
|
||||
int ia5 = 0;
|
||||
int t61 = 0;
|
||||
|
||||
if (len <= 0)
|
||||
len = -1;
|
||||
if (s == NULL)
|
||||
return (V_ASN1_PRINTABLESTRING);
|
||||
|
||||
while ((*s) && (len-- != 0)) {
|
||||
c = *(s++);
|
||||
if (!(((c >= 'a') && (c <= 'z')) ||
|
||||
((c >= 'A') && (c <= 'Z')) ||
|
||||
(c == ' ') ||
|
||||
((c >= '0') && (c <= '9')) ||
|
||||
(c == ' ') || (c == '\'') ||
|
||||
(c == '(') || (c == ')') ||
|
||||
(c == '+') || (c == ',') ||
|
||||
(c == '-') || (c == '.') ||
|
||||
(c == '/') || (c == ':') || (c == '=') || (c == '?')))
|
||||
ia5 = 1;
|
||||
if (c & 0x80)
|
||||
t61 = 1;
|
||||
}
|
||||
if (t61)
|
||||
return (V_ASN1_T61STRING);
|
||||
if (ia5)
|
||||
return (V_ASN1_IA5STRING);
|
||||
return (V_ASN1_PRINTABLESTRING);
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
int ASN1_PRINTABLE_type(const unsigned char *s, int len)
|
||||
{
|
||||
int c;
|
||||
int ia5 = 0;
|
||||
int t61 = 0;
|
||||
|
||||
if (len <= 0)
|
||||
len = -1;
|
||||
if (s == NULL)
|
||||
return (V_ASN1_PRINTABLESTRING);
|
||||
|
||||
while ((*s) && (len-- != 0)) {
|
||||
c = *(s++);
|
||||
if (!(((c >= 'a') && (c <= 'z')) ||
|
||||
((c >= 'A') && (c <= 'Z')) ||
|
||||
(c == ' ') ||
|
||||
((c >= '0') && (c <= '9')) ||
|
||||
(c == ' ') || (c == '\'') ||
|
||||
(c == '(') || (c == ')') ||
|
||||
(c == '+') || (c == ',') ||
|
||||
(c == '-') || (c == '.') ||
|
||||
(c == '/') || (c == ':') || (c == '=') || (c == '?')))
|
||||
ia5 = 1;
|
||||
if (c & 0x80)
|
||||
t61 = 1;
|
||||
}
|
||||
if (t61)
|
||||
return (V_ASN1_T61STRING);
|
||||
if (ia5)
|
||||
return (V_ASN1_IA5STRING);
|
||||
return (V_ASN1_PRINTABLESTRING);
|
||||
}
|
||||
-313
@@ -1,313 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <stdlib.h> /* For bsearch */
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
#include <openssl_grpc/obj.h>
|
||||
#include <openssl_grpc/stack.h>
|
||||
|
||||
DEFINE_STACK_OF(ASN1_STRING_TABLE)
|
||||
|
||||
static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
|
||||
static void st_free(ASN1_STRING_TABLE *tbl);
|
||||
|
||||
/*
|
||||
* This is the global mask for the mbstring functions: this is use to mask
|
||||
* out certain types (such as BMPString and UTF8String) because certain
|
||||
* software (e.g. Netscape) has problems with them.
|
||||
*/
|
||||
|
||||
static unsigned long global_mask = B_ASN1_UTF8STRING;
|
||||
|
||||
void ASN1_STRING_set_default_mask(unsigned long mask)
|
||||
{
|
||||
global_mask = mask;
|
||||
}
|
||||
|
||||
unsigned long ASN1_STRING_get_default_mask(void)
|
||||
{
|
||||
return global_mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sets the default to various "flavours" of configuration.
|
||||
* based on an ASCII string. Currently this is: MASK:XXXX : a numerical mask
|
||||
* value. nobmp : Don't use BMPStrings (just Printable, T61). pkix : PKIX
|
||||
* recommendation in RFC2459. utf8only : only use UTF8Strings (RFC2459
|
||||
* recommendation for 2004). default: the default value, Printable, T61, BMP.
|
||||
*/
|
||||
|
||||
int ASN1_STRING_set_default_mask_asc(const char *p)
|
||||
{
|
||||
unsigned long mask;
|
||||
char *end;
|
||||
if (!strncmp(p, "MASK:", 5)) {
|
||||
if (!p[5])
|
||||
return 0;
|
||||
mask = strtoul(p + 5, &end, 0);
|
||||
if (*end)
|
||||
return 0;
|
||||
} else if (!strcmp(p, "nombstr"))
|
||||
mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING));
|
||||
else if (!strcmp(p, "pkix"))
|
||||
mask = ~((unsigned long)B_ASN1_T61STRING);
|
||||
else if (!strcmp(p, "utf8only"))
|
||||
mask = B_ASN1_UTF8STRING;
|
||||
else if (!strcmp(p, "default"))
|
||||
mask = 0xFFFFFFFFL;
|
||||
else
|
||||
return 0;
|
||||
ASN1_STRING_set_default_mask(mask);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function generates an ASN1_STRING based on limits in a
|
||||
* table. Frequently the types and length of an ASN1_STRING are restricted by
|
||||
* a corresponding OID. For example certificates and certificate requests.
|
||||
*/
|
||||
|
||||
ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
|
||||
const unsigned char *in, int inlen,
|
||||
int inform, int nid)
|
||||
{
|
||||
ASN1_STRING_TABLE *tbl;
|
||||
ASN1_STRING *str = NULL;
|
||||
unsigned long mask;
|
||||
int ret;
|
||||
if (!out)
|
||||
out = &str;
|
||||
tbl = ASN1_STRING_TABLE_get(nid);
|
||||
if (tbl) {
|
||||
mask = tbl->mask;
|
||||
if (!(tbl->flags & STABLE_NO_MASK))
|
||||
mask &= global_mask;
|
||||
ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
|
||||
tbl->minsize, tbl->maxsize);
|
||||
} else
|
||||
ret =
|
||||
ASN1_mbstring_copy(out, in, inlen, inform,
|
||||
DIRSTRING_TYPE & global_mask);
|
||||
if (ret <= 0)
|
||||
return NULL;
|
||||
return *out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now the tables and helper functions for the string table:
|
||||
*/
|
||||
|
||||
/* size limits: this stuff is taken straight from RFC3280 */
|
||||
|
||||
#define ub_name 32768
|
||||
#define ub_common_name 64
|
||||
#define ub_locality_name 128
|
||||
#define ub_state_name 128
|
||||
#define ub_organization_name 64
|
||||
#define ub_organization_unit_name 64
|
||||
#define ub_title 64
|
||||
#define ub_email_address 128
|
||||
#define ub_serial_number 64
|
||||
|
||||
/* This table must be kept in NID order */
|
||||
|
||||
static const ASN1_STRING_TABLE tbl_standard[] = {
|
||||
{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
|
||||
{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
|
||||
{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
|
||||
{NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
|
||||
{NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
|
||||
{NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE,
|
||||
0},
|
||||
{NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING,
|
||||
STABLE_NO_MASK},
|
||||
{NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
|
||||
{NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
|
||||
{NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
|
||||
{NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING,
|
||||
STABLE_NO_MASK},
|
||||
{NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
|
||||
{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
|
||||
{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
|
||||
{NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
|
||||
};
|
||||
|
||||
static int sk_table_cmp(const ASN1_STRING_TABLE **a,
|
||||
const ASN1_STRING_TABLE **b)
|
||||
{
|
||||
return (*a)->nid - (*b)->nid;
|
||||
}
|
||||
|
||||
static int table_cmp(const void *in_a, const void *in_b)
|
||||
{
|
||||
const ASN1_STRING_TABLE *a = in_a;
|
||||
const ASN1_STRING_TABLE *b = in_b;
|
||||
return a->nid - b->nid;
|
||||
}
|
||||
|
||||
ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
|
||||
{
|
||||
int found;
|
||||
size_t idx;
|
||||
ASN1_STRING_TABLE *ttmp;
|
||||
ASN1_STRING_TABLE fnd;
|
||||
fnd.nid = nid;
|
||||
|
||||
ttmp =
|
||||
bsearch(&fnd, tbl_standard,
|
||||
sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE),
|
||||
sizeof(ASN1_STRING_TABLE), table_cmp);
|
||||
if (ttmp)
|
||||
return ttmp;
|
||||
if (!stable)
|
||||
return NULL;
|
||||
sk_ASN1_STRING_TABLE_sort(stable);
|
||||
found = sk_ASN1_STRING_TABLE_find(stable, &idx, &fnd);
|
||||
if (!found)
|
||||
return NULL;
|
||||
return sk_ASN1_STRING_TABLE_value(stable, idx);
|
||||
}
|
||||
|
||||
int ASN1_STRING_TABLE_add(int nid,
|
||||
long minsize, long maxsize, unsigned long mask,
|
||||
unsigned long flags)
|
||||
{
|
||||
ASN1_STRING_TABLE *tmp;
|
||||
char new_nid = 0;
|
||||
flags &= ~STABLE_FLAGS_MALLOC;
|
||||
if (!stable)
|
||||
stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
|
||||
if (!stable) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (!(tmp = ASN1_STRING_TABLE_get(nid))) {
|
||||
tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
|
||||
if (!tmp) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
tmp->flags = flags | STABLE_FLAGS_MALLOC;
|
||||
tmp->nid = nid;
|
||||
tmp->minsize = tmp->maxsize = -1;
|
||||
new_nid = 1;
|
||||
} else
|
||||
tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
|
||||
if (minsize != -1)
|
||||
tmp->minsize = minsize;
|
||||
if (maxsize != -1)
|
||||
tmp->maxsize = maxsize;
|
||||
tmp->mask = mask;
|
||||
if (new_nid)
|
||||
sk_ASN1_STRING_TABLE_push(stable, tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ASN1_STRING_TABLE_cleanup(void)
|
||||
{
|
||||
STACK_OF(ASN1_STRING_TABLE) *tmp;
|
||||
tmp = stable;
|
||||
if (!tmp)
|
||||
return;
|
||||
stable = NULL;
|
||||
sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
|
||||
}
|
||||
|
||||
static void st_free(ASN1_STRING_TABLE *tbl)
|
||||
{
|
||||
if (tbl->flags & STABLE_FLAGS_MALLOC)
|
||||
OPENSSL_free(tbl);
|
||||
}
|
||||
|
||||
#ifdef STRING_TABLE_TEST
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ASN1_STRING_TABLE *tmp;
|
||||
int i, last_nid = -1;
|
||||
|
||||
for (tmp = tbl_standard, i = 0;
|
||||
i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) {
|
||||
if (tmp->nid < last_nid) {
|
||||
last_nid = 0;
|
||||
break;
|
||||
}
|
||||
last_nid = tmp->nid;
|
||||
}
|
||||
|
||||
if (last_nid != 0) {
|
||||
printf("Table order OK\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
for (tmp = tbl_standard, i = 0;
|
||||
i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++)
|
||||
printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
|
||||
OBJ_nid2ln(tmp->nid));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,313 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#include <stdlib.h> /* For bsearch */
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/obj.h>
|
||||
#include <openssl/stack.h>
|
||||
|
||||
DEFINE_STACK_OF(ASN1_STRING_TABLE)
|
||||
|
||||
static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
|
||||
static void st_free(ASN1_STRING_TABLE *tbl);
|
||||
|
||||
/*
|
||||
* This is the global mask for the mbstring functions: this is use to mask
|
||||
* out certain types (such as BMPString and UTF8String) because certain
|
||||
* software (e.g. Netscape) has problems with them.
|
||||
*/
|
||||
|
||||
static unsigned long global_mask = B_ASN1_UTF8STRING;
|
||||
|
||||
void ASN1_STRING_set_default_mask(unsigned long mask)
|
||||
{
|
||||
global_mask = mask;
|
||||
}
|
||||
|
||||
unsigned long ASN1_STRING_get_default_mask(void)
|
||||
{
|
||||
return global_mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sets the default to various "flavours" of configuration.
|
||||
* based on an ASCII string. Currently this is: MASK:XXXX : a numerical mask
|
||||
* value. nobmp : Don't use BMPStrings (just Printable, T61). pkix : PKIX
|
||||
* recommendation in RFC2459. utf8only : only use UTF8Strings (RFC2459
|
||||
* recommendation for 2004). default: the default value, Printable, T61, BMP.
|
||||
*/
|
||||
|
||||
int ASN1_STRING_set_default_mask_asc(const char *p)
|
||||
{
|
||||
unsigned long mask;
|
||||
char *end;
|
||||
if (!strncmp(p, "MASK:", 5)) {
|
||||
if (!p[5])
|
||||
return 0;
|
||||
mask = strtoul(p + 5, &end, 0);
|
||||
if (*end)
|
||||
return 0;
|
||||
} else if (!strcmp(p, "nombstr"))
|
||||
mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING));
|
||||
else if (!strcmp(p, "pkix"))
|
||||
mask = ~((unsigned long)B_ASN1_T61STRING);
|
||||
else if (!strcmp(p, "utf8only"))
|
||||
mask = B_ASN1_UTF8STRING;
|
||||
else if (!strcmp(p, "default"))
|
||||
mask = 0xFFFFFFFFL;
|
||||
else
|
||||
return 0;
|
||||
ASN1_STRING_set_default_mask(mask);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function generates an ASN1_STRING based on limits in a
|
||||
* table. Frequently the types and length of an ASN1_STRING are restricted by
|
||||
* a corresponding OID. For example certificates and certificate requests.
|
||||
*/
|
||||
|
||||
ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
|
||||
const unsigned char *in, int inlen,
|
||||
int inform, int nid)
|
||||
{
|
||||
ASN1_STRING_TABLE *tbl;
|
||||
ASN1_STRING *str = NULL;
|
||||
unsigned long mask;
|
||||
int ret;
|
||||
if (!out)
|
||||
out = &str;
|
||||
tbl = ASN1_STRING_TABLE_get(nid);
|
||||
if (tbl) {
|
||||
mask = tbl->mask;
|
||||
if (!(tbl->flags & STABLE_NO_MASK))
|
||||
mask &= global_mask;
|
||||
ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
|
||||
tbl->minsize, tbl->maxsize);
|
||||
} else
|
||||
ret =
|
||||
ASN1_mbstring_copy(out, in, inlen, inform,
|
||||
DIRSTRING_TYPE & global_mask);
|
||||
if (ret <= 0)
|
||||
return NULL;
|
||||
return *out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now the tables and helper functions for the string table:
|
||||
*/
|
||||
|
||||
/* size limits: this stuff is taken straight from RFC3280 */
|
||||
|
||||
#define ub_name 32768
|
||||
#define ub_common_name 64
|
||||
#define ub_locality_name 128
|
||||
#define ub_state_name 128
|
||||
#define ub_organization_name 64
|
||||
#define ub_organization_unit_name 64
|
||||
#define ub_title 64
|
||||
#define ub_email_address 128
|
||||
#define ub_serial_number 64
|
||||
|
||||
/* This table must be kept in NID order */
|
||||
|
||||
static const ASN1_STRING_TABLE tbl_standard[] = {
|
||||
{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
|
||||
{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
|
||||
{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
|
||||
{NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
|
||||
{NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
|
||||
{NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE,
|
||||
0},
|
||||
{NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING,
|
||||
STABLE_NO_MASK},
|
||||
{NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
|
||||
{NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
|
||||
{NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
|
||||
{NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING,
|
||||
STABLE_NO_MASK},
|
||||
{NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
|
||||
{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
|
||||
{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
|
||||
{NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
|
||||
};
|
||||
|
||||
static int sk_table_cmp(const ASN1_STRING_TABLE **a,
|
||||
const ASN1_STRING_TABLE **b)
|
||||
{
|
||||
return (*a)->nid - (*b)->nid;
|
||||
}
|
||||
|
||||
static int table_cmp(const void *in_a, const void *in_b)
|
||||
{
|
||||
const ASN1_STRING_TABLE *a = in_a;
|
||||
const ASN1_STRING_TABLE *b = in_b;
|
||||
return a->nid - b->nid;
|
||||
}
|
||||
|
||||
ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
|
||||
{
|
||||
int found;
|
||||
size_t idx;
|
||||
ASN1_STRING_TABLE *ttmp;
|
||||
ASN1_STRING_TABLE fnd;
|
||||
fnd.nid = nid;
|
||||
|
||||
ttmp =
|
||||
bsearch(&fnd, tbl_standard,
|
||||
sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE),
|
||||
sizeof(ASN1_STRING_TABLE), table_cmp);
|
||||
if (ttmp)
|
||||
return ttmp;
|
||||
if (!stable)
|
||||
return NULL;
|
||||
sk_ASN1_STRING_TABLE_sort(stable);
|
||||
found = sk_ASN1_STRING_TABLE_find(stable, &idx, &fnd);
|
||||
if (!found)
|
||||
return NULL;
|
||||
return sk_ASN1_STRING_TABLE_value(stable, idx);
|
||||
}
|
||||
|
||||
int ASN1_STRING_TABLE_add(int nid,
|
||||
long minsize, long maxsize, unsigned long mask,
|
||||
unsigned long flags)
|
||||
{
|
||||
ASN1_STRING_TABLE *tmp;
|
||||
char new_nid = 0;
|
||||
flags &= ~STABLE_FLAGS_MALLOC;
|
||||
if (!stable)
|
||||
stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
|
||||
if (!stable) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (!(tmp = ASN1_STRING_TABLE_get(nid))) {
|
||||
tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
|
||||
if (!tmp) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
tmp->flags = flags | STABLE_FLAGS_MALLOC;
|
||||
tmp->nid = nid;
|
||||
tmp->minsize = tmp->maxsize = -1;
|
||||
new_nid = 1;
|
||||
} else
|
||||
tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
|
||||
if (minsize != -1)
|
||||
tmp->minsize = minsize;
|
||||
if (maxsize != -1)
|
||||
tmp->maxsize = maxsize;
|
||||
tmp->mask = mask;
|
||||
if (new_nid)
|
||||
sk_ASN1_STRING_TABLE_push(stable, tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ASN1_STRING_TABLE_cleanup(void)
|
||||
{
|
||||
STACK_OF(ASN1_STRING_TABLE) *tmp;
|
||||
tmp = stable;
|
||||
if (!tmp)
|
||||
return;
|
||||
stable = NULL;
|
||||
sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
|
||||
}
|
||||
|
||||
static void st_free(ASN1_STRING_TABLE *tbl)
|
||||
{
|
||||
if (tbl->flags & STABLE_FLAGS_MALLOC)
|
||||
OPENSSL_free(tbl);
|
||||
}
|
||||
|
||||
#ifdef STRING_TABLE_TEST
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ASN1_STRING_TABLE *tmp;
|
||||
int i, last_nid = -1;
|
||||
|
||||
for (tmp = tbl_standard, i = 0;
|
||||
i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) {
|
||||
if (tmp->nid < last_nid) {
|
||||
last_nid = 0;
|
||||
break;
|
||||
}
|
||||
last_nid = tmp->nid;
|
||||
}
|
||||
|
||||
if (last_nid != 0) {
|
||||
printf("Table order OK\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
for (tmp = tbl_standard, i = 0;
|
||||
i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++)
|
||||
printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
|
||||
OBJ_nid2ln(tmp->nid));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
-212
@@ -1,212 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl_grpc/asn1.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <openssl_grpc/asn1t.h>
|
||||
#include <openssl_grpc/err.h>
|
||||
#include <openssl_grpc/mem.h>
|
||||
|
||||
#include "asn1_locl.h"
|
||||
|
||||
/*
|
||||
* This is an implementation of the ASN1 Time structure which is: Time ::=
|
||||
* CHOICE { utcTime UTCTime, generalTime GeneralizedTime } written by Steve
|
||||
* Henson.
|
||||
*/
|
||||
|
||||
IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
|
||||
|
||||
ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
|
||||
{
|
||||
return ASN1_TIME_adj(s, t, 0, 0);
|
||||
}
|
||||
|
||||
ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
|
||||
int offset_day, long offset_sec)
|
||||
{
|
||||
struct tm *ts;
|
||||
struct tm data;
|
||||
|
||||
ts = OPENSSL_gmtime(&t, &data);
|
||||
if (ts == NULL) {
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME);
|
||||
return NULL;
|
||||
}
|
||||
if (offset_day || offset_sec) {
|
||||
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
|
||||
return NULL;
|
||||
}
|
||||
if ((ts->tm_year >= 50) && (ts->tm_year < 150))
|
||||
return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
|
||||
return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
|
||||
}
|
||||
|
||||
int ASN1_TIME_check(ASN1_TIME *t)
|
||||
{
|
||||
if (t->type == V_ASN1_GENERALIZEDTIME)
|
||||
return ASN1_GENERALIZEDTIME_check(t);
|
||||
else if (t->type == V_ASN1_UTCTIME)
|
||||
return ASN1_UTCTIME_check(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Convert an ASN1_TIME structure to GeneralizedTime */
|
||||
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
|
||||
ASN1_GENERALIZEDTIME **out)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME *ret = NULL;
|
||||
char *str;
|
||||
int newlen;
|
||||
|
||||
if (!ASN1_TIME_check(t))
|
||||
return NULL;
|
||||
|
||||
if (!out || !*out) {
|
||||
if (!(ret = ASN1_GENERALIZEDTIME_new()))
|
||||
goto err;
|
||||
} else {
|
||||
ret = *out;
|
||||
}
|
||||
|
||||
/* If already GeneralizedTime just copy across */
|
||||
if (t->type == V_ASN1_GENERALIZEDTIME) {
|
||||
if (!ASN1_STRING_set(ret, t->data, t->length))
|
||||
goto err;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* grow the string */
|
||||
if (!ASN1_STRING_set(ret, NULL, t->length + 2))
|
||||
goto err;
|
||||
/* ASN1_STRING_set() allocated 'len + 1' bytes. */
|
||||
newlen = t->length + 2 + 1;
|
||||
str = (char *)ret->data;
|
||||
/* Work out the century and prepend */
|
||||
if (t->data[0] >= '5')
|
||||
OPENSSL_strlcpy(str, "19", newlen);
|
||||
else
|
||||
OPENSSL_strlcpy(str, "20", newlen);
|
||||
|
||||
OPENSSL_strlcat(str, (char *)t->data, newlen);
|
||||
|
||||
done:
|
||||
if (out != NULL && *out == NULL)
|
||||
*out = ret;
|
||||
return ret;
|
||||
|
||||
err:
|
||||
if (out == NULL || *out != ret)
|
||||
ASN1_GENERALIZEDTIME_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
|
||||
{
|
||||
ASN1_TIME t;
|
||||
|
||||
t.length = strlen(str);
|
||||
t.data = (unsigned char *)str;
|
||||
t.flags = 0;
|
||||
|
||||
t.type = V_ASN1_UTCTIME;
|
||||
|
||||
if (!ASN1_TIME_check(&t)) {
|
||||
t.type = V_ASN1_GENERALIZEDTIME;
|
||||
if (!ASN1_TIME_check(&t))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t)
|
||||
{
|
||||
if (t == NULL) {
|
||||
time_t now_t;
|
||||
time(&now_t);
|
||||
if (OPENSSL_gmtime(&now_t, tm))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (t->type == V_ASN1_UTCTIME)
|
||||
return asn1_utctime_to_tm(tm, t);
|
||||
else if (t->type == V_ASN1_GENERALIZEDTIME)
|
||||
return asn1_generalizedtime_to_tm(tm, t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ASN1_TIME_diff(int *pday, int *psec,
|
||||
const ASN1_TIME *from, const ASN1_TIME *to)
|
||||
{
|
||||
struct tm tm_from, tm_to;
|
||||
if (!asn1_time_to_tm(&tm_from, from))
|
||||
return 0;
|
||||
if (!asn1_time_to_tm(&tm_to, to))
|
||||
return 0;
|
||||
return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user