A call to the API SecKeyGeneratePair in SecureEnclave for iOS18 returns an OSStatus 0 but the SecKeyRef is not present.
Understand that this API is currently deprecated and there are plans to move to the new APIs, but I believe this API should still work in iOS18 as expected for now.
The API works as expected on iPadOS 18.
// Create SE key
let sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleAfterFirstUnlock,
.privateKeyUsage, nil)!
let privKeyAttr = [
kSecAttrAccessControl: sacRef,
kSecAttrIsPermanent: true,
] as NSDictionary
os_log("Priv key params: %{public}@", log: osLogger, privKeyAttr)
let keygenAttr = [
kSecAttrApplicationLabel: attrApplicationLabelSeKey,
kSecAttrTokenID: kSecAttrTokenIDSecureEnclave,
kSecPrivateKeyAttrs: privKeyAttr,
kSecAttrKeyType: kSecAttrKeyTypeEC,
kSecAttrKeySizeInBits: 256
] as NSDictionary
var error: Unmanaged<CFError>?
os_log("keygen params: %{public}@", log: osLogger, keygenAttr)
var keyRef: SecKey?
let status = SecKeyGeneratePair(keygenAttr,
&keyRef,
nil)
os_log("SecKeyGeneratePair osStatus: %{public}d, keyRef: %{public}@", log: osLogger, status, keyRef == nil ? "null" : "ref present")
Post
Replies
Boosts
Views
Activity
At present, we have been receiving numerous reports from customers who integrate our SDK who have been encountering the failures (errSecItemNotFound) while trying to retrieve a key using SecItemCopyMatching. We are raising this query we are still in the midst of properly reproducing this issue though it has been reported to occur in several devices during the OS upgrade to the iOS 17 betas. This issue is still occurring in the latest iOS 17 beta 7. This issue was not present in previous iOS version. At present, we are of the conclusion that this issue is occurring randomly amongst devices that upgraded to the iOS 17 betas and it is not limited to older devices.
What we believe is occurring is that:
A key is created and stored into Keychain using SecItemAdd.
The same key is queried at a later timepoint but encounters the error errSecItemNotFound.
Our SDK then attempts to regenerate a new key for the same label and attribute to store it using SecItemAdd, but the system then reports errSecDuplicateItem at the key already exists.
The workaround here includes a manual deletion of the said key.
This issue seems to occur only during an OS upgrade to the iOS17 betas with the likelihood that the key was already present in Keychain prior to the upgrade. I share below the snippet relating to how this said key is generated, stored and retrieved. // Initial key is added
// A random data of 32 bytes length is generated
CFDataRef dataRef = <32bytes of data>;
*attr = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
BREAK_IF_NULL(*attr);
CFDictionarySetValue(*attr, kSecClass, kSecClassGenericPassword);
CFStringRef aKey = CFStringCreateWithCString(kCFAllocatorDefault, "KEY_ACCOUNT", kCFStringEncodingUTF8);
CFDictionaryAddValue(*attr, kSecAttrAccount, aKey);
CFDictionarySetValue(*attr, kSecReturnData, kCFBooleanFalse); CFDictionarySetValue(*attr, kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlock);
label = CFStringCreateWithFormat(NULL, NULL, CFSTR("A_LABEL"));
CFDictionarySetValue(attr, kSecAttrService, label);
CFDictionarySetValue(attr, kSecValueData, dataRef); SecItemAdd(attr);
// Query for retrieval of key
label = CFStringCreateWithFormat(NULL, NULL, CFSTR("A_LABEL")); CFDictionarySetValue(attributes, kSecAttrService, label);
CFDictionarySetValue(attributes, kSecReturnData, kCFBooleanTrue);
CFDictionarySetValue(attributes, kSecMatchLimit, limit);
CFDictionarySetValue(attributes, kSecReturnAttributes, returnAttributes);
osStatus = SecItemCopyMatching(attributes, result);
if (errSecItemNotFound == osStatus) { }
Please do let me know if more information could be useful. At present, we have ensured that the key generated are well-within the size limits and is stored simply as a kSecClassGenericPassword with limited access control to the key. Additionally, the query used was intended to be generalised to avoid encountering such occurrences.
Don't currently see a means of generating a registration/authentication request with this, do Passkeys currently support the handling/processing of client extensions as defined by WebAuthn?
If so, is there a reference list of supported client extensions by Passkey?
In particular, do Passkeys support creation of 'payment' credentials?
https://www.w3.org/TR/secure-payment-confirmation/#sctn-payment-extension-registration extension
Short question: Is is possible to disable the iCloud Keychain synchronization of the Passkeys on-demand?
This would ensure and allow device-specific binding where necessary.
When retrieving the ASAuthorizationPlatformPublicKeyCredentialRegistration, the decoded fmt value of rawAttestationObject is none instead of apple.
Is this currently expected?
Hi,
When attempting to perform a credential registration, I constantly get the error
Application with identifier <...> is not associated with domain <domain>
I've verified the following:
The file is present on the required URL path
https://123.com/.well-known/apple-app-site-association
{
"webcredentials": {
"apps": [ "<PREFIX>.bundleID" ]
}
}
Added the Capabilities to my domain
Confirmed that the CA is valid and there are no redirects.
Am I missing something? My device is able to properly access the file
Hi,
When trying to enable this through Settings -> Developer, the Switch constantly turns back Off once leaving and returning to the page.
Attempting to use the Platform authenticator according to the steps here
Leads to the error:
The operation couldn't be completed. Syncing platform authenticator must be enabled to register a platform public key credential; this can be enabled in Settings > Developer.
Hi,
I believe its pretty clear but to confirm, does DocC work with Objective-C based products, i.e static frameworks / libraries?
Hi,
In DeviceCheck attestKey(_:clientDataHash:completionHandler:) is it possible to set the up and uv values if a separate user verification (via LAContext for e.g.) is completed outside theDCAppAttestService flow? Otherwise, the bit-values for up and uv are currently always returning false.
Hi,
Using the https://developer.apple.com/documentation/devicecheck
I should be able to leverage the attest APIs to verify the integrity of my apps. However, I am constantly getting an unknownSystemFailure when attempting to attestKey(_:).
This is after key pair generation and clientDataHash for the challenge. Please refer to the code sample. Would appreciate any feedback on how to get this to work.
let service = DCAppAttestService.shared
guard service.isSupported else {
return
}
service.generateKey { (keyId, error) in
if error != nil {
print("\(error!.localizedDescription)")
return
}
print(keyId!)
let challenge = "r6ctg89rt3948tc497tn4379".data(using: .utf8)
let hash = Data(SHA256.hash(data: challenge!))
service.attestKey(keyId!, clientDataHash: hash) { (attestationObject, error) in
if error != nil {
print("\(error!.localizedDescription)")
return
}
print(attestationObject?.debugDescription)
}
}
Hi,
Using the https://developer.apple.com/documentation/devicecheck
I should be able to leverage the attest APIs to verify the integrity of my apps. However, I am constantly getting an unknownSystemFailure when attempting to attestKey(_:).
This is after key pair generation and clientDataHash for the challenge. Please refer to the code sample. Would appreciate any feedback on how to get this to work.
let service = DCAppAttestService.shared
guard service.isSupported else {
return
}
service.generateKey { (keyId, error) in
if error != nil {
print("\(error!.localizedDescription)")
return
}
print(keyId!)
let challenge = "r6ctg89rt3948tc497tn4379".data(using: .utf8)
let hash = Data(SHA256.hash(data: challenge!))
service.attestKey(keyId!, clientDataHash: hash) { (attestationObject, error) in
if error != nil {
print("\(error!.localizedDescription)")
return
}
print(attestationObject?.debugDescription)
}
}