From d25fefa08fd203609b161d73298856997c001599 Mon Sep 17 00:00:00 2001 From: MazurDorian Date: Sun, 15 Jun 2025 18:11:29 +0200 Subject: [PATCH 1/2] fix: use kSecAccessControlDevicePasscode as a fallback on IOS --- ios/RNKeychainManager/RNKeychainManager.m | 61 +++++++++++++++-------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/ios/RNKeychainManager/RNKeychainManager.m b/ios/RNKeychainManager/RNKeychainManager.m index 6888ff0d..6acd8516 100644 --- a/ios/RNKeychainManager/RNKeychainManager.m +++ b/ios/RNKeychainManager/RNKeychainManager.m @@ -183,30 +183,51 @@ LAPolicy authPolicy(NSDictionary *options) SecAccessControlCreateFlags accessControlValue(NSDictionary *options) { + SecAccessControlCreateFlags flags = 0; if (options && options[kAccessControlType] && [options[kAccessControlType] isKindOfClass:[NSString class]]) { - if ([options[kAccessControlType] isEqualToString: kAccessControlUserPresence]) { - return kSecAccessControlUserPresence; + NSString *type = options[kAccessControlType]; + + if ([type isEqualToString:kAccessControlUserPresence]) { + flags = kSecAccessControlUserPresence; + } else if ([type isEqualToString:kAccessControlBiometryAny]) { + flags = kSecAccessControlTouchIDAny; + } else if ([type isEqualToString:kAccessControlBiometryCurrentSet]) { + flags = kSecAccessControlTouchIDCurrentSet; + } else if ([type isEqualToString:kAccessControlDevicePasscode]) { + flags = kSecAccessControlDevicePasscode; + } else if ([type isEqualToString:kAccessControlBiometryAnyOrDevicePasscode]) { + flags = kSecAccessControlTouchIDAny | + kSecAccessControlOr | + kSecAccessControlDevicePasscode; + } else if ([type isEqualToString:kAccessControlBiometryCurrentSetOrDevicePasscode]) { + flags = kSecAccessControlTouchIDCurrentSet | + kSecAccessControlOr | + kSecAccessControlDevicePasscode; + } else if ([type isEqualToString:kAccessControlApplicationPassword]) { + flags = kSecAccessControlApplicationPassword; } - else if ([options[kAccessControlType] isEqualToString: kAccessControlBiometryAny]) { - return kSecAccessControlTouchIDAny; - } - else if ([options[kAccessControlType] isEqualToString: kAccessControlBiometryCurrentSet]) { - return kSecAccessControlTouchIDCurrentSet; - } - else if ([options[kAccessControlType] isEqualToString: kAccessControlDevicePasscode]) { - return kSecAccessControlDevicePasscode; - } - else if ([options[kAccessControlType] isEqualToString: kAccessControlBiometryAnyOrDevicePasscode]) { - return kSecAccessControlTouchIDAny|kSecAccessControlOr|kSecAccessControlDevicePasscode; - } - else if ([options[kAccessControlType] isEqualToString: kAccessControlBiometryCurrentSetOrDevicePasscode]) { - return kSecAccessControlTouchIDCurrentSet|kSecAccessControlOr|kSecAccessControlDevicePasscode; - } - else if ([options[kAccessControlType] isEqualToString: kAccessControlApplicationPassword]) { - return kSecAccessControlApplicationPassword; + } +#if TARGET_OS_IOS || TARGET_OS_VISION + BOOL requestedBiometric = + (flags & kSecAccessControlTouchIDAny) || + (flags & kSecAccessControlTouchIDCurrentSet); + + BOOL requestedPasscode = + (flags & kSecAccessControlDevicePasscode); + + if (requestedBiometric && requestedPasscode) { + NSError *error = nil; + BOOL canAuthenticate = [[LAContext new] canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&aerr]; + + if (!canAuthenticate) + { + // No usable biometrics – use the safest subset. + flags = kSecAccessControlDevicePasscode; } } - return 0; +#endif + + return flags; } - (void)insertKeychainEntry:(NSDictionary *)attributes From 4751ea251fd6da004513e8eacc818f4887ce34bc Mon Sep 17 00:00:00 2001 From: Dorian Mazur <46839236+DorianMazur@users.noreply.github.com> Date: Sun, 15 Jun 2025 18:54:27 +0200 Subject: [PATCH 2/2] Update RNKeychainManager.m --- ios/RNKeychainManager/RNKeychainManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/RNKeychainManager/RNKeychainManager.m b/ios/RNKeychainManager/RNKeychainManager.m index 6acd8516..43404de8 100644 --- a/ios/RNKeychainManager/RNKeychainManager.m +++ b/ios/RNKeychainManager/RNKeychainManager.m @@ -216,7 +216,7 @@ SecAccessControlCreateFlags accessControlValue(NSDictionary *options) (flags & kSecAccessControlDevicePasscode); if (requestedBiometric && requestedPasscode) { - NSError *error = nil; + NSError *aerr = nil; BOOL canAuthenticate = [[LAContext new] canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&aerr]; if (!canAuthenticate)