Kristian Melting
Kristian Melting

Reputation: 11

SecKeyChain items and SecRecord differences between debugging on device and simulator, Xamarin iOS

I am creating an app in Xamarin.iOS which utilizes the SecKeyChain, from Security. In it, I am trying to save a user´s credentials as a SecRecord to the KeyChain, and later access it. When the app starts, it will check if there are any saved credentials in the KeyChain, and decide whether or not to prompt a manual login.

When SecKeyChain.Add is called, it returns success. However, after a force-close of the app SecKeyChain.QueryAsRecord fails with the error code AuthFailed. This only happens on the device, while the simulator succeeds.

Another issue is related to the SecRecord created. There are severe differences between the object created when debugging on the Device and the Simulator. The code creating the SecRecord is:

var credentialsRecord = new SecRecord(SecKind.GenericPassword)
        {
            Generic = NSData.FromString("record"),
            Label = credentials.Username,
            Account = credentials.Username,
            Service = CredentialsStorageServiceName,
            ValueData = NSData.FromBytes(credentials.Password.ToIntPtr(), Convert.ToUInt32(credentials.Password.Length()) * 2),
            AccessControl = new SecAccessControl(SecAccessible.WhenPasscodeSetThisDeviceOnly, SecAccessControlCreateFlags.TouchIDCurrentSet)
        };
var statusCode = SecKeyChain.Add(credentialsRecord);

In entitlements.plist, I have enabled keychain access groups, and added a group named the same as my dummy Xcode project´s bundle identifier. In project options -> iOS bundle signing I have a signing identity and a provisioning profile, with the custom entitlements field empty.

Am I missing something to access the keychain of the device, or is the issue related to something else?

Please let me know if I am missing something, and thank you in advance.

Upvotes: 1

Views: 1445

Answers (1)

Razvan Pocaznoi
Razvan Pocaznoi

Reputation: 409

I'm not very intimately with Xamarin, but since it wraps the iOS native apis in C#, Apple's own examples might help (since it covers basically the same scenario you're describing): https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html#//apple_ref/doc/uid/TP30000897-CH208-SW1

Also it might be useful to look into the Apple docs for the SecAccessControlCreateWithFlags (https://developer.apple.com/reference/security/1394452-secaccesscontrolcreatewithflags) since you're using custom protection & flags

Here are the excerpts for the combination you're using:

the SecAccessible.WhenPasscodeSetThisDeviceOnly protection means:

The data in the keychain can only be accessed when the device is unlocked. Only available if a passcode is set on the device.

the SecAccessControlCreateFlags.TouchIDCurrentSet flag means:

Constraint to access with Touch ID for currently enrolled fingers. Touch ID must be available and enrolled with at least one finger. Item is invalidated if fingers are added or removed.

As for using the keychain with the simulator, I wouldn't rely on consistent behavior there. There's also no TouchID or passcode so the keychain item attributes & access control flags that use them (as it's your case) won't work.

Long story short, when developing security using keychain the safest way is to do it on an actual device to ensure that the app will behave as expected in the users' hands. However if you want to develop on the simulator use the default flags (or use the apple's example as inspiration) and switch to the more secure flags when moving to production.

Upvotes: 1

Related Questions