Hello developers and apple support team. Im was quite surprised why it's not possible to get SecKey reference for key which was generated using DCAppAttestService.generateKey()
Case 1.
So after
self.iosDeviceAttestationManager.generateKey { keyId, error in
guard let keyId = keyId else {
promise(.failure(error!))
return
}
promise(.success(keyId))
}
Then Im converting keyId from string to Data using
guard let keyIdData = Data(base64Encoded: keyId) else {
return Fail(error: Errors.someError).eraseToAnyPublisher()
}
P.S. Actually I have tried convert keyId as pure string to data but it also does not work
let keyIdData = keyID.data(using: .utf8)!
Then Im trying to obtain this key using standard keychain API.
let getquery: [String: Any] = [
kSecClass as String: kSecClassKey,
kSecAttrApplicationTag as String: keyIdData,
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecReturnRef as String: true]
var item: CFTypeRef?
let status = SecItemCopyMatching(getquery as CFDictionary, &item)
guard status == errSecSuccess else {
print("SecItemCopyMatching failed. Status = \(status)")
return nil
}
Which return me
SecItemCopyMatching failed. Status = -25300
Which means that itemNot found in keychain. Why it's happening?
Case 2.
I have tried other way around to create ECKey using
let access = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
.privateKeyUsage,
nil)
let ECKeySize = 256
let attributes: NSDictionary = [
kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeySizeInBits: ECKeySize,
kSecAttrTokenID: kSecAttrTokenIDSecureEnclave,
kSecPrivateKeyAttrs: [
kSecAttrIsPermanent: true,
kSecAttrApplicationTag: keyTagData,
kSecAttrAccessControl: access as Any
]
]
var error: Unmanaged<CFError>?
guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
error!.takeRetainedValue() as Error
return nil
}
and then trying to attest this key using
self.iosDeviceAttestationManager.attestKey(keyId, clientDataHash: clientDataHash) { data, error in
guard let data = data else {
promise(.failure(error!))
return
}
promise(.success(data))
}
But this gives me error
Error Domain=com.apple.devicecheck.error Code=3 "(null)"
Which states fot InvalidKey
So is there any way how I could get reference to attested key to later use it for signing/verification purposes?
Thanks, in advance!