When attempting to generate a key pair using SecKeyGeneratePair to be stored in SecureEnclave whilst also supplying an kSecAccessControlApplicationPassword, an error code 26276 (Internal Error) is returned.
A corresponding log:
[client] Unable to connect to com.apple.setoken even after retries
Keypair generation would work when:
1) kSecAccessControlApplicationPassword is omitted
2) keypair generation does not use the kSecAttrTokenIDSecureEnclave
Sample code:
NSError *secError = NULL;
SecAccessControlCreateFlags flags =
kSecAccessControlApplicationPassword
;
SecAccessControlRef accessControlRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
flags,
(CFErrorRef*)(__bridge void*)secError);
if (secError != NULL) {
NSLog(@"ERRORRRRRR: %@", secError.localizedDescription);
return;
}
CFMutableDictionaryRef privateKeyParams = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(privateKeyParams, kSecAttrIsPermanent, kCFBooleanTrue);
CFDictionarySetValue(privateKeyParams, kSecAttrAccessControl, accessControlRef);
CFMutableDictionaryRef keygenParams = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(keygenParams, kSecAttrTokenID, kSecAttrTokenIDSecureEnclave);
CFDictionarySetValue(keygenParams, kSecAttrKeyType, kSecAttrKeyTypeEC);
int size = 256;
CFNumberRef sizeInBitsNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &size);
CFDictionarySetValue(keygenParams, kSecAttrKeySizeInBits, sizeInBitsNumberRef);
CFDictionarySetValue(keygenParams, kSecClass, kSecClassKey);
CFDictionarySetValue(keygenParams, kSecPrivateKeyAttrs, privateKeyParams);
CFDictionarySetValue(keygenParams, kSecAttrLabel , (__bridge CFStringRef)@"abcde");
_context = [[LAContext alloc]init];
CFDictionarySetValue(keygenParams, kSecUseAuthenticationContext, (__bridge const void *)(_context));
SecKeyRef publicKey = NULL;
OSStatus generationStatus = SecKeyGeneratePair(keygenParams, &publicKey, NULL);
NSLog(@"Generation Status: %d", (int) generationStatus);
Usage of the combination flags below would fail as well:
SecAccessControlCreateFlags flags =
kSecAccessControlApplicationPassword
| kSecAccessControlAnd
| kSecAccessControlPrivateKeyUsage
;
Works as intended on existing iOS. Tested on iOS 13 beta 2.
Any feedback / help / suggestion is much appreciated! Filed a Feedback too.