We generate key pair and import cert with access flag kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly in our application. We then have notification extension that access shared keychain to retrieve the identity when device is locked. We use SecItemCopyMatching to get all SecIdentity with its attributes as below:
let queryDict: [String: Any] = [
kSecClass as String: kSecClassIdentity,
kSecReturnAttributes as String: true,
kSecReturnRef as String: true,
kSecMatchLimit as String: kSecMatchLimitAll
]
var oss = SecItemCopyMatching(queryDict as CFDictionary, &attrs)
When the code runs on notification extension with locked device, it failed on some devices (not on all devices) with error -25308. The sysdiagnose shows:
default securityd 2024-03-14 10:49:13.844996 -0400 129 0x110115 SecDbKeychainItemV7: cannot decrypt metadata key because the keychain is locked (-25308)
default securityd 2024-03-14 10:49:13.845036 -0400 129 0x110091 NSExtension[2222]/1#7 LF=0 copy_matching Error Domain=NSOSStatusErrorDomain Code=-25308 "ks_crypt: e00002e2 failed to 'od' item (class 6, bag: 0) Access to item attempted while keychain is locked." UserInfo={numberOfErrorsDeep=0, NSDescription=ks_crypt: e00002e2 failed to 'od' item (class 6, bag: 0) Access to item attempted while keychain is locked.}
We also try to use access flag kSecAttrAccessibleAlwaysThisDeviceOnly, but it doesn't make difference. Since securityd reports "cannot decrypt metadata key because keychain is locked". I wonder if it is because we query attributes for all identity. Is it a bug on Security framework?
Thanks, Ying
i actually already asked user to try a build with change to use
kSecAttrAccessibleAlwaysThisDeviceOnly
when generating key pair & importing cert, but the problem still exist.
Did this test delete all the previous identities before adding this new one? If not, please try this.
My goal of this test is to see whether this problem is tied to the specific private key that you previously generated.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"