Reputation: 821
I want to import the OSX/iOS certificates into an OpenSSL context at runtime. To do this I am using SecItemCopyMatching with the following code to retrieve the certificates from the OS keychain:
CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(NULL, 4, NULL, NULL);
CFDictionaryAddValue(attrDict, kSecClass, kSecClassCertificate);
CFDictionaryAddValue(attrDict, kSecReturnRef, kCFBooleanTrue);
CFDictionaryAddValue(attrDict, kSecMatchLimit, kSecMatchLimitAll);
CFDictionaryAddValue(attrDict, kSecMatchTrustedOnly, kCFBooleanTrue );
res = SecItemCopyMatching(attrDict, (CFTypeRef*)&certlist);
This seems to return the user and system certificates, but it does not return the contents of "System Roots" in the keychain. How can I retrieve these a well?
Upvotes: 4
Views: 915
Reputation: 321
Also remember that typically certificates under System Roots are not marked as trusted. They are implicitly "trusted" because that keychain is read-only. So I'd suggest you use:
CFDictionaryAddValue(attrDict, kSecMatchTrustedOnly, kCFBooleanFalse );
Upvotes: 0
Reputation: 1461
I hit the same problem and this is the solution that I found: Manually open System Roots keychain and add it to the search list for the query as follows:
SecKeychainRef systemRoots = NULL;
OSStatus kcStatus = SecKeychainOpen("/System/Library/Keychains/SystemRootCertificates.keychain", &systemRoots);
CFArrayRef currentSearchList;
SecKeychainCopySearchList(¤tSearchList);
CFMutableArrayRef newSearchList = CFArrayCreateMutableCopy(NULL, 5, currentSearchList);
CFRelease(currentSearchList);
if (!kcStatus) {
CFArrayAppendValue(newSearchList, systemRoots);
}
CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(NULL, 5, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(attrDict, kSecMatchSearchList, newSearchList); // this is the important part
Upvotes: 5