SecItemCopyMatching returns errSecAuthFailed when targeting keys created with kSecAccessControlUserPresence

When I generate or import keys with kSecAccessControlUserPresence, SecItemCopyMatching fails about a quarter of the time with errSecAuthFailed. Generation is like this:

Code Block objective-c
SecKeyRef publicKey = NULL;
SecKeyRef privateKey = NULL;
SecAccessControlRef access =
SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
kSecAccessControlUserPresence,
nil);
NSMutableDictionary* privateKeyAttr = [[NSMutableDictionary alloc] init];
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
[privateKeyAttr setObject:(id)label forKey:(id)kSecAttrApplicationTag];
[privateKeyAttr setObject:(bridge id)access forKey:(id)kSecAttrAccessControl];
NSMutableDictionary* publicKeyAttr = [[NSMutableDictionary alloc] init];
[publicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
[publicKeyAttr setObject:(id)label forKey:(id)kSecAttrApplicationTag];
NSMutableDictionary* keyPairAttr = [[NSMutableDictionary alloc] init];
[keyPairAttr setObject:(bridge id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[keyPairAttr setObject:[NSNumber numberWithInt:2048] forKey:(id)kSecAttrKeySizeInBits];
[keyPairAttr setObject:privateKeyAttr forKey:(id)kSecPrivateKeyAttrs];
[keyPairAttr setObject:publicKeyAttr forKey:(id)kSecPublicKeyAttrs];
OSStatus status = SecKeyGeneratePair((CFDictionaryRef)keyPairAttr, &publicKey, &privateKey);


SecItemCopyMatching is invoked like this:

Code Block language
NSMutableDictionary * query = [[NSMutableDictionary alloc] init];
[query setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit];
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnRef];
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
[query setObject:(id)label forKey:(id)kSecAttrApplicationTag];
[query setObject:(id)kSecClassKey forKey:(id)kSecClass];
CFTypeRef result = nil;
OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, &result);


Any thoughts on how to reliably invoke SecItemCopyMatching in this case?




Hej! Did you try SecKeyCreateRandomKey as recommended as in Generating New Cryptographic Keys which simplifies the call and reduces possible errors...

SecItemCopyMatching returns errSecAuthFailed when targeting keys created with kSecAccessControlUserPresence
 
 
Q