Get SecKey reference to key from DCAppAttestService.generateKey()

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!

Replies

No answer from apple support team?

did you get any update on this ?

Any success? Or any walk-around to get access/reference to keys generated for the attestation?