From 73e3a5c7d8b7e8e2727664b61e1d35a9ab848e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Mon, 18 Sep 2023 15:27:19 +0200 Subject: [PATCH 1/9] Apple: #531: Make PowerAuthAuthentication immutable --- docs/Migration-from-1.7-to-1.8.md | 8 ++++++-- .../PowerAuth2/PowerAuthAuthentication.h | 20 +++++-------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/docs/Migration-from-1.7-to-1.8.md b/docs/Migration-from-1.7-to-1.8.md index c9cd6890..170c5c08 100644 --- a/docs/Migration-from-1.7-to-1.8.md +++ b/docs/Migration-from-1.7-to-1.8.md @@ -52,6 +52,8 @@ Legacy PowerAuth configuration: - The `ICommitActivationWithBiometryListener` is now deprecated and you can use `IPersistActivationWithBiometryListener` as a replacement. +- The `PowerAuthAuthentication` object is now immutable object. + - The biometry-related methods in `PowerAuthSDK` are no longer annotated as `@RequiresApi(api = Build.VERSION_CODES.M)`. This change may lead to a several dead code branches in your code if you still support devices older than Android 6.0. - Removed all interfaces deprecated in release `1.7.x` @@ -142,6 +144,8 @@ Visit [Synchronized Time](https://developers.wultra.com/components/powerauth-mob - `.commitWithPasswordAndBiometry(password:)` is now `.persistithPasswordAndBiometry(password:)` - `.commitWithPasswordAndBiometry(password:customBiometryKey:customPossessionKey:)` is now `.persistWithPasswordAndBiometry(password:customBiometryKey:customPossessionKey:)` +- The `PowerAuthAuthentication` object is now immutable and no longer implements `NSCopying` protocol. + - `PowerAuthErrorCode` now contains new `.timeSynchronization` case indicating a problem with the time synchronization. - Removed all interfaces deprecated in release `1.7.x` @@ -203,10 +207,10 @@ Visit [Synchronized Time](https://developers.wultra.com/components/powerauth-mob ### API changes -- TBA +- The `PowerAuthAuthentication` object is now immutable object and no longer implement `NSCopying` protocol. ## watchOS ### API changes -- TBA \ No newline at end of file +- The `PowerAuthAuthentication` object is now immutable object and no longer implement `NSCopying` protocol. \ No newline at end of file diff --git a/proj-xcode/PowerAuth2/PowerAuthAuthentication.h b/proj-xcode/PowerAuth2/PowerAuthAuthentication.h index aac32ce5..743d7e7f 100644 --- a/proj-xcode/PowerAuth2/PowerAuthAuthentication.h +++ b/proj-xcode/PowerAuth2/PowerAuthAuthentication.h @@ -27,14 +27,10 @@ @interface PowerAuthAuthentication : NSObject /// Indicates if a possession factor should be used. -/// -/// Modifying content of usePossession property is deprecated. Please use appropriate static method to create PowerAuthAuthentication instance. -@property (nonatomic, assign) BOOL usePossession; +@property (nonatomic, readonly, assign) BOOL usePossession; /// Indicates if a biometry factor should be used. -/// -/// Modifying content of useBiometry property is deprecated. Please use appropriate static method to create PowerAuthAuthentication instance. -@property (nonatomic, assign) BOOL useBiometry; +@property (nonatomic, readonly, assign) BOOL useBiometry; /// Contains password safely stored in PowerAuthCorePassword object in case that knowledge factor is required in authentication. @property (nonatomic, readonly, strong, nullable) PowerAuthCorePassword * password; @@ -43,22 +39,16 @@ /// /// Use this value to give user a hint on what is biometric authentication used for in this specific authentication. /// For example, include a name of the account user uses to log in. -/// -/// Modifying content of biometryPrompt property is deprecated. Please use appropriate static method to create PowerAuthAuthentication instance. -@property (nonatomic, strong, nullable) NSString *biometryPrompt; +@property (nonatomic, readonly, strong, nullable) NSString *biometryPrompt; /// Indicates if a biometry factor should be used. If both biometryContext and biometryPrompt properties are set, then the context will be applied. @property (nonatomic, strong, nullable, readonly) LAContext *biometryContext API_UNAVAILABLE(watchos, tvos); /// If 'usePossession' is set to YES, this value may specify possession key data. If no custom data is specified, default possession key is used. -/// -/// Modifying content of overridenPossessionKey property is deprecated. Please use appropriate static method to create PowerAuthAuthentication instance. -@property (nonatomic, strong, nullable) NSData *overridenPossessionKey; +@property (nonatomic, strong, nullable, readonly) NSData *overridenPossessionKey; /// If 'useBiometry' is set to YES, this value may specify biometry key data. If no custom data is specified, default biometry key is used for the PowerAuthSDK instance, based on the keychain configuration and SDK instance configuration. -/// -/// Modifying content of overridenBiometryKey property is deprecated. Please use appropriate static method to create PowerAuthAuthentication instance. -@property (nonatomic, strong, nullable) NSData *overridenBiometryKey; +@property (nonatomic, strong, nullable, readonly) NSData *overridenBiometryKey; @end From 95f0a5eea436ca6f50cc9aaf1950e67e530e45e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Tue, 19 Sep 2023 09:51:15 +0200 Subject: [PATCH 2/9] Apple: Fixed PA2PrivateTokenData copy method --- proj-xcode/PowerAuth2/private/PA2PrivateTokenData.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proj-xcode/PowerAuth2/private/PA2PrivateTokenData.m b/proj-xcode/PowerAuth2/private/PA2PrivateTokenData.m index 495b64ed..e584c611 100644 --- a/proj-xcode/PowerAuth2/private/PA2PrivateTokenData.m +++ b/proj-xcode/PowerAuth2/private/PA2PrivateTokenData.m @@ -123,6 +123,8 @@ - (id) copyWithZone:(NSZone *)zone c->_name = _name; c->_identifier = _identifier; c->_secret = _secret; + c->_activationIdentifier = _activationIdentifier; + c->_authenticationFactors = _authenticationFactors; } return c; } From 6cb5e36798edac3935f96ab9a81859147792b5af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Tue, 19 Sep 2023 09:51:34 +0200 Subject: [PATCH 3/9] Apple: Remove deprecated method impl. --- .../PowerAuth2/private/PA2PrivateTokenKeychainStore.m | 9 --------- 1 file changed, 9 deletions(-) diff --git a/proj-xcode/PowerAuth2/private/PA2PrivateTokenKeychainStore.m b/proj-xcode/PowerAuth2/private/PA2PrivateTokenKeychainStore.m index 1eb41c97..b75723af 100644 --- a/proj-xcode/PowerAuth2/private/PA2PrivateTokenKeychainStore.m +++ b/proj-xcode/PowerAuth2/private/PA2PrivateTokenKeychainStore.m @@ -308,15 +308,6 @@ - (BOOL) canRequestForAccessToken }]; } - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-implementations" -- (void) cancelTask:(id)task -{ - [PA2ConformsTo(task, PowerAuthOperationTask) cancel]; -} -#pragma clang diagnostic pop - #if PA2_HAS_CORE_MODULE == 1 || TARGET_OS_WATCH == 1 // // Implementation available for PowerAuth2 & PowerAuth2ForWatch modules From e0e57a6d8a2171e37ac21cd9c580a7e36f94d009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Tue, 19 Sep 2023 13:01:54 +0200 Subject: [PATCH 4/9] Apple: iOS and tvOS min deployment target changed to 12.0 - Fixed warnings from Xcode 15 --- PowerAuth2.podspec | 4 +-- PowerAuthCore.podspec | 4 +-- cc7 | 2 +- .../PowerAuth2.xcodeproj/project.pbxproj | 16 +++++---- .../PowerAuth2_IntegrationTests_iOS.xcscheme | 2 +- .../PowerAuth2_IntegrationTests_tvOS.xcscheme | 2 +- .../PowerAuth2_TestHostApp_iOS.xcscheme | 2 +- .../PowerAuth2_TestHostApp_tvOS.xcscheme | 2 +- .../xcschemes/PowerAuth2_iOS.xcscheme | 2 +- .../xcschemes/PowerAuth2_tvOS.xcscheme | 2 +- proj-xcode/PowerAuth2/PowerAuthKeychain.m | 33 +++---------------- .../PowerAuthCore.xcodeproj/project.pbxproj | 18 +++++----- .../xcschemes/PowerAuthCoreTests_iOS.xcscheme | 2 +- .../PowerAuthCoreTests_tvOS.xcscheme | 2 +- .../xcschemes/PowerAuthCore_iOS.xcscheme | 2 +- .../xcschemes/PowerAuthCore_tvOS.xcscheme | 2 +- scripts/config-apple.sh | 4 +-- scripts/templates/PowerAuth2.podspec | 4 +-- scripts/templates/PowerAuthCore.podspec | 4 +-- 19 files changed, 43 insertions(+), 66 deletions(-) diff --git a/PowerAuth2.podspec b/PowerAuth2.podspec index 157fb85c..d7b60035 100644 --- a/PowerAuth2.podspec +++ b/PowerAuth2.podspec @@ -23,8 +23,8 @@ Pod::Spec.new do |s| :submodules => true } - s.ios.deployment_target = '11.0' - s.tvos.deployment_target = '11.0' + s.ios.deployment_target = '12.0' + s.tvos.deployment_target = '12.0' # XCFramework build s.prepare_command = <<-CMD diff --git a/PowerAuthCore.podspec b/PowerAuthCore.podspec index bcfadbfe..c86601f1 100644 --- a/PowerAuthCore.podspec +++ b/PowerAuthCore.podspec @@ -22,8 +22,8 @@ Pod::Spec.new do |s| :submodules => true } - s.ios.deployment_target = '11.0' - s.tvos.deployment_target = '11.0' + s.ios.deployment_target = '12.0' + s.tvos.deployment_target = '12.0' # XCFramework build s.prepare_command = <<-CMD diff --git a/cc7 b/cc7 index 8d7c0697..ba8ba8e3 160000 --- a/cc7 +++ b/cc7 @@ -1 +1 @@ -Subproject commit 8d7c06971aa6716f84c00d743d38f9721d6c6415 +Subproject commit ba8ba8e3c2434e6916976efe3bd00126d13e31cf diff --git a/proj-xcode/PowerAuth2.xcodeproj/project.pbxproj b/proj-xcode/PowerAuth2.xcodeproj/project.pbxproj index 455cee7d..9f0cccd3 100644 --- a/proj-xcode/PowerAuth2.xcodeproj/project.pbxproj +++ b/proj-xcode/PowerAuth2.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 56; objects = { /* Begin PBXBuildFile section */ @@ -1728,7 +1728,7 @@ attributes = { BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1320; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1500; ORGANIZATIONNAME = "Wultra s.r.o."; TargetAttributes = { BF4DBCCC1CDF9CDE008F3A47 = { @@ -1762,7 +1762,7 @@ }; }; buildConfigurationList = BF4DBB961CDF3130008F3A47 /* Build configuration list for PBXProject "PowerAuth2" */; - compatibilityVersion = "Xcode 12.0"; + compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -2274,6 +2274,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = c11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -2293,14 +2294,14 @@ "$(PROJECT_DIR)/../cc7/include", "$(PROJECT_DIR)/../cc7/openssl-lib/apple/include", ); - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/../cc7/openssl-lib/apple"; MACOSX_DEPLOYMENT_TARGET = 10.15; ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = iphoneos; SWIFT_VERSION = 5.0; - TVOS_DEPLOYMENT_TARGET = 11.0; + TVOS_DEPLOYMENT_TARGET = 12.0; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Debug; @@ -2341,6 +2342,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = c11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -2354,14 +2356,14 @@ "$(PROJECT_DIR)/../cc7/include", "$(PROJECT_DIR)/../cc7/openssl-lib/apple/include", ); - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/../cc7/openssl-lib/apple"; MACOSX_DEPLOYMENT_TARGET = 10.15; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_VERSION = 5.0; - TVOS_DEPLOYMENT_TARGET = 11.0; + TVOS_DEPLOYMENT_TARGET = 12.0; VALIDATE_PRODUCT = YES; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; diff --git a/proj-xcode/PowerAuth2.xcodeproj/xcshareddata/xcschemes/PowerAuth2_IntegrationTests_iOS.xcscheme b/proj-xcode/PowerAuth2.xcodeproj/xcshareddata/xcschemes/PowerAuth2_IntegrationTests_iOS.xcscheme index 75afd80a..0d2b0bde 100644 --- a/proj-xcode/PowerAuth2.xcodeproj/xcshareddata/xcschemes/PowerAuth2_IntegrationTests_iOS.xcscheme +++ b/proj-xcode/PowerAuth2.xcodeproj/xcshareddata/xcschemes/PowerAuth2_IntegrationTests_iOS.xcscheme @@ -1,6 +1,6 @@ = __IPHONE_11_2 - #define __LABiometryTypeNone LABiometryTypeNone -#else - #define __LABiometryTypeNone LABiometryNone -#endif -// 11.3+ -#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_11_3 - #define __kSecAccessControlBiometryAny kSecAccessControlBiometryAny - #define __kSecAccessControlBiometryCurrentSet kSecAccessControlBiometryCurrentSet -#else - #define __kSecAccessControlBiometryAny kSecAccessControlTouchIDAny - #define __kSecAccessControlBiometryCurrentSet kSecAccessControlTouchIDCurrentSet -#endif /** Private function returns full information about biometric support on the system. The method internally @@ -330,7 +305,7 @@ static PowerAuthBiometricAuthenticationInfo _getBiometryInfo(void) // In case of error we cannot evaluate, but the type of biometry can be determined. NSInteger code = [error.domain isEqualToString:LAErrorDomain] ? error.code : 0; LABiometryType bt = context.biometryType; - if (bt != __LABiometryTypeNone) { + if (bt != LABiometryTypeNone) { info.biometryType = _LABiometryTypeToPAType(bt); if (code == LAErrorBiometryLockout) { info.currentStatus = PowerAuthBiometricAuthenticationStatus_Lockout; @@ -354,11 +329,11 @@ static SecAccessControlCreateFlags _getBiometryAccessControlFlags(PowerAuthKeych if (access != PowerAuthKeychainItemAccess_None) { switch (access) { case PowerAuthKeychainItemAccess_AnyBiometricSet: - return __kSecAccessControlBiometryAny; + return kSecAccessControlBiometryAny; case PowerAuthKeychainItemAccess_AnyBiometricSetOrDevicePasscode: - return __kSecAccessControlBiometryAny | kSecAccessControlOr | kSecAccessControlDevicePasscode; + return kSecAccessControlBiometryAny | kSecAccessControlOr | kSecAccessControlDevicePasscode; case PowerAuthKeychainItemAccess_CurrentBiometricSet: - return __kSecAccessControlBiometryCurrentSet; + return kSecAccessControlBiometryCurrentSet; default: break; } diff --git a/proj-xcode/PowerAuthCore.xcodeproj/project.pbxproj b/proj-xcode/PowerAuthCore.xcodeproj/project.pbxproj index 6d71c0ce..8ed272b9 100644 --- a/proj-xcode/PowerAuthCore.xcodeproj/project.pbxproj +++ b/proj-xcode/PowerAuthCore.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 56; objects = { /* Begin PBXBuildFile section */ @@ -73,7 +73,6 @@ BF720DCF2642A5EA00D5932A /* PowerAuthCoreDeprecated.m in Sources */ = {isa = PBXBuildFile; fileRef = BF720DCE2642A5EA00D5932A /* PowerAuthCoreDeprecated.m */; }; BF720DD02642A5EA00D5932A /* PowerAuthCoreDeprecated.m in Sources */ = {isa = PBXBuildFile; fileRef = BF720DCE2642A5EA00D5932A /* PowerAuthCoreDeprecated.m */; }; BF86E65E26395AD3004C8AE5 /* PowerAuthCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF6ADD1524C8486D001B3E5E /* PowerAuthCore.framework */; }; - BF86E68E26395BA1004C8AE5 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = BF86E68D26395BA1004C8AE5 /* libc++.tbd */; }; BF86E6B626395D44004C8AE5 /* PowerAuthCoreTestsWrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = BF86E6B426395D44004C8AE5 /* PowerAuthCoreTestsWrapper.mm */; }; BF86E6B726395D44004C8AE5 /* PowerAuthCorePublicObjectsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = BF86E6B526395D44004C8AE5 /* PowerAuthCorePublicObjectsTests.mm */; }; BF86E6D426395F12004C8AE5 /* libPowerAuthCoreLibTests-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BF99D9152073E17000735ED2 /* libPowerAuthCoreLibTests-ios.a */; }; @@ -542,7 +541,6 @@ buildActionMask = 2147483647; files = ( BF86E6D426395F12004C8AE5 /* libPowerAuthCoreLibTests-ios.a in Frameworks */, - BF86E68E26395BA1004C8AE5 /* libc++.tbd in Frameworks */, BF86E65E26395AD3004C8AE5 /* PowerAuthCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1118,7 +1116,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1500; ORGANIZATIONNAME = "Wultra s.r.o."; TargetAttributes = { BF3ACC842073DBA500B8107E = { @@ -1136,7 +1134,7 @@ }; }; buildConfigurationList = BF3ACC802073DBA500B8107E /* Build configuration list for PBXProject "PowerAuthCore" */; - compatibilityVersion = "Xcode 12.0"; + compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -1548,6 +1546,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = c11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -1567,7 +1566,7 @@ "$(PROJECT_DIR)/../cc7/include", "$(PROJECT_DIR)/../cc7/openssl-lib/apple/include", ); - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/../cc7/openssl-lib/apple"; MACOSX_DEPLOYMENT_TARGET = 10.15; ONLY_ACTIVE_ARCH = YES; @@ -1576,7 +1575,7 @@ openssl, ); SDKROOT = iphoneos; - TVOS_DEPLOYMENT_TARGET = 11.0; + TVOS_DEPLOYMENT_TARGET = 12.0; }; name = Debug; }; @@ -1618,6 +1617,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = c11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -1631,7 +1631,7 @@ "$(PROJECT_DIR)/../cc7/include", "$(PROJECT_DIR)/../cc7/openssl-lib/apple/include", ); - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/../cc7/openssl-lib/apple"; MACOSX_DEPLOYMENT_TARGET = 10.15; OTHER_LDFLAGS = ( @@ -1639,7 +1639,7 @@ openssl, ); SDKROOT = iphoneos; - TVOS_DEPLOYMENT_TARGET = 11.0; + TVOS_DEPLOYMENT_TARGET = 12.0; VALIDATE_PRODUCT = YES; }; name = Release; diff --git a/proj-xcode/PowerAuthCore.xcodeproj/xcshareddata/xcschemes/PowerAuthCoreTests_iOS.xcscheme b/proj-xcode/PowerAuthCore.xcodeproj/xcshareddata/xcschemes/PowerAuthCoreTests_iOS.xcscheme index 0e4311f7..e250beaa 100644 --- a/proj-xcode/PowerAuthCore.xcodeproj/xcshareddata/xcschemes/PowerAuthCoreTests_iOS.xcscheme +++ b/proj-xcode/PowerAuthCore.xcodeproj/xcshareddata/xcschemes/PowerAuthCoreTests_iOS.xcscheme @@ -1,6 +1,6 @@ true } - s.ios.deployment_target = '11.0' - s.tvos.deployment_target = '11.0' + s.ios.deployment_target = '12.0' + s.tvos.deployment_target = '12.0' # XCFramework build s.prepare_command = <<-CMD diff --git a/scripts/templates/PowerAuthCore.podspec b/scripts/templates/PowerAuthCore.podspec index f6d1c3d5..02b2f9b6 100644 --- a/scripts/templates/PowerAuthCore.podspec +++ b/scripts/templates/PowerAuthCore.podspec @@ -22,8 +22,8 @@ Pod::Spec.new do |s| :submodules => true } - s.ios.deployment_target = '11.0' - s.tvos.deployment_target = '11.0' + s.ios.deployment_target = '12.0' + s.tvos.deployment_target = '12.0' # XCFramework build s.prepare_command = <<-CMD From af04440492ac1cf450ac2e0d589d82e924fc99a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Tue, 19 Sep 2023 13:02:18 +0200 Subject: [PATCH 5/9] Fix #544: Final migration to 1.8.0 --- docs/Migration-from-1.7-to-1.8.md | 36 ++++++++++++++++++++++++++++++- docs/Supported-Versions.md | 6 +++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/docs/Migration-from-1.7-to-1.8.md b/docs/Migration-from-1.7-to-1.8.md index 170c5c08..2a151245 100644 --- a/docs/Migration-from-1.7-to-1.8.md +++ b/docs/Migration-from-1.7-to-1.8.md @@ -150,6 +150,8 @@ Visit [Synchronized Time](https://developers.wultra.com/components/powerauth-mob - Removed all interfaces deprecated in release `1.7.x` +- Minimum deployment target updated to iOS 12 and tvOS 12 + ### Other changes #### Synchronized time @@ -207,10 +209,42 @@ Visit [Synchronized Time](https://developers.wultra.com/components/powerauth-mob ### API changes +- `PowerAuthConfiguration` - class now supports only the simplified configuration. + - Use new object constructor with all required parameters: + ```swift + let config = PowerAuthConfiguration( + instanceId: "your-instance-id", + baseEndpointUrl: "https://api.wultra.com/enrollment-server", + configuration: "ARDDj6EB6iA...H9bMk8Ju3K1wmjbA==" + ) + ``` + - Removed `applicationKey`, `applicationSecret`, `masterServerPublicKey`, `disableAutomaticProtocolUpgrade` properties. + - The `PowerAuthAuthentication` object is now immutable object and no longer implement `NSCopying` protocol. +- Removed all interfaces deprecated in release `1.7.x` + +- Minimum deployment target updated to iOS 12 and tvOS 12. + ## watchOS ### API changes -- The `PowerAuthAuthentication` object is now immutable object and no longer implement `NSCopying` protocol. \ No newline at end of file +- `PowerAuthConfiguration` - class now supports only the simplified configuration. + - Use new object constructor with all required parameters: + ```swift + let config = PowerAuthConfiguration( + instanceId: "your-instance-id", + baseEndpointUrl: "https://api.wultra.com/enrollment-server", + configuration: "ARDDj6EB6iA...H9bMk8Ju3K1wmjbA==" + ) + ``` + - Removed `applicationKey`, `applicationSecret`, `masterServerPublicKey`, `disableAutomaticProtocolUpgrade` properties. + +- The `PowerAuthAuthentication` object is now immutable object and no longer implement `NSCopying` protocol. + +- Removed all interfaces deprecated in release `1.7.x` + +## Known Bugs + +The PowerAuth SDKs for iOS and tvOS App Extensions, as well as for watchOS, do not use time synchronized with the server for token-based authentication. To avoid any compatibility issues with the server, the authentication headers generated in your App Extension or on watchOS still use the older protocol version 3.1. This issue will be fixed in a future SDK update. \ No newline at end of file diff --git a/docs/Supported-Versions.md b/docs/Supported-Versions.md index c8705e47..f81eaa2f 100644 --- a/docs/Supported-Versions.md +++ b/docs/Supported-Versions.md @@ -2,8 +2,8 @@ We currently support the following versions of mobile OS: -- iOS 11.0 -- tvOS: 11.0 +- iOS 12.0 +- tvOS: 12.0 - watchOS 4.0 - macOS Catalyst: 10.15 - Android 4.4 (API level 19) @@ -14,7 +14,7 @@ We currently support the following versions of mobile OS: On iOS: -- We offer the biometry support since iOS 9.0, the used biometric type depends on the particular device capabilities. +- The used biometric type depends on the particular device capabilities. On Android: From dc3dd9afe919b8187055d6832574c0958b8fefe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Wed, 20 Sep 2023 13:01:30 +0200 Subject: [PATCH 6/9] Docs: Updated migration to 1.8 (related to PR #552) --- docs/Migration-from-1.7-to-1.8.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/Migration-from-1.7-to-1.8.md b/docs/Migration-from-1.7-to-1.8.md index 2a151245..43214bd1 100644 --- a/docs/Migration-from-1.7-to-1.8.md +++ b/docs/Migration-from-1.7-to-1.8.md @@ -49,11 +49,16 @@ Legacy PowerAuth configuration: - `commitActivationWithAuthentication()` is now `persistActivationWithAuthentication()` - All variants of `commitActivationWithPassword()` are now `persistActivationWithPassword()` - All variants of `commitActivation()` are now `persistActivation()` + - All variants of `authenticateUsingBiometry()` are now using new `IAuthenticateWithBiometryListener` interface returning `PowerAuthAuthentication` in success. - The `ICommitActivationWithBiometryListener` is now deprecated and you can use `IPersistActivationWithBiometryListener` as a replacement. - The `PowerAuthAuthentication` object is now immutable object. +- `PowerAuthErrorCodes` now contains the following new error codes: + - `TIME_SYNCHRONIZATION` indicating a problem with the time synchronization. + - `BIOMETRY_NOT_ENROLLED` indicating that device has no enrolled biometry. + - The biometry-related methods in `PowerAuthSDK` are no longer annotated as `@RequiresApi(api = Build.VERSION_CODES.M)`. This change may lead to a several dead code branches in your code if you still support devices older than Android 6.0. - Removed all interfaces deprecated in release `1.7.x` From cf87854a9fbf7152cb10e3773504c1e6fba4969a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Thu, 21 Sep 2023 13:34:42 +0200 Subject: [PATCH 7/9] Apple: #531: Remove legacy PowerAuthAuthentication constructor --- proj-xcode/PowerAuth2/PowerAuthAuthentication.h | 5 ++++- proj-xcode/PowerAuth2/PowerAuthAuthentication.m | 8 +------- proj-xcode/PowerAuth2Tests/PowerAuthAuthenticationTests.m | 7 ------- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/proj-xcode/PowerAuth2/PowerAuthAuthentication.h b/proj-xcode/PowerAuth2/PowerAuthAuthentication.h index 743d7e7f..914445ea 100644 --- a/proj-xcode/PowerAuth2/PowerAuthAuthentication.h +++ b/proj-xcode/PowerAuth2/PowerAuthAuthentication.h @@ -24,7 +24,10 @@ /** Class representing a multi-factor authentication object. */ -@interface PowerAuthAuthentication : NSObject +@interface PowerAuthAuthentication : NSObject + +/// No longer available. Use static methods instead. +- (nonnull instancetype) init NS_UNAVAILABLE; /// Indicates if a possession factor should be used. @property (nonatomic, readonly, assign) BOOL usePossession; diff --git a/proj-xcode/PowerAuth2/PowerAuthAuthentication.m b/proj-xcode/PowerAuth2/PowerAuthAuthentication.m index fd50c1a5..6504c1aa 100644 --- a/proj-xcode/PowerAuth2/PowerAuthAuthentication.m +++ b/proj-xcode/PowerAuth2/PowerAuthAuthentication.m @@ -88,10 +88,8 @@ - (NSString*) description NSString * usage_str; if (_objectUsage == AUTH_FOR_SIGN) { usage_str = @"for sign"; - } else if (_objectUsage == AUTH_FOR_PERSIST) { - usage_str = @"for persist"; } else { - usage_str = @"legacy"; + usage_str = @"for persist"; } NSMutableArray * factors = [NSMutableArray arrayWithCapacity:3]; if (_usePossession) { @@ -419,10 +417,6 @@ - (NSInteger) signatureFactorMask - (BOOL) validateUsage:(BOOL)forPersist { - if (_objectUsage == 0) { - PowerAuthLog(@"WARNING: Using PowerAuthAuthentication object created with legacy constructor."); - return NO; - } if (forPersist != (_objectUsage == AUTH_FOR_PERSIST)) { if (forPersist) { PowerAuthLog(@"WARNING: Using PowerAuthAuthentication object for a different purpose. The object for activation persist is expected."); diff --git a/proj-xcode/PowerAuth2Tests/PowerAuthAuthenticationTests.m b/proj-xcode/PowerAuth2Tests/PowerAuthAuthenticationTests.m index e54bfd86..046f61f1 100644 --- a/proj-xcode/PowerAuth2Tests/PowerAuthAuthenticationTests.m +++ b/proj-xcode/PowerAuth2Tests/PowerAuthAuthenticationTests.m @@ -269,11 +269,4 @@ - (void) testWrongUsage XCTAssertFalse([auth validateUsage:NO]); } -- (void) testLegacyObject -{ - PowerAuthAuthentication * auth = [[PowerAuthAuthentication alloc] init]; - XCTAssertFalse([auth validateUsage:NO]); - XCTAssertFalse([auth validateUsage:YES]); -} - @end From a9457b5b600325465b05eba325ed9cf5e17cbbd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Thu, 21 Sep 2023 15:08:39 +0200 Subject: [PATCH 8/9] Updated migration guide. --- docs/Migration-from-1.7-to-1.8.md | 6 +++--- proj-android/build.gradle | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/Migration-from-1.7-to-1.8.md b/docs/Migration-from-1.7-to-1.8.md index 43214bd1..d30d9752 100644 --- a/docs/Migration-from-1.7-to-1.8.md +++ b/docs/Migration-from-1.7-to-1.8.md @@ -49,9 +49,9 @@ Legacy PowerAuth configuration: - `commitActivationWithAuthentication()` is now `persistActivationWithAuthentication()` - All variants of `commitActivationWithPassword()` are now `persistActivationWithPassword()` - All variants of `commitActivation()` are now `persistActivation()` - - All variants of `authenticateUsingBiometry()` are now using new `IAuthenticateWithBiometryListener` interface returning `PowerAuthAuthentication` in success. + - All variants of `authenticateUsingBiometry()` are now replaced with `authenticateUsingBiometrics()` with `IAuthenticateWithBiometricsListener` interface returning `PowerAuthAuthentication` in success. -- The `ICommitActivationWithBiometryListener` is now deprecated and you can use `IPersistActivationWithBiometryListener` as a replacement. +- The `ICommitActivationWithBiometryListener` is now deprecated and you can use `IPersistActivationWithBiometricsListener` as a replacement. - The `PowerAuthAuthentication` object is now immutable object. @@ -59,7 +59,7 @@ Legacy PowerAuth configuration: - `TIME_SYNCHRONIZATION` indicating a problem with the time synchronization. - `BIOMETRY_NOT_ENROLLED` indicating that device has no enrolled biometry. -- The biometry-related methods in `PowerAuthSDK` are no longer annotated as `@RequiresApi(api = Build.VERSION_CODES.M)`. This change may lead to a several dead code branches in your code if you still support devices older than Android 6.0. +- The biometry-related methods in `PowerAuthSDK` are no longer annotated as `@RequiresApi(api = Build.VERSION_CODES.M)`. This change may lead to a several dead code branches in your code if you still support devices older than Android 6.0. - Removed all interfaces deprecated in release `1.7.x` diff --git a/proj-android/build.gradle b/proj-android/build.gradle index 06a93eae..36c9eb3b 100644 --- a/proj-android/build.gradle +++ b/proj-android/build.gradle @@ -52,5 +52,9 @@ allprojects { tasks.withType(Javadoc) { options.addStringOption('Xdoclint:-html', '-quiet') } + // Uncomment to show usage of deprecated interfaces +// tasks.withType(JavaCompile) { +// options.compilerArgs << "-Xlint:deprecation" +// } } From b2fe769d7b4fa9c25c0bde8b59c93670b4adbd8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Thu, 21 Sep 2023 15:13:28 +0200 Subject: [PATCH 9/9] Android: Fix #554: Added PowerAuthAuthentication.destroy() --- .../powerauth/biometry/BiometricKeyData.java | 10 ++++ .../sdk/PowerAuthAuthentication.java | 48 +++++++++++++++++-- .../security/powerauth/sdk/PowerAuthSDK.java | 3 ++ 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/biometry/BiometricKeyData.java b/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/biometry/BiometricKeyData.java index ad712a54..e2eeaecc 100644 --- a/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/biometry/BiometricKeyData.java +++ b/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/biometry/BiometricKeyData.java @@ -18,6 +18,8 @@ import androidx.annotation.NonNull; +import java.util.Arrays; + /** * The {@code BiometricKeyData} class contains result from the biometric authentication in case that * authentication succeeded. @@ -61,4 +63,12 @@ public BiometricKeyData(@NonNull byte[] dataToSave, @NonNull byte[] derivedData, public boolean isNewKey() { return newKey; } + + /** + * Destroy potential sensitive content stored in this object. + */ + public void destroy() { + Arrays.fill(dataToSave, (byte) 0xCD); + Arrays.fill(derivedData, (byte) 0xCD); + } } diff --git a/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/sdk/PowerAuthAuthentication.java b/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/sdk/PowerAuthAuthentication.java index 82842f5a..21772277 100644 --- a/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/sdk/PowerAuthAuthentication.java +++ b/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/sdk/PowerAuthAuthentication.java @@ -21,6 +21,8 @@ import io.getlime.security.powerauth.core.Password; import io.getlime.security.powerauth.system.PowerAuthLog; +import java.util.Arrays; + /** * Class representing a multi-factor authentication object. */ @@ -48,9 +50,14 @@ public class PowerAuthAuthentication { /** * Construct object with desired combination of factors. Such authentication object can be used * either to persist activation and for the signature calculation. - * + *

* Note that you should prefer static construction functions instead of this constructor, unless * you have a special reason for it. + *

+ * Note that the constructor internally makes a copy of provided byte arrays. This is because authentication object + * now supports {@link #destroy()} method that clears content of such arrays. We don't want to clear instance of + * array that is still in use somewhere else. + * * * @param persistActivation If true, then authentication can be used to persist activation. * @param password If set, then knowledge factor will be used to persist activation or signature calculation. @@ -62,12 +69,31 @@ public class PowerAuthAuthentication { @Nullable Password password, @Nullable byte[] biometryFactorRelatedKey, @Nullable byte[] overriddenPossessionKey) { - this.useBiometry = biometryFactorRelatedKey; + this.useBiometry = safeArrayCopy(biometryFactorRelatedKey); this.password = password; - this.overriddenPossessionKey = overriddenPossessionKey; + this.overriddenPossessionKey = safeArrayCopy(overriddenPossessionKey); this.persistActivation = persistActivation; } + /** + * Make copy of provided byte array if non-null array is provided. + * @param original Array to safely copy. + * @return new array with copied content or null if input is null. + */ + private static byte[] safeArrayCopy(byte[] original) { + if (original != null) { + return Arrays.copyOf(original, original.length); + } + return null; + } + + /** + * Make sure that the sensitive data is always wiped out from the memory. + */ + protected void finalize() { + destroy(); + } + // Persist activation /** @@ -347,6 +373,22 @@ public byte[] getOverriddenPossessionKey() { return overriddenPossessionKey; } + /** + * Destroys any sensitive content, such as password stored in the authentication object. + * After this call, the object becomes unusable for authentication operations. + */ + public void destroy() { + if (password != null) { + password.destroy(); + } + if (useBiometry != null) { + Arrays.fill(useBiometry, (byte) 0xCD); // This may help with the debugging. CD CD CD is more suspicious than 00 00 00 + } + if (overriddenPossessionKey != null) { + Arrays.fill(overriddenPossessionKey, (byte) 0xCD); + } + } + // Internal interfaces /** diff --git a/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/sdk/PowerAuthSDK.java b/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/sdk/PowerAuthSDK.java index 38f2f54a..585d2330 100644 --- a/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/sdk/PowerAuthSDK.java +++ b/proj-android/PowerAuthLibrary/src/main/java/io/getlime/security/powerauth/sdk/PowerAuthSDK.java @@ -1045,6 +1045,7 @@ public void onBiometricDialogCancelled(boolean userCancel) { public void onBiometricDialogSuccess(@NonNull BiometricKeyData biometricKeyData) { final PowerAuthAuthentication authentication = PowerAuthAuthentication.persistWithPasswordAndBiometry(password, biometricKeyData.getDerivedData()); final int errorCode = persistActivationWithAuthentication(context, authentication); + biometricKeyData.destroy(); if (errorCode == PowerAuthErrorCodes.SUCCEED) { callback.onBiometricDialogSuccess(); } else { @@ -2360,6 +2361,8 @@ public void onBiometricDialogCancelled(boolean userCancel) { @Override public void onBiometricDialogSuccess(@NonNull BiometricKeyData biometricKeyData) { final PowerAuthAuthentication authentication = PowerAuthAuthentication.possessionWithBiometry(biometricKeyData.getDerivedData()); + // TODO: This should be moved in the next release to some global point to make sure that we always clear this object. + biometricKeyData.destroy(); listener.onBiometricDialogSuccess(authentication); }