I'm a little confused about the keychain implementation here.
As mentioned in On Mac Keychains:
The Keychain and SecKeychain APIs only talk to the file-based keychain. The SecItem API talks to either implementation. Specifically, it talks to the data protection keychain if you supply either the kSecUseDataProtectionKeychain or the kSecAttrSynchronizable attribute. If not, it talks to the file-based keychain.
The keychain should default to file-based, since I'm working with MacOS and I didn't set either kSecAttrSynchronizable or kSecUseDataProtectionKeychain. I didn't get why the keychain is considered as data protection here.
However, inspired by the article, I manually set the above two attributes to false. And eventually I got the error:
OSStatus -25304 : The specified item is no longer valid. It may have been deleted from the keychain.
It seems like I did something wrong when I create the SecKeyRef, so it failed to find it. I applied SecKeyCreateWithData to create the SecKey as described here Storing CryptoKit Keys in the Keychain. Though the example is for CryptoKit, I assume the API should also work for pure data... or am I wrong here?
Here is the implementation, and key_error returns NULL. I assume the key creation succeed.
CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(my_alloc, 0, NULL, NULL);
CFDictionarySetValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeECSECPrimeRandom);
CFDictionarySetValue(parameters, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
CFDictionarySetValue(parameters, kSecUseDataProtectionKeychain, kCFBooleanFalse);
CFDictionarySetValue(parameters, kSecAttrSynchronizable, kCFBooleanFalse);
CFDictionarySetValue(parameters, kSecUseKeychain, keychain); // Not sure if the keychain attribute works here ...?
// key_data is the binary data read from ANSI file, which is a ECC key in X963 format.
SecKeyRef privKey = SecKeyCreateWithData(key_data, parameters, &key_error);