Is it possible to use Touch-ID Authentication AND Keychain sharing in an iOS app?
Asked Answered
P

2

17

I’ve been successfully able to implement TouchID with keychain as well as Keychain Sharing (syncing keychain items between multiple devices) separately. When I try to do them both, I get an error “-50“ which is invalid parameters. From the below code, removing either kSecAttrAccessControl or kSecAttrSynchronizable works as expected.

Based on my experience (read - a few days of frustration) so far, and based on the capabilities of some keychain API simplification tools like UICKeychainStore, it seems like if I use Touch ID Authentication, Keychain Sharing wouldn’t work and vice versa. I’m looking for an Apple documentation that would state that, but unable to find it.

I’ve gone through Apple’s SecItem.h page, and a useful info I found states the following about kSecAttrAccessible and kSecAttrSynchronizable: “If both attributes are specified on either OS X or iOS, the value for the kSecAttrAccessible key may only be one whose name does not end with “ThisDeviceOnly", as those cannot sync to another device.” However, I'm not using "ThisDeviceOnly" (I'm currently using kSecAttrAccessibleAlways for testing purposes)

Can you help in pointing out if and where Apple has documented this limitation? That would help me document it for the records, and move on. Thanks.

- (void)addKeychainItemWithIdentifier:(NSString *)identifier andData:(NSData *)data {

    CFErrorRef error = NULL;
    SecAccessControlRef sacObject;
    sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
                                            kSecAttrAccessibleAlways,
                                            kSecAccessControlUserPresence, &error);
    if(sacObject == NULL || error != NULL)
    {
    NSString *msg0 = [NSString stringWithFormat:NSLocalizedString(@"SEC_ITEM_ADD_CAN_CREATE_OBJECT", nil), error];
    [self printResultWithMessage:msg0];
    return;
    }

    NSDictionary *attributes = @{
                             (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                             (__bridge id)kSecValueData: data,
                             (__bridge id)kSecAttrAccessible:(__bridge id)kSecAttrAccessibleAlways,
                             (__bridge id)kSecAttrService: identifier,
                             (__bridge id)kSecAttrSynchronizable:(__bridge id)kCFBooleanTrue,
                             (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacObject
                             };

    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    OSStatus status =  SecItemAdd((__bridge CFDictionaryRef)attributes, nil);
    NSError *statuserror = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil];
    [self printResultWithMessage:[self keychainErrorToString:status]];
    });
}
Pest answered 21/4, 2015 at 22:24 Comment(0)
P
3

I think I may have found the answer to this

In WWDC 2014 video 711, the following is mentioned at 31:48

ACL Protected Items - No Synchronization, No Back up

Thus Touch ID authentication cannot be used for Keychain Sharing between devices as those items are Device-Only

Pest answered 21/5, 2015 at 17:23 Comment(0)
C
1

This example project might help, the title is KeychainTouchID: Using Touch ID with Keychain and LocalAuthentication:

https://developer.apple.com/library/ios/samplecode/KeychainTouchID/Introduction/Intro.html

This might be limited to local though, no sharing.

Caesar answered 29/4, 2015 at 0:28 Comment(2)
Yes, that's the project I referred to implement Touch ID authentication. It doesn't include keychain sharing between devices though.Pest
I could be wrong here, but from my understanding the TouchID has its own storage within the device that can't be read by the OS in any way to share the data. I only know this from watching the WWDC where they announced TouchID.Caesar

© 2022 - 2024 — McMap. All rights reserved.