iOS SFHFKeychainUtils failing *sometimes* with error -25308 errSecInteractionNotAllowed
Asked Answered
B

2

39

I have this code getting back a password from the keychain for a given username NSString:

NSError *error = nil;
NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
NSString *pw = [SFHFKeychainUtils getPasswordForUsername:username andServiceName:appName error:&error];
if(error != nil)
    // log the error    

Most of the time for most users this all works fine - but for some specific users this call seems to fail (and carry on failing) where it returns the following error:

The operation couldn’t be completed. (SFHFKeychainUtilsErrorDomain error -25308.)

This is apparently errSecInteractionNotAllowed - which from what I've read I think this means some kind of user interaction is required for the keychain to be accessed.

Does anyone have any idea why this call may be failing for some specific users only? This keychain entry is specific to my app - so why would any user interaction be required to access it?

Any pointers much appreciated...

Buyers answered 15/3, 2012 at 16:27 Comment(0)
B
54

OK so I worked this out finally.

Eventually I worked out the users who were having problems had set a lock code on their phone. If the phone was locked the keychain system was returning this -25308 error.

If you only ever need to access the keychain when the app is active in the forground you would never see this issue - but if you need to carry on processing when the phone is locked or if the app is in background then you would see it.

Elsewhere I'd read that the default access attribute for the kechain system is kSecAttrAccessibleAlways - but I think that is out of date. It seems the default access attribute for the keychain system is such that when the phone is locked with a pin code then the items are unavailable.

The fix for this is to change the SFHFKeychainUtils code to set a specific kSecAttrAccessible attribute on the keychain items it manages (which the original code did not do - presumably as it pre-dated these attributes).

This wordpress updated version of the SFHFKeychainUtils code has the fixes in it - search for kSecAttrAccessible to see where they have added the accessible attribute code.

Hope this helps anyone else running into this...

Buyers answered 16/3, 2012 at 10:22 Comment(7)
I've verified this on iOS4, iOS5 and iOS6. On all iOS versions the errSecInteractionNotAllowed error code is returned if data which is not marked with kSecAttrAccessibleAlways is read when your device is in locked state (e.g. background tasks, Newsstand downloads etc).Duumvirate
kSecAttrAccessibleAlways is not a great choice - you can get more of the security benefits, and still avoid the error, by using something like kSecAttrAccessibleAfterFirstUnlock (or an even more restrictive setting, if that works for your app).Bustee
I can confirm that, when the app is in foreground but the device is locked with password, the keychain library give me the -25308. Thanks !Follmer
I am unable to access the link. Can you give a fresh link to updated versionDispatcher
SFHFKeychainUtils has not been updated for a long time now - I no longer use it - I'd suggest searching for a more recent security system wrapper which presumably would expose these newer attributes and would be better supported.Buyers
Here is the updated link : github.com/wordpress-mobile/WordPress-iOS/blob/…Predict
You're my hero, thanks so much for helping me find out why my Keychain access seemed so unpredictable. By default, KeychainSwift (github.com/evgenyneu/keychain-swift) was using kSecAttrAccessibleWhenUnlocked while I needed kSecAttrAccessibleAlways (the app needs to send locations in background mode).Tartan
H
5

I was having this issue in iOS 14 with Widgets extensions that are accessing to the keychain to get the JWT token to call some rests.

Apparently, widgets tried by default to update also when the device is locked and the keychain item I was trying to use was not accessible.

After setting this attribute to the keychain element (swift 5 code), everything seems to be working:

keychainItem[kSecAttrAccessible as String] = kSecAttrAccessibleAfterFirstUnlock
Harmless answered 11/6, 2021 at 7:2 Comment(1)
Be aware of iOS15+ pre-warm after reboot (before first unlock) developer.apple.com/documentation/uikit/app_and_environment/…Donets

© 2022 - 2024 — McMap. All rights reserved.