I'm having several issues with managing certificates in the default keychain using swift on macOS.
I have a self containd command line test program with hardcoded pem format cert and private key.
I can convert both pem formats to der via openssl.
Issue 1, For Certificate:
I can create a certificate and add it to the keychain.
I am not able to find or delete the certificate after I add it.
Issue 2, For the key:
I can create the key but when I try to add it to the keychain I get "A required entitlement isn't present."
In our actual app, I can add certs but can't find them (success but cert returned does not match). I can add keys and find them. All using similar code to my test app, so I decided to write the test and got stuck. I don't see any special entitlements for keychain access in our app.
Looking for answers on issue 1 and issue 2.
I have a self contained public github project here as it won't let me attach a zip: https://github.com/alfieeisenberg/cgcertmgr
It won't let me attach a zip of the project or my source.
In both cases below I tried with just labels, just tags, and both with same results.
Here is how I'm trying to add keys:
func addPrivateKeyToKeychain(privateKey: SecKey, label: String) -> Bool {
let addQuery: [NSString: Any] = [
kSecClass: kSecClassKey,
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
kSecAttrLabel: label,
kSecAttrApplicationTag: label,
kSecValueRef: privateKey
]
let status = SecItemAdd(addQuery as CFDictionary, nil)
if status != errSecSuccess {
if status == errSecDuplicateItem {
print("\(#function): \(#line), Key already exists: errSecDuplicateItem")
}
print("\(#function): \(#line), status: \(status) \(SecCopyErrorMessageString(status, nil) as String? ?? "Unknown error")")
}
return status == errSecSuccess
}
Here is adding certs:
func addCertificateToKeychain(certificate: SecCertificate, label: String) -> Bool {
let addQuery: [NSString: Any] = [
kSecClass: kSecClassCertificate,
kSecAttrLabel: label,
kSecAttrApplicationTag: label,
kSecValueRef: certificate
]
let status = SecItemAdd(addQuery as CFDictionary, nil)
if status != errSecSuccess {
print("\(#function): \(#line), status: \(status) \(SecCopyErrorMessageString(status, nil) as String? ?? "Unknown error")")
}
return status == errSecSuccess
}
And finding a cert:
func findCertificateInKeychain(label: String) -> SecCertificate? {
let query: [NSString: Any] = [
kSecClass: kSecClassCertificate,
kSecAttrLabel: label,
kSecAttrApplicationTag: label,
kSecReturnRef: kCFBooleanTrue!,
kSecMatchLimit: kSecMatchLimitOne
]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
print("\(#function): \(#line), status: \(status)")
if status != errSecSuccess {
print("\(#function): \(#line), status: \(status) \(SecCopyErrorMessageString(status, nil) as String? ?? "Unknown error")")
}
guard status == errSecSuccess, let certificate = item else {
print("\(#function): \(#line), Certificate not found")
return nil
}
return (certificate as! SecCertificate)
}
Output:
===Trying Certs===
tryCerts(pemCertificate:): 338, Certificate added: true
findCertificateInKeychain(label:): 272, status: -25300
findCertificateInKeychain(label:): 274, status: -25300 The specified item could not be found in the keychain.
findCertificateInKeychain(label:): 277, Certificate not found
tryCerts(pemCertificate:): 340, Certificate found: nil
deleteCertificateFromKeychain(label:): 314, status: -25300 The specified item could not be found in the keychain.
tryCerts(pemCertificate:): 342, Certificate deleted: false
===Trying Keys===
addPrivateKeyToKeychain(privateKey:label:): 256, status: -34018 A required entitlement isn't present.
Program ended with exit code: 0
Post
Replies
Boosts
Views
Activity
We have a sandboxed swift app with an associated network extension where both write to the same log file in a shared container (via NSFileCoordinator)
On sonoma all was good. With sequoia, we get a popup requesting access to the file from the user.
I realize this is all in the name of security, but is there any way to prevent this popup?
alf