Touch ID / Face ID biometryCurrentSet never fails on iOS 15

I've got some admittedly old Objective-C code handling Keychain items protected by Touch ID / Face ID that uses the access control flag kSecAccessControlTouchIDCurrentSet, accessing the items would fail with errSecItemNotFound when the user adds or removes a finger/face from the device, however on iOS 15.0 this is not happening. It does work on iOS 14.6 still.

My deployment target is still iOS 11.0 so I haven't moved to kSecAccessControlBiometryCurrentSet as the replacement for the now deprecated TouchID value - but the enum raw values are the same so I don't see how that could be the cause.

I can't see what the new error code is, because I'm not using Xcode 13, but I'll try and get the DeviceSupport copied in (official support for this is please!)

to help search:

Swift touchIDCurrentSet biometryCurrentSet

Objective-C
kSecAccessControlTouchIDCurrentSet kSecAccessControlBiometryCurrentSet

Accepted Answer

I took this sample code https://developer.apple.com/documentation/localauthentication/accessing_keychain_items_with_face_id_or_touch_id and added the access control flag biometryCurrentSet to reproduce the scenario. The sample code uses an Internet Password item not a Generic Password item, but this didn't seem to matter.

In Xcode 13 I can see the error code is now errSecAuthFailed when the biometry set changes. Our code was only checking for errSecItemNotFound.

Updating our code back in Xcode 12 with deployment target iOS 11.0 to check for either of these return codes has our app behaving correctly again in iOS 15 and below.

Answers

I've got some admittedly old Objective-C code handling keychain items

What type of keychain item? A key? A generic password? Or something else?

but the enum raw values are the same so I don't see how that could be the cause.

Agreed.

I can't see what the new error code is, because I'm not using Xcode 13, but I'll try and get the DeviceSupport copied in

Please don’t do that. It puts your Xcode in an unsupported state and can result in much harder to debug issues down the pike.

If you’re not ready to make the leap to Xcode 13:

  1. Build your app with Xcode 12.

  2. From the organiser, export a Development signed build.

  3. Install that using the Finder.

And if you need to investigate an issue like this, add log points to your code. If you use the standard API for this, you’ll be able to view your log entries using Console.

Adding log points like this is a good idea anyway. The resulting log entries will be captured in a sysdiagnose log, which gives you a way to debug problems like this that you can’t reproduce locally.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • This is with a Generic Password item. I've found an answer which I will post. Thanks for the advice, our new code is using os.log already.

    Unfortunately Console app is restricted on my corporate Mac, as is using Xcode 13, so DeviceSupport is regrettably the few options we have. Would greatly appreciate dynamic download of DeviceSupport inside Xcode (like simulator runtimes) and support in at least the last version of the previous Xcode (12 in this case).

Add a Comment

I took this sample code https://developer.apple.com/documentation/localauthentication/accessing_keychain_items_with_face_id_or_touch_id and added the access control flag biometryCurrentSet to reproduce the scenario. The sample code uses an Internet Password item not a Generic Password item, but this didn't seem to matter.

In Xcode 13 I can see the error code is now errSecAuthFailed when the biometry set changes. Our code was only checking for errSecItemNotFound.

Updating our code back in Xcode 12 with deployment target iOS 11.0 to check for either of these return codes has our app behaving correctly again in iOS 15 and below.