From 1842a9c74a3265e671755c2dfc6b10e00ac92146 Mon Sep 17 00:00:00 2001 From: Brianna Birman Date: Wed, 12 Aug 2020 23:12:36 -0700 Subject: [PATCH] Passcode deprecations --- .../Common/SalesforceSDKManager+Internal.h | 2 +- .../Classes/Common/SalesforceSDKManager.m | 37 +++++--- .../AppLockView/SFSDKAppLockViewConfig.h | 5 +- .../AppLockView/SFSDKAppLockViewConfig.m | 2 + .../AppLockView/SFSDKAppLockViewController.h | 2 +- .../AppLockView/SFSDKAppLockViewController.m | 16 ++++ .../SFSDKPasscodeCreateController.m | 6 +- .../AppLockView/SFSDKPasscodeTextField.m | 2 + .../SFSDKPasscodeVerifyController.m | 8 ++ .../Security/SFKeyStoreManager+Internal.h | 2 +- .../Classes/Security/SFKeyStoreManager.m | 5 +- .../Security/SFPBKDF2PasscodeProvider.h | 3 +- .../Security/SFPBKDF2PasscodeProvider.m | 4 + .../Classes/Security/SFPasscodeKeyStore.m | 3 +- .../Security/SFPasscodeManager+Internal.h | 1 + .../Classes/Security/SFPasscodeManager.h | 33 ++++---- .../Classes/Security/SFPasscodeManager.m | 23 +++-- .../Security/SFPasscodeProviderManager.h | 7 +- .../Security/SFPasscodeProviderManager.m | 3 + .../Classes/Security/SFSDKCryptoUtils.h | 28 ++++++- .../Classes/Security/SFSDKCryptoUtils.m | 24 +++++- .../Security/SFSHA256PasscodeProvider.h | 2 + .../Security/SFSHA256PasscodeProvider.m | 4 + .../Security/SFSecurityLockout+Internal.h | 1 + .../Classes/Security/SFSecurityLockout.h | 80 ++++++++++-------- .../Classes/Security/SFSecurityLockout.m | 84 +++++++++++++++---- .../UserAccount/SFUserAccountManager.m | 4 +- .../RestAPIExplorer/AppDelegate.swift | 1 - 28 files changed, 288 insertions(+), 104 deletions(-) diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Common/SalesforceSDKManager+Internal.h b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Common/SalesforceSDKManager+Internal.h index c80a561e95..a8b072b835 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Common/SalesforceSDKManager+Internal.h +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Common/SalesforceSDKManager+Internal.h @@ -27,7 +27,7 @@ @end -@interface SalesforceSDKManager () +@interface SalesforceSDKManager () { BOOL _isLaunching; UIViewController* _snapshotViewController; diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Common/SalesforceSDKManager.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Common/SalesforceSDKManager.m index 48b4278db9..43a12d7e6d 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Common/SalesforceSDKManager.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Common/SalesforceSDKManager.m @@ -216,7 +216,6 @@ - (instancetype)init { #endif self.sdkManagerFlow = self; self.delegates = [NSHashTable weakObjectsHashTable]; - [SFSecurityLockout addDelegate:self]; [[NSNotificationCenter defaultCenter] addObserver:self.sdkManagerFlow selector:@selector(handleAppForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self.sdkManagerFlow selector:@selector(handleAppBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self.sdkManagerFlow selector:@selector(handleAppTerminate:) name:UIApplicationWillTerminateNotification object:nil]; @@ -233,10 +232,14 @@ - (instancetype)init { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUserWillLogout:) name:kSFNotificationUserWillLogout object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self.sdkManagerFlow selector:@selector(handleUserDidLogout:) name:kSFNotificationUserDidLogout object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUserWillSwitch:) name:kSFNotificationUserWillSwitch object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUserDidSwitch:) name:kSFNotificationUserDidSwitch object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUserWillSwitch:) name:kSFNotificationUserWillSwitch object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUserDidSwitch:) name:kSFNotificationUserDidSwitch object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(passcodeFlowWillBegin:) name:kSFPasscodeFlowWillBegin object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(passcodeFlowDidComplete:) name:kSFPasscodeFlowCompleted object:nil]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in MobileSDK 9.0 [SFPasscodeManager sharedManager].preferredPasscodeProvider = kSFPasscodeProviderPBKDF2; + SFSDK_USE_DEPRECATED_END self.useSnapshotView = YES; [self computeWebViewUserAgent]; // web view user agent is computed asynchronously so very first call to self.userAgentString(...) will be missing it self.userAgentString = [self defaultUserAgentString]; @@ -697,8 +700,9 @@ - (void)handleAppForeground:(NSNotification *)notification [SFSDKCoreLogger i:[self class] format:@"Passcode validation succeeded, or was not required, on app foreground. Triggering postAppForeground handler."]; [self sendPostAppForegroundIfRequired]; }]; - + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [SFSecurityLockout validateTimer]; + SFSDK_USE_DEPRECATED_END } } } @@ -782,14 +786,18 @@ - (void)handleAppWillResignActive:(NSNotification *)notification - (void)handleAuthCompleted:(NSNotification *)notification { // Will set up the passcode timer for auth that occurs out of band from SDK Manager launch. + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [SFSecurityLockout setupTimer]; + SFSDK_USE_DEPRECATED_END [SFSecurityLockout startActivityMonitoring]; } - (void)handleIDPInitiatedAuthCompleted:(NSNotification *)notification { // Will set up the passcode timer for auth that occurs out of band from SDK Manager launch. + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [SFSecurityLockout setupTimer]; + SFSDK_USE_DEPRECATED_END [SFSecurityLockout startActivityMonitoring]; NSDictionary *userInfo = notification.userInfo; SFUserAccount *userAccount = userInfo[kSFNotificationUserInfoAccountKey]; @@ -804,7 +812,9 @@ - (void)handleIDPUserAddCompleted:(NSNotification *)notification SFUserAccount *userAccount = userInfo[kSFNotificationUserInfoAccountKey]; // this is the only user context in the idp app. if ([userAccount isEqual:[SFUserAccountManager sharedInstance].currentUser]) { + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [SFSecurityLockout setupTimer]; + SFSDK_USE_DEPRECATED_END [SFSecurityLockout startActivityMonitoring]; [[SFUserAccountManager sharedInstance] switchToUser:userAccount]; [self sendPostLaunch]; @@ -820,6 +830,7 @@ - (void)handlePostLogout // Close the passcode screen and reset passcode monitoring. [SFSecurityLockout cancelPasscodeScreen]; [SFSecurityLockout stopActivityMonitoring]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [SFSecurityLockout removeTimer]; [self sendPostLogout]; } @@ -841,6 +852,7 @@ - (void)handleUserDidSwitch:(SFUserAccount *)fromUser toUser:(SFUserAccount *)to - (void)savePasscodeActivityInfo { [SFSecurityLockout removeTimer]; + SFSDK_USE_DEPRECATED_END [SFInactivityTimerCenter saveActivityTimestamp]; } @@ -888,7 +900,8 @@ - (void)dismissSnapshot if ([self isSnapshotPresented]) { if (self.snapshotPresentationAction && self.snapshotDismissalAction) { self.snapshotDismissalAction(_snapshotViewController); - if ([SFSecurityLockout isPasscodeNeeded]) { + if ([SFSecurityLockout shouldLock]) { + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [SFSecurityLockout validateTimer]; } } else { @@ -896,6 +909,7 @@ - (void)dismissSnapshot [[SFSDKWindowManager sharedManager].snapshotWindow dismissWindowAnimated:NO withCompletion:^{ if ([SFSecurityLockout isPasscodeNeeded]) { [SFSecurityLockout validateTimer]; + SFSDK_USE_DEPRECATED_END } }]; }]; @@ -957,7 +971,9 @@ - (void)authAtLaunch SFUserAccountManagerSuccessCallbackBlock successBlock = ^(SFOAuthInfo *authInfo,SFUserAccount *userAccount) { [SFSDKCoreLogger i:[self class] format:@"Authentication (%@) succeeded. Launch completed.", authInfo.authTypeDescription]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [SFSecurityLockout setupTimer]; + SFSDK_USE_DEPRECATED_END [SFSecurityLockout startActivityMonitoring]; [self authValidatedToPostAuth:SFSDKLaunchActionAuthenticated]; }; @@ -992,7 +1008,9 @@ - (void)authBypassAtLaunch // stays on the screen, masking the main UI. [[SFUserAccountManager sharedInstance] dismissAuthViewControllerIfPresent]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [SFSecurityLockout setupTimer]; + SFSDK_USE_DEPRECATED_END [SFSecurityLockout startActivityMonitoring]; [self authValidatedToPostAuth:noAuthLaunchAction]; } @@ -1138,18 +1156,17 @@ - (void)userAccountManager:(SFUserAccountManager *)userAccountManager [self.sdkManagerFlow handleUserDidSwitch:fromUser toUser:toUser]; } -#pragma mark - SFSecurityLockoutDelegate +#pragma mark - SFSecurityLockout -- (void)passcodeFlowWillBegin:(SFAppLockControllerMode)mode -{ +- (void)passcodeFlowWillBegin:(NSNotification *)notification { self.passcodeDisplayed = YES; } -- (void)passcodeFlowDidComplete:(BOOL)success -{ +- (void)passcodeFlowDidComplete:(NSNotification *)notification { self.passcodeDisplayed = NO; [self sendPostAppForegroundIfRequired]; } + @end NSString *SFAppTypeGetDescription(SFAppType appType){ diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewConfig.h b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewConfig.h index 781baff4fe..3522cd3381 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewConfig.h +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewConfig.h @@ -29,6 +29,7 @@ #import #import "SFSDKViewControllerConfig.h" +#import "SalesforceSDKConstants.h" NS_ASSUME_NONNULL_BEGIN @@ -46,7 +47,7 @@ NS_SWIFT_NAME(AppLockViewControllerConfig) * but users will be unable to unlock the app if their pin is longer than the specified * length. */ -@property (nonatomic) BOOL forcePasscodeLength; +@property (nonatomic) BOOL forcePasscodeLength SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** * The number of allowed passcode entry attempts before the user is logged out. @@ -121,7 +122,7 @@ NS_SWIFT_NAME(AppLockViewControllerConfig) /** * Length of the user's passcode. */ -@property (nonatomic) NSUInteger passcodeLength; +@property (nonatomic) NSUInteger passcodeLength SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); @end diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewConfig.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewConfig.m index 3133ad8d80..1f52ff62b2 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewConfig.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewConfig.m @@ -54,7 +54,9 @@ -(instancetype) init { _buttonFont = [UIFont systemFontOfSize:14 weight:UIFontWeightBold]; _touchIdImage = [SFSDKResourceUtils imageNamed:@"touchId"]; _faceIdImage = [SFSDKResourceUtils imageNamed:@"faceId"]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 _passcodeLength = [SFSecurityLockout passcodeLength]; + SFSDK_USE_DEPRECATED_END } return self; } diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewController.h b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewController.h index 89e84846ea..5fd6d848ec 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewController.h +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewController.h @@ -32,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN -NS_SWIFT_NAME(AppLockViewController) +NS_SWIFT_NAME(AppLockViewController) SFSDK_DEPRECATED(8.3, 9.0, "Will be internal.") @interface SFSDKAppLockViewController : SFSDKNavigationController - (instancetype)initWithMode:(SFAppLockControllerMode)mode andViewConfig:(SFSDKAppLockViewConfig *)config; diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewController.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewController.m index 11c978a651..030f2f5587 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewController.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/AppLockView/SFSDKAppLockViewController.m @@ -36,6 +36,7 @@ #import "SFSDKWindowManager.h" #import "SFSecurityLockout.h" #import "SFSDKViewUtils.h" +#import "SFSecurityLockout+Internal.h" @interface SFSDKAppLockViewController () @@ -46,7 +47,10 @@ @interface SFSDKAppLockViewController () +@interface SFKeyStoreManager () @property (nonatomic, strong) SFGeneratedKeyStore *generatedKeyStore; diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFKeyStoreManager.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFKeyStoreManager.m index abcd78ac5d..c5cacdb752 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFKeyStoreManager.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFKeyStoreManager.m @@ -55,7 +55,9 @@ - (id)init self = [super init]; if (self) { [self initializeKeyStores]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [[SFPasscodeManager sharedManager] addObserver:self forKeyPath:@"encryptionKey" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:NULL]; + SFSDK_USE_DEPRECATED_END } return self; } @@ -214,7 +216,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N // Starting in SDK 6.0, we no longer use SFPasscodeKeyStore. // The only reason we are still watching the encryption key of the passcode manager is to handle upgrade from pre-6.0 SDK to 6+. // As soon as we get the passcode, we migrate all the keys from the passcode key store to the generated key store. - + SFSDK_USE_DEPRECATED_BEGIN if (!(object == [SFPasscodeManager sharedManager] && [keyPath isEqualToString:@"encryptionKey"])) { return; } @@ -227,7 +229,6 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N if ([oldKey length] == 0 && [newKey length] > 0) { // We just got the passcode, migrate keys (if any) - SFSDK_USE_DEPRECATED_BEGIN SFPasscodeKeyStore *passcodeKeyStore = [[SFPasscodeKeyStore alloc] init]; passcodeKeyStore.keyStoreKey.encryptionKey.key = [[self class] keyStringToData:newKey]; if (passcodeKeyStore.keyStoreKey != nil && passcodeKeyStore.keyStoreDictionary.count > 0) { diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPBKDF2PasscodeProvider.h b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPBKDF2PasscodeProvider.h index 38a2458517..4de447d09c 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPBKDF2PasscodeProvider.h +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPBKDF2PasscodeProvider.h @@ -24,13 +24,14 @@ #import #import "SFPasscodeProviderManager.h" +#import "SalesforceSDKConstants.h" NS_ASSUME_NONNULL_BEGIN /** * Contains configuration values for generating an encryption key. */ - +SFSDK_DEPRECATED(8.3, 9.0, "Will be removed and passcode will be managed internally.") @interface SFPBKDF2PasscodeProvider : NSObject /** diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPBKDF2PasscodeProvider.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPBKDF2PasscodeProvider.m index b24fac0a10..0e9f6f0186 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPBKDF2PasscodeProvider.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPBKDF2PasscodeProvider.m @@ -40,7 +40,11 @@ - (void)setPasscodeData:(SFPBKDFData *)passcodeData keychainId:(NSString *)keych @end +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" @implementation SFPBKDF2PasscodeProvider +#pragma clang diagnostic pop + @synthesize passcodeLength; @synthesize saltLengthInBytes = _saltLengthInBytes; @synthesize numDerivationRounds = _numDerivationRounds; diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeKeyStore.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeKeyStore.m index 1459ee34a8..f1af63b3b3 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeKeyStore.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeKeyStore.m @@ -27,6 +27,7 @@ #import "SFPasscodeManager.h" #import "SFKeyStoreManager+Internal.h" #import "SFKeychainItemWrapper.h" +#import "SFSecurityLockout.h" // Keychain and NSCoding constants static NSString * const kPasscodeKeyStoreKeychainIdentifier = @"com.salesforce.keystore.passcodeKeystoreKeychainId"; @@ -74,7 +75,7 @@ - (BOOL)keyStoreAvailable - (BOOL)keyStoreEnabled { - return [[SFPasscodeManager sharedManager] passcodeIsSet]; + return [SFSecurityLockout isPasscodeSet]; } - (SFKeyStoreKey *)keyStoreKey diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager+Internal.h b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager+Internal.h index 822ef4f216..d8229a14df 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager+Internal.h +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager+Internal.h @@ -24,6 +24,7 @@ #import "SFPasscodeManager.h" +SFSDK_DEPRECATED(8.3, 9.0, "Will be removed.") @interface SFPasscodeManager () @property (nonatomic, strong, nonnull) NSHashTable> *delegates; diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager.h b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager.h index 3b93ef44b1..ba75e7a97c 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager.h +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager.h @@ -23,6 +23,7 @@ */ #import +#import "SalesforceSDKConstants.h" NS_ASSUME_NONNULL_BEGIN @@ -31,26 +32,27 @@ NS_ASSUME_NONNULL_BEGIN populated with old passcode stored with `SFPasscodeResetOldPasscodeKey` key and new passcode stored with `SFPasscodeResetNewPasscodeKey` key. */ -extern NSString *const SFPasscodeResetNotification; +extern NSString *const SFPasscodeResetNotification SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Key in userInfo published by `SFPasscodeResetNotification`. The value of this key is the old hashed passcode before the passcode reset */ -extern NSString *const SFPasscodeResetOldPasscodeKey; +extern NSString *const SFPasscodeResetOldPasscodeKey SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Key in userInfo published by `SFPasscodeResetNotification`. The value of this key is the new hashed passcode that triggers the new passcode reset */ -extern NSString *const SFPasscodeResetNewPasscodeKey; +extern NSString *const SFPasscodeResetNewPasscodeKey SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); @class SFPasscodeManager; /** Delegate protocol for SFPasscodeManager callbacks */ +SFSDK_DEPRECATED(8.3, 9.0, "Will be removed.") @protocol SFPasscodeManagerDelegate @optional @@ -68,63 +70,64 @@ extern NSString *const SFPasscodeResetNewPasscodeKey; /** Class for managing storage, retrieval, and verification of passcodes. */ +SFSDK_DEPRECATED(8.3, 9.0, "Will be removed.") @interface SFPasscodeManager : NSObject /** @return The shared instance of the passcode manager. */ -+ (SFPasscodeManager *)sharedManager; ++ (SFPasscodeManager *)sharedManager SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** The encryption key associated with the app. */ -@property (nonatomic, readonly, nullable) NSString *encryptionKey; +@property (nonatomic, readonly, nullable) NSString *encryptionKey SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** The preferred passcode provider for the app. If another provider was previously configured, the passcode manager will automatically update to the preferred provider at the next passcode update or verification. */ -@property (nonatomic, copy) NSString *preferredPasscodeProvider; +@property (nonatomic, copy) NSString *preferredPasscodeProvider SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** The lenght of the user's passcode. */ -@property (nonatomic) NSUInteger passcodeLength; +@property (nonatomic) NSUInteger passcodeLength SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Whether the device has the capability to use biometric unlock. */ -@property (nonatomic) BOOL deviceHasBiometric; +@property (nonatomic) BOOL deviceHasBiometric SFSDK_DEPRECATED(8.3, 9.0, "Use deviceHasBiometric on SFSecurityLockout instead"); /** Adds a delegate to the list of passcode manager delegates. @param delegate Delegate to add to the list. */ -- (void)addDelegate:(id)delegate; +- (void)addDelegate:(id)delegate SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Removes a delegate from the delegate list. No action is taken if the delegate does not exist. @param delegate Delegate to be removed. */ -- (void)removeDelegate:(id)delegate; +- (void)removeDelegate:(id)delegate SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** @return Whether or not a passcode has been set. */ -- (BOOL)passcodeIsSet; +- (BOOL)passcodeIsSet SFSDK_DEPRECATED(8.3, 9.0, "Use isPasscodeSet on SFSecurityLockout instead."); /** Reset the passcode in the keychain. */ -- (void)resetPasscode; +- (void)resetPasscode SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Verify the passcode. @param passcode The passcode to verify. @return YES if the passcode verifies, NO otherwise. */ -- (BOOL)verifyPasscode:(NSString *)passcode; +- (BOOL)verifyPasscode:(NSString *)passcode SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Change the current passcode. This method serves as an entry point for managing the change @@ -133,13 +136,13 @@ extern NSString *const SFPasscodeResetNewPasscodeKey; @param newPasscode The new passcode to change to. If nil or empty, this method will unset the existing passcode. */ -- (void)changePasscode:(nullable NSString *)newPasscode; +- (void)changePasscode:(nullable NSString *)newPasscode SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Set the passcode. @param newPasscode The passcode to set. */ -- (void)setPasscode:(NSString *)newPasscode; +- (void)setPasscode:(NSString *)newPasscode SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); @end diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager.m index 3b4c3bb5b9..1159ba4ad8 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeManager.m @@ -24,10 +24,13 @@ #import "SFPasscodeManager+Internal.h" #import "SFPasscodeProviderManager.h" -#import #import "SFKeychainItemWrapper.h" +#import "SFSecurityLockout+Internal.h" +#import "SFSecurityLockout.h" +SFSDK_USE_DEPRECATED_BEGIN static SFPasscodeManager *sharedInstance = nil; +SFSDK_USE_DEPRECATED_END // // Public constants @@ -43,7 +46,10 @@ // Key in userInfo published by `SFPasscodeResetNotification` to store the new hashed passcode that triggers the new passcode reset NSString *const SFPasscodeResetNewPasscodeKey = @"SFPasscodeResetNewPasswordKey"; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" @implementation SFPasscodeManager +#pragma clang diagnostic pop @synthesize encryptionKey = _encryptionKey; @synthesize preferredPasscodeProvider = _preferredPasscodeProvider; @@ -111,7 +117,7 @@ - (void)enumerateDelegates:(void (^)(id))block } #pragma mark - Passcode management - +SFSDK_USE_DEPRECATED_BEGIN - (void)setEncryptionKeyForPasscode:(NSString *)passcode { id currentProvider = [SFPasscodeProviderManager currentPasscodeProvider]; @@ -167,6 +173,7 @@ - (BOOL)verifyPasscode:(NSString *)passcode return [currentProvider verifyPasscode:passcode]; } } +SFSDK_USE_DEPRECATED_END - (void)changePasscode:(NSString *)newPasscode { @@ -220,7 +227,6 @@ - (void)setPasscode:(NSString *)newPasscode [SFPasscodeProviderManager setCurrentPasscodeProviderByName:preferredProvider.providerName]; currentProvider = [SFPasscodeProviderManager currentPasscodeProvider]; } - [currentProvider setVerificationPasscode:newPasscode]; NSString *encryptionKey = [currentProvider generateEncryptionKey:newPasscode]; [self setEncryptionKey:encryptionKey]; @@ -232,15 +238,8 @@ - (NSUInteger)passcodeLength return self.passcodeLength; } -- (BOOL)deviceHasBiometric -{ - LAContext *context = [[LAContext alloc] init]; - NSError *biometricError; - BOOL deviceHasBiometric = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&biometricError]; - if (!deviceHasBiometric) { - [SFSDKCoreLogger d:[self class] format:@"Device cannot use Touch Id or Face Id. Error: %@", biometricError]; - } - return deviceHasBiometric; +- (BOOL)deviceHasBiometric { + return [SFSecurityLockout deviceHasBiometric]; } @end diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeProviderManager.h b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeProviderManager.h index a2a6b0b2a6..69709b0464 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeProviderManager.h +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeProviderManager.h @@ -23,6 +23,7 @@ */ #import +#import "SalesforceSDKConstants.h" NS_ASSUME_NONNULL_BEGIN @@ -35,16 +36,17 @@ typedef NSString * SFPasscodeProviderId NS_EXTENSIBLE_STRING_ENUM; /** * String representing the provider name for the SHA-256 passcode provider. */ -FOUNDATION_EXTERN SFPasscodeProviderId const kSFPasscodeProviderSHA256; +FOUNDATION_EXTERN SFPasscodeProviderId const kSFPasscodeProviderSHA256 SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** * String representing the provider name for the PBKDF2 passcode provider. */ -FOUNDATION_EXTERN SFPasscodeProviderId const kSFPasscodeProviderPBKDF2; +FOUNDATION_EXTERN SFPasscodeProviderId const kSFPasscodeProviderPBKDF2 SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** * Protocol that a passcode provider class must implement. */ +SFSDK_DEPRECATED(8.3, 9.0, "Will be removed and passcode will be managed internally.") @protocol SFPasscodeProvider /** @@ -103,6 +105,7 @@ FOUNDATION_EXTERN SFPasscodeProviderId const kSFPasscodeProviderPBKDF2; /** * Class for managing passcode providers. */ +SFSDK_DEPRECATED(8.3, 9.0, "Will be removed and passcode will be managed internally.") @interface SFPasscodeProviderManager : NSObject /** diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeProviderManager.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeProviderManager.m index 32909edf2d..0f99541121 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeProviderManager.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFPasscodeProviderManager.m @@ -37,7 +37,10 @@ static NSMutableDictionary *PasscodeProviderMap; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" @implementation SFPasscodeProviderManager +#pragma clang diagnostic pop + (void)initialize { diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSDKCryptoUtils.h b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSDKCryptoUtils.h index 8068ead666..38387b02b5 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSDKCryptoUtils.h +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSDKCryptoUtils.h @@ -23,6 +23,7 @@ */ #import +#import "SalesforceSDKConstants.h" NS_ASSUME_NONNULL_BEGIN @@ -63,7 +64,16 @@ extern NSUInteger const kSFPBKDFDefaultSaltByteLength; * @param stringToHash Plain-text string used to generate the key. * @return `SFPBKDFData` object representing the derived key. */ -+ (SFPBKDFData *)createPBKDF2DerivedKey:(NSString *)stringToHash; ++ (SFPBKDFData *)createPBKDF2DerivedKey:(NSString *)stringToHash SFSDK_DEPRECATED(8.3, 9.0, "Use pbkdf2DerivedKey: instead."); + +/** + * Creates a PBKDF2 derived key from an input key string. Uses default values for the + * random-generated salt data and its length, the number of derivation rounds, and the + * derived key length. + * @param stringToHash Plain-text string used to generate the key. + * @return The derived key. + */ ++ (nullable NSData *)pbkdf2DerivedKey:(NSString *)stringToHash; /** * Creates a PBKDF2-derived key from an input key string, a salt, number of derivation @@ -77,7 +87,21 @@ extern NSUInteger const kSFPBKDFDefaultSaltByteLength; + (nullable SFPBKDFData *)createPBKDF2DerivedKey:(NSString *)stringToHash salt:(NSData *)salt derivationRounds:(NSUInteger)numDerivationRounds - keyLength:(NSUInteger)derivedKeyLength; + keyLength:(NSUInteger)derivedKeyLength SFSDK_DEPRECATED(8.3, 9.0, "Use pbkdf2DerivedKey:salt:derivationRounds:keyLength: instead."); + +/** + * Creates a PBKDF2-derived key from an input key string, a salt, number of derivation + * rounds, and the given derived key length. + * @param stringToHash Base string to use for the derived key. + * @param salt Salt to append to the string. + * @param numDerivationRounds Number of derivation rounds used to generate the key. + * @param derivedKeyLength Requested derived key length. + * @return The derived key. + */ ++ (nullable NSData *)pbkdf2DerivedKey:(NSString *)stringToHash + salt:(NSData *)salt + derivationRounds:(NSUInteger)numDerivationRounds + keyLength:(NSUInteger)derivedKeyLength; /** * Encrypt the given data using the AES-128 algorithm. diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSDKCryptoUtils.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSDKCryptoUtils.m index aa46695345..55d2129ad6 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSDKCryptoUtils.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSDKCryptoUtils.m @@ -124,11 +124,31 @@ + (SFPBKDFData *)createPBKDF2DerivedKey:(NSString *)stringToHash keyLength:kSFPBKDFDefaultDerivedKeyByteLength]; } ++ (nullable NSData *)pbkdf2DerivedKey:(NSString *)stringToHash { + NSData *salt = [SFSDKCryptoUtils randomByteDataWithLength:kSFPBKDFDefaultSaltByteLength]; + return [SFSDKCryptoUtils pbkdf2DerivedKey:stringToHash + salt:salt + derivationRounds:kSFPBKDFDefaultNumberOfDerivationRounds + keyLength:kSFPBKDFDefaultDerivedKeyByteLength]; +} + + (SFPBKDFData *)createPBKDF2DerivedKey:(NSString *)stringToHash salt:(NSData *)salt derivationRounds:(NSUInteger)numDerivationRounds keyLength:(NSUInteger)derivedKeyLength { + NSData *keyData = [SFSDKCryptoUtils pbkdf2DerivedKey:stringToHash salt:salt derivationRounds:numDerivationRounds keyLength:derivedKeyLength]; + if (keyData) { + return [[SFPBKDFData alloc] initWithKey:keyData salt:salt derivationRounds:numDerivationRounds derivedKeyLength:derivedKeyLength]; + } else { + return nil; + } +} + ++ (nullable NSData *)pbkdf2DerivedKey:(NSString *)stringToHash + salt:(NSData *)salt + derivationRounds:(NSUInteger)numDerivationRounds + keyLength:(NSUInteger)derivedKeyLength { NSData *stringToHashAsData = [stringToHash dataUsingEncoding:NSUTF8StringEncoding]; unsigned char key[derivedKeyLength]; int result = CCKeyDerivationPBKDF(kCCPBKDF2, [stringToHashAsData bytes], [stringToHashAsData length], [salt bytes], [salt length], kCCPRFHmacAlgSHA256, (uint)numDerivationRounds, key, derivedKeyLength); @@ -137,9 +157,7 @@ + (SFPBKDFData *)createPBKDF2DerivedKey:(NSString *)stringToHash // Error return nil; } else { - NSData *keyData = [NSData dataWithBytes:key length:derivedKeyLength]; - SFPBKDFData *returnPBKDFData = [[SFPBKDFData alloc] initWithKey:keyData salt:salt derivationRounds:numDerivationRounds derivedKeyLength:derivedKeyLength]; - return returnPBKDFData; + return [NSData dataWithBytes:key length:derivedKeyLength]; } } diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSHA256PasscodeProvider.h b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSHA256PasscodeProvider.h index 8b3dcda20e..735bc77d33 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSHA256PasscodeProvider.h +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSHA256PasscodeProvider.h @@ -24,12 +24,14 @@ #import #import "SFPasscodeProviderManager.h" +#import "SalesforceSDKConstants.h" NS_ASSUME_NONNULL_BEGIN /** * Passcode provider for passcodes hashed with the SHA-256 algorithm. */ +SFSDK_DEPRECATED(8.3, 9.0, "Will be removed and passcode will be managed internally.") @interface SFSHA256PasscodeProvider : NSObject @end diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSHA256PasscodeProvider.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSHA256PasscodeProvider.m index 618cb32b80..31e18d3b86 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSHA256PasscodeProvider.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSHA256PasscodeProvider.m @@ -31,7 +31,11 @@ static NSString * const kKeychainIdentifierPasscode = @"com.salesforce.security.passcode"; static NSString * const kKeychainIdentifierPasscodeLength = @"com.salesforce.security.passcodeLength"; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" @implementation SFSHA256PasscodeProvider +#pragma clang diagnostic pop + @synthesize passcodeLength; @synthesize providerName = _providerName; diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout+Internal.h b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout+Internal.h index 710c298480..d4215501a6 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout+Internal.h +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout+Internal.h @@ -9,6 +9,7 @@ static NSString * _Nullable const kSecurityIsLockedLegacyKey = @"security.islock static NSString * const kBiometricUnlockAllowedKey = @"security.biometric.allowed"; // Enabled in the Org static NSString * const kBiometricStateKey = @"secuirty.biometric.state"; +SFSDK_DEPRECATED(8.3, 9.0, "Will be internal.") @interface SFSecurityLockout () /** diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout.h b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout.h index 3b2e331073..e0af285142 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout.h +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout.h @@ -26,6 +26,7 @@ #import #import "SFAppLockViewControllerTypes.h" +#import "SalesforceSDKConstants.h" NS_ASSUME_NONNULL_BEGIN @@ -94,7 +95,7 @@ typedef NS_ENUM(NSUInteger, SFBiometricUnlockState) { Biometric unlock is not available. */ SFBiometricUnlockUnavailable -}NS_SWIFT_NAME(BiometricUnlockState); +} NS_SWIFT_NAME(BiometricUnlockState); @class SFSDKAppLockViewConfig; @@ -119,21 +120,22 @@ typedef void (^SFLockScreenFailureCallbackBlock)(void); /** Block typedef for creating the passcode view controller. */ -typedef UIViewController* _Nullable (^SFPasscodeViewControllerCreationBlock)(SFAppLockControllerMode mode,SFSDKAppLockViewConfig *viewConfig); +typedef UIViewController* _Nullable (^SFPasscodeViewControllerCreationBlock)(SFAppLockControllerMode mode,SFSDKAppLockViewConfig *viewConfig) SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Block typedef for displaying and dismissing the passcode view controller. */ -typedef void (^SFPasscodeViewControllerPresentationBlock)(UIViewController*); +typedef void (^SFPasscodeViewControllerPresentationBlock)(UIViewController*) SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Block typedef for displaying and dismissing the passcode view controller. */ -typedef void (^SFPasscodeViewControllerDismissBlock)(UIViewController*,void(^_Nullable)(void)); +typedef void (^SFPasscodeViewControllerDismissBlock)(UIViewController*,void(^_Nullable)(void)) SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Delegate protocol for SFSecurityLockout events and callbacks. */ +SFSDK_DEPRECATED(8.3, 9.0, "Use notifications or SFLockScreenSuccessCallbackBlock and SFLockScreenFailureCallbackBlock instead") @protocol SFSecurityLockoutDelegate @optional @@ -170,25 +172,25 @@ typedef void (^SFPasscodeViewControllerDismissBlock)(UIViewController*,void(^_Nu Adds a delegate to the list of SFSecurityLockout delegates. @param delegate The delegate to add to the list. */ -+ (void)addDelegate:(id)delegate; ++ (void)addDelegate:(id)delegate SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Removes a delegate from the list of SFSecurityLockout delegates. @param delegate The delegate to remove from the list. */ -+ (void)removeDelegate:(id)delegate; ++ (void)removeDelegate:(id)delegate SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Get the current lockout time, in seconds @return The lockout time limit. */ -+ (NSUInteger)lockoutTime; ++ (NSUInteger)lockoutTime SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Gets the configured passcode length. @return The passcode length. */ -+ (NSUInteger)passcodeLength; ++ (NSUInteger)passcodeLength SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** The current state of biometric unlock. @@ -212,26 +214,26 @@ typedef void (^SFPasscodeViewControllerDismissBlock)(UIViewController*,void(^_Nu policy. I.e. passcode state can only be cleared if the current user is the only user who would be subject to that policy. */ -+ (void)clearPasscodeState; ++ (void)clearPasscodeState SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Resets the passcode state of the app, *if* there aren't other users with an overriding passcode policy. I.e. passcode state can only be cleared if the user is the only user who would be subject to that policy. */ -+ (void)clearPasscodeState:(SFUserAccount *)userLoggingOut; ++ (void)clearPasscodeState:(SFUserAccount *)userLoggingOut SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Initialize the timer */ -+ (void)setupTimer; ++ (void)setupTimer SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Unregister and invalidate the timer */ -+ (void)removeTimer; ++ (void)removeTimer SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Validate the timer upon app entering the foreground */ -+ (void)validateTimer; ++ (void)validateTimer SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Check if passcode is enabled. @return `YES` if passcode is enabled and required. @@ -260,33 +262,45 @@ typedef void (^SFPasscodeViewControllerDismissBlock)(UIViewController*,void(^_Nu /** Unlock the device (e.g a result of a successful passcode/biometric challenge) @param action Action that was taken during lockout. */ -+ (void)unlock:(SFSecurityLockoutAction)action; ++ (void)unlock:(SFSecurityLockoutAction)action SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Wipe the device (e.g. because passcode/biometric challenge failed) */ -+ (void)wipeState; ++ (void)wipeState SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Toggle the locked state @param locked Locks the device if `YES`, otherwise unlocks the device. */ -+ (void)setIsLocked:(BOOL)locked; ++ (void)setIsLocked:(BOOL)locked SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Check if device is locked */ -+ (BOOL)locked; ++ (BOOL)locked SFSDK_DEPRECATED(8.3, 9.0, "Will be internal"); /** Check if the passcode is valid */ -+ (BOOL)isPasscodeValid; ++ (BOOL)isPasscodeValid SFSDK_DEPRECATED(8.3, 9.0, "Will be internal."); /** Check to see if the passcode screen is needed. */ -+ (BOOL)isPasscodeNeeded; ++ (BOOL)isPasscodeNeeded SFSDK_DEPRECATED(8.3, 9.0, "Use shouldLock instead."); + + /** Whether or not a passcode has been set. + */ ++ (BOOL)isPasscodeSet; + +/** Whether screen should be locked or not. + */ ++ (BOOL)shouldLock; + +/** Whether the device has the capability to use biometric unlock. + */ ++ (BOOL)deviceHasBiometric; /** Show the passcode view. Used by unit tests. @param showPasscode If YES, passcode view can be displayed. */ -+ (void)setCanShowPasscode:(BOOL)showPasscode; ++ (void)setCanShowPasscode:(BOOL)showPasscode SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Sets the callback block to be called on any action that triggers screen lock, and unlocks @@ -315,49 +329,49 @@ typedef void (^SFPasscodeViewControllerDismissBlock)(UIViewController*,void(^_Nu /** @return The block used to create the passcode view controller */ -+ (SFPasscodeViewControllerCreationBlock)passcodeViewControllerCreationBlock; ++ (SFPasscodeViewControllerCreationBlock)passcodeViewControllerCreationBlock SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Sets the block that will create the passcode view controller. @param vcBlock The passcode view controller creation block to use. */ -+ (void)setPasscodeViewControllerCreationBlock:(SFPasscodeViewControllerCreationBlock)vcBlock; ++ (void)setPasscodeViewControllerCreationBlock:(SFPasscodeViewControllerCreationBlock)vcBlock SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** @return The block used to present the passcode view controller. */ -+ (SFPasscodeViewControllerPresentationBlock)presentPasscodeViewControllerBlock; ++ (SFPasscodeViewControllerPresentationBlock)presentPasscodeViewControllerBlock SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Sets the block that will present the passcode view controller. @param vcBlock The block to use to present the passcode view controller. */ -+ (void)setPresentPasscodeViewControllerBlock:(SFPasscodeViewControllerPresentationBlock)vcBlock; ++ (void)setPresentPasscodeViewControllerBlock:(SFPasscodeViewControllerPresentationBlock)vcBlock SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Set the block that will dismiss the passcode view controller. @param vcBlock The block defined to dismiss the passcode view controller. */ -+ (void)setDismissPasscodeViewControllerBlock:(SFPasscodeViewControllerDismissBlock)vcBlock; ++ (void)setDismissPasscodeViewControllerBlock:(SFPasscodeViewControllerDismissBlock)vcBlock SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Sets a retained instance of the current passcode view controller that's displayed. @param vc The passcode view controller. */ -+ (void)setPasscodeViewController:(nullable UIViewController *)vc; ++ (void)setPasscodeViewController:(nullable UIViewController *)vc SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** Presents the biometric enrollment view controller block. This can be used to prompt the user to enable biometric unlock if it was denied upon inital login or upgrade. @param viewConfig SFSDKPasscodeViewConfig used to create the view controller. Supply nil to use the current SFSDKPasscodeViewConfig. */ -+ (void)presentBiometricEnrollment:(nullable SFSDKAppLockViewConfig*)viewConfig; ++ (void)presentBiometricEnrollment:(nullable SFSDKAppLockViewConfig *)viewConfig; /** * Returns the currently displayed passcode view controller, or nil if the passcode view controller * is not currently displayed. */ -+ (UIViewController *)passcodeViewController; ++ (UIViewController *)passcodeViewController SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** * Whether to force the passcode screen to be displayed, despite sanity conditions for whether passcodes @@ -365,21 +379,21 @@ typedef void (^SFPasscodeViewControllerDismissBlock)(UIViewController*,void(^_Nu * to its default value of NO. * @param forceDisplay Whether to force the passcode screen to be displayed. Default value is NO. */ -+ (void)setForcePasscodeDisplay:(BOOL)forceDisplay; ++ (void)setForcePasscodeDisplay:(BOOL)forceDisplay SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** * @return Whether or not the app is configured to force the display of the passcode screen. */ -+ (BOOL)forcePasscodeDisplay; ++ (BOOL)forcePasscodeDisplay SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** * @return Whether or not to validate the passcode at app startup. */ -+ (BOOL)validatePasscodeAtStartup; ++ (BOOL)validatePasscodeAtStartup SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); /** * Set the response of the user being prompted to use biometric unlock. - * @param userAllowedBiometric YES if the user accpeted, NO otherwise. + * @param userAllowedBiometric YES if the user accepted, NO otherwise. */ + (void)userAllowedBiometricUnlock:(BOOL)userAllowedBiometric; @@ -387,7 +401,7 @@ typedef void (^SFPasscodeViewControllerDismissBlock)(UIViewController*,void(^_Nu * Set the passcode length upon upgrade if it was not previously set. * @param length Length of the user's passcode. */ -+ (void)setUpgradePasscodeLength:(NSUInteger)length; ++ (void)setUpgradePasscodeLength:(NSUInteger)length SFSDK_DEPRECATED(8.3, 9.0, "Will be removed."); @end diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout.m index cd869f5a9d..dee0acfaa8 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/Security/SFSecurityLockout.m @@ -47,6 +47,9 @@ #import "SFSDKPasscodeCreateController.h" #import "SFSDKPasscodeVerifyController.h" #import "SFSDKBiometricViewController+Internal.h" +#import "SalesforceSDKConstants.h" +#import "SFSDKCryptoUtils.h" +#import "SFPasscodeProviderManager.h" // Private constants @@ -69,10 +72,12 @@ static UIViewController *sPasscodeViewController = nil; static SFLockScreenSuccessCallbackBlock sLockScreenSuccessCallbackBlock = NULL; static SFLockScreenFailureCallbackBlock sLockScreenFailureCallbackBlock = NULL; +SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 static SFPasscodeViewControllerCreationBlock sPasscodeViewControllerCreationBlock = NULL; static SFPasscodeViewControllerPresentationBlock sPresentPasscodeViewControllerBlock = NULL; static SFPasscodeViewControllerDismissBlock sDismissPasscodeViewControllerBlock = NULL; static NSHashTable> *sDelegates = nil; +SFSDK_USE_DEPRECATED_END static BOOL sForcePasscodeDisplay = NO; static BOOL sValidatePasscodeAtStartup = NO; static SFSDKAppLockViewConfig *_passcodeViewConfig = nil; @@ -105,9 +110,10 @@ + (void)initialize } else { securityLockoutTime = [[SFSecurityLockout readLockoutTimeFromKeychain] unsignedIntegerValue]; } - - sDelegates = [NSHashTable weakObjectsHashTable]; + sDelegates = [NSHashTable weakObjectsHashTable]; + + SFSDK_USE_DEPRECATED_BEGIN [SFSecurityLockout setPasscodeViewControllerCreationBlock:^UIViewController *(SFAppLockControllerMode mode, SFSDKAppLockViewConfig *viewConfig) { SFSDKAppLockViewController *pvc = [[SFSDKAppLockViewController alloc] initWithMode:mode andViewConfig:viewConfig]; return pvc; @@ -130,6 +136,7 @@ + (void)initialize }]; }]; }]; + SFSDK_USE_DEPRECATED_END } } @@ -181,6 +188,7 @@ + (void)upgradeSettings } } +SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 + (void)addDelegate:(id)delegate { @synchronized (self) { @@ -207,6 +215,7 @@ + (void)enumerateDelegates:(void (^)(id))block } } } +SFSDK_USE_DEPRECATED_END + (void)validateTimer { @@ -240,11 +249,13 @@ + (SFPasscodePolicy)getChangesInPasscodePolicy:(NSUInteger)newLockoutTime passco result |= SFPasscodePolicyTimeoutIsMoreRestrictive; } + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 if ([self passcodeLength] == kDefaultPasscodeLength) { result |= SFPasscodePolicySetupNewPasscode; - }else if (newPasscodeLength > [self passcodeLength]) { + } else if (newPasscodeLength > [self passcodeLength]) { result |= SFPasscodePolicyPasscodeLengthIsMoreRestrictive; } + SFSDK_USE_DEPRECATED_END return result; } @@ -285,7 +296,9 @@ + (void)setInactivityConfiguration:(NSUInteger)newPasscodeLength lockoutTime:(NS if ([self policy:newPolicy equals:SFPasscodePolicySetupNewPasscode]) { mode = SFAppLockControllerModeCreatePasscode; SFSDKAppLockViewConfig *config = [self passcodeViewConfig]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 config.passcodeLength = newPasscodeLength; + SFSDK_USE_DEPRECATED_END [self setPasscodeViewConfig:config]; shouldShowView = true; } @@ -377,7 +390,9 @@ + (void)clearAllPasscodeState [SFSecurityLockout setPasscodeLength:kDefaultPasscodeLength]; [SFSecurityLockout setBiometricState:SFBiometricUnlockUnavailable]; [SFInactivityTimerCenter removeTimer:kTimerSecurity]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [[SFPasscodeManager sharedManager] changePasscode:nil]; + SFSDK_USE_DEPRECATED_END } + (NSUInteger)passcodeLength @@ -393,9 +408,19 @@ + (void)setPasscodeLength:(NSUInteger)newPasscodeLength [SFSecurityLockout writePasscodeLengthToKeychain:[NSNumber numberWithInteger:newPasscodeLength]]; } ++ (BOOL)deviceHasBiometric { + LAContext *context = [[LAContext alloc] init]; + NSError *biometricError; + BOOL deviceHasBiometric = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&biometricError]; + if (!deviceHasBiometric) { + [SFSDKCoreLogger d:[self class] format:@"Device cannot use Touch Id or Face Id. Error: %@", biometricError]; + } + return deviceHasBiometric; +} + + (BOOL)biometricUnlockAllowed { - return [[SFPreferences globalPreferences] boolForKey:kBiometricUnlockAllowedKey] && [[SFPasscodeManager sharedManager] deviceHasBiometric]; + return [[SFPreferences globalPreferences] boolForKey:kBiometricUnlockAllowedKey] && [SFSecurityLockout deviceHasBiometric]; } + (void)setBiometricAllowed:(BOOL)enabled @@ -461,9 +486,11 @@ + (BOOL)inactivityExpired + (void)startActivityMonitoring { + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 if ([SFSecurityLockout lockoutTime] > 0) { [[SFUserActivityMonitor sharedInstance] startMonitoring]; } + SFSDK_USE_DEPRECATED_END } + (void)stopActivityMonitoring @@ -490,6 +517,7 @@ + (void)removeTimer + (void)setPasscodeViewConfig:(SFSDKAppLockViewConfig *)passcodeViewConfig { _passcodeViewConfig = passcodeViewConfig; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 // This guarentees the user's passcode is the length specified in the connected app. if (_passcodeViewConfig.forcePasscodeLength) { // Set passcode length to the last minimum length we got from the connected app. @@ -499,16 +527,19 @@ + (void)setPasscodeViewConfig:(SFSDKAppLockViewConfig *)passcodeViewConfig { _passcodeViewConfig.passcodeLength = [SFSecurityLockout passcodeLength]; } } + SFSDK_USE_DEPRECATED_END } + (SFSDKAppLockViewConfig *)passcodeViewConfig { if (_passcodeViewConfig == nil) { _passcodeViewConfig = [SFSDKAppLockViewConfig createDefaultConfig]; } else { + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 NSUInteger storedLength = [SFSecurityLockout passcodeLength]; if (storedLength) { _passcodeViewConfig.passcodeLength = storedLength; } + SFSDK_USE_DEPRECATED_END } return _passcodeViewConfig; } @@ -536,6 +567,7 @@ + (void)unlock:(BOOL)success action:(SFSecurityLockoutAction)action [SFSDKEventBuilderHelper createAndStoreEvent:@"passcodeUnlock" userAccount:nil className:NSStringFromClass([self class]) attributes:nil]; [self sendPasscodeFlowCompletedNotification:success]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 UIViewController *passVc = [SFSecurityLockout passcodeViewController]; if (passVc != nil) { SFPasscodeViewControllerDismissBlock dismissBlock = [SFSecurityLockout dismissPasscodeViewControllerBlock]; @@ -561,6 +593,7 @@ + (void)unlock:(BOOL)success action:(SFSecurityLockoutAction)action [delegate passcodeFlowDidComplete:success]; } }]; + SFSDK_USE_DEPRECATED_END }); } @@ -580,7 +613,9 @@ + (void)timerExpired:(NSTimer*)theTimer [SFSecurityLockout lock]; } else { [SFInactivityTimerCenter removeTimer:kTimerSecurity]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [SFSecurityLockout setupTimer]; + SFSDK_USE_DEPRECATED_END } } @@ -603,8 +638,9 @@ + (void)lock [SFSecurityLockout unlockSuccessPostProcessing:SFSecurityLockoutActionNone]; return; } - + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 if ([SFSecurityLockout lockoutTime] == 0) { + SFSDK_USE_DEPRECATED_END [SFSDKCoreLogger i:[self class] format:@"Skipping 'lock' since pin policies are not configured."]; [SFSecurityLockout unlockSuccessPostProcessing:SFSecurityLockoutActionNone]; return; @@ -612,7 +648,7 @@ + (void)lock } if ([SFApplicationHelper sharedApplication].applicationState == UIApplicationStateActive || ![SFSDKWindowManager sharedManager].snapshotWindow.isEnabled) { - if (![[SFPasscodeManager sharedManager] deviceHasBiometric]) { + if (![SFSecurityLockout deviceHasBiometric]) { [self setBiometricState:SFBiometricUnlockUnavailable]; } @@ -623,8 +659,6 @@ + (void)lock sForcePasscodeDisplay = NO; } - - + (SFPasscodeViewControllerCreationBlock)passcodeViewControllerCreationBlock { return sPasscodeViewControllerCreationBlock; @@ -649,10 +683,12 @@ + (void)setPresentPasscodeViewControllerBlock:(SFPasscodeViewControllerPresentat } } +SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 + (SFPasscodeViewControllerDismissBlock)dismissPasscodeViewControllerBlock { return sDismissPasscodeViewControllerBlock; } +SFSDK_USE_DEPRECATED_END + (void)setDismissPasscodeViewControllerBlock:(SFPasscodeViewControllerDismissBlock)vcBlock { @@ -678,6 +714,7 @@ + (void)presentPasscodeController:(SFAppLockControllerMode)modeValue return; } + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [self setIsLocked:YES]; if (_showPasscode) { [self sendPasscodeFlowWillBeginNotification:modeValue]; @@ -691,6 +728,7 @@ + (void)presentPasscodeController:(SFAppLockControllerMode)modeValue UIViewController *passcodeViewController = passcodeVcCreationBlock(modeValue, self.passcodeViewConfig); [SFSecurityLockout setPasscodeViewController:passcodeViewController]; SFPasscodeViewControllerPresentationBlock presentBlock = [SFSecurityLockout presentPasscodeViewControllerBlock]; + SFSDK_USE_DEPRECATED_END if (presentBlock != nil) { presentBlock(passcodeViewController); } @@ -711,7 +749,9 @@ + (void)presentBiometricEnrollment:(SFSDKAppLockViewConfig*)viewConfig } else { SFSDKAppLockViewConfig *displayConfig = (viewConfig) ? viewConfig : self.passcodeViewConfig; [[SFSDKWindowManager sharedManager].passcodeWindow presentWindowAnimated:NO withCompletion:^{ + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 SFSDKAppLockViewController *navController = [[SFSDKAppLockViewController alloc] initWithMode:SFAppLockControllerModeEnableBiometric andViewConfig:displayConfig]; + SFSDK_USE_DEPRECATED_END navController.modalPresentationStyle = UIModalPresentationFullScreen; [[SFSDKWindowManager sharedManager].passcodeWindow.viewController presentViewController:navController animated:NO completion:^{}]; }]; @@ -737,6 +777,7 @@ + (void)sendPasscodeFlowCompletedNotification:(BOOL)validationSuccess [[NSNotificationCenter defaultCenter] postNotification:n]; } +// TODO: Remove this and sValidatePasscodeAtStartup in 9.0 + (BOOL)validatePasscodeAtStartup { return sValidatePasscodeAtStartup; @@ -757,17 +798,28 @@ + (BOOL)locked return locked; } ++ (BOOL)isPasscodeSet { + SFSDK_USE_DEPRECATED_BEGIN // TODO: Migrate in Mobile SDK 9.0 + return [[SFPasscodeManager sharedManager] passcodeIsSet]; + SFSDK_USE_DEPRECATED_END +} + + (BOOL)isPasscodeValid { if(securityLockoutTime == 0) return YES; // no passcode is required. - return([[SFPasscodeManager sharedManager] passcodeIsSet]); + return [SFSecurityLockout isPasscodeSet]; } -+ (BOOL)isPasscodeNeeded -{ - if(securityLockoutTime == 0) return NO; // no passcode is required. ++ (BOOL)isPasscodeNeeded { + return [SFSecurityLockout shouldLock]; +} + ++ (BOOL)shouldLock { + if (securityLockoutTime == 0) return NO; // no passcode is required. - BOOL result = [SFSecurityLockout inactivityExpired] || [SFSecurityLockout validatePasscodeAtStartup] || ![SFSecurityLockout isPasscodeValid]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 + BOOL result = [SFSecurityLockout inactivityExpired] || ![SFSecurityLockout isPasscodeValid]; + SFSDK_USE_DEPRECATED_END result = result || sForcePasscodeDisplay; return result; } @@ -792,6 +844,7 @@ + (UIViewController *)passcodeViewController + (void)cancelPasscodeScreen { void (^cancelPasscodeBlock)(void) = ^{ + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 UIViewController *passVc = [SFSecurityLockout passcodeViewController]; [SFSDKCoreLogger i:[SFSecurityLockout class] format:@"App requested passcode screen cancel. Screen %@ displayed.", (passVc != nil ? @"is" : @"is not")]; if (passVc != nil) { @@ -799,8 +852,8 @@ + (void)cancelPasscodeScreen dismissBlock(passVc,^{ [SFSecurityLockout setPasscodeViewController:nil]; }); - } + SFSDK_USE_DEPRECATED_END }; if (![NSThread isMainThread]) { @@ -836,6 +889,7 @@ + (SFLockScreenSuccessCallbackBlock)lockScreenSuccessCallbackBlock return sLockScreenSuccessCallbackBlock; } +SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 + (BOOL)passcodeScreenIsPresent { if ([SFSecurityLockout passcodeViewController] != nil && [[SFSecurityLockout passcodeViewController] presentedViewController]!= nil) { @@ -868,6 +922,7 @@ + (void)unlockFailurePostProcessing blockCopy(); } } +SFSDK_USE_DEPRECATED_END + (void)userAllowedBiometricUnlock:(BOOL)userAllowedBiometric { @@ -962,4 +1017,3 @@ + (void)writeNumberToKeychain:(NSNumber *)number identifier: (NSString *)identif } @end - diff --git a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/UserAccount/SFUserAccountManager.m b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/UserAccount/SFUserAccountManager.m index 495d973558..fffbc840f0 100644 --- a/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/UserAccount/SFUserAccountManager.m +++ b/libs/SalesforceSDKCore/SalesforceSDKCore/Classes/UserAccount/SFUserAccountManager.m @@ -539,7 +539,9 @@ - (void)postPushUnregistration:(SFUserAccount *)user { [self deleteAccountForUser:user error:nil]; id authClient = self.authClient(); [authClient revokeRefreshToken:user.credentials]; + SFSDK_USE_DEPRECATED_BEGIN // TODO: Remove in Mobile SDK 9.0 [SFSecurityLockout clearPasscodeState:user]; + SFSDK_USE_DEPRECATED_END BOOL isCurrentUser = [user isEqual:self.currentUser]; if (isCurrentUser) { [self setCurrentUserInternal:nil]; @@ -1437,7 +1439,7 @@ - (void)presentBiometricEnrollment:(nullable SFSDKAppLockViewConfig *)config { } - (BOOL)deviceHasBiometric { - return [[SFPasscodeManager sharedManager] deviceHasBiometric]; + return [SFSecurityLockout deviceHasBiometric]; } - (SFBiometricUnlockState)biometricUnlockState { diff --git a/native/SampleApps/RestAPIExplorer/RestAPIExplorer/AppDelegate.swift b/native/SampleApps/RestAPIExplorer/RestAPIExplorer/AppDelegate.swift index 9b45d25405..9fc1d4ebe1 100644 --- a/native/SampleApps/RestAPIExplorer/RestAPIExplorer/AppDelegate.swift +++ b/native/SampleApps/RestAPIExplorer/RestAPIExplorer/AppDelegate.swift @@ -175,7 +175,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { passcodeViewConfig.instructionTextColor = UIColor.white passcodeViewConfig.borderColor = UIColor.yellow passcodeViewConfig.maxNumberOfAttempts = 3 - passcodeViewConfig.forcePasscodeLength = true UserAccountManager.shared.appLockViewControllerConfig = passcodeViewConfig }