How can I extract all root CA certificates from all the keychains on OSX programmatically in pem format?
Keychain programming services should allow this but how?
Any help would be appreciable.
How can I extract all root CA certificates from all the keychains on OSX programmatically in pem format?
Keychain programming services should allow this but how?
Any help would be appreciable.
security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain >certs-roots.pem
security find-certificate -a -p /Library/Keychains/System.keychain >certs-system.pem
security find-certificate -a -p ~/Library/Keychains/login.keychain-db >certs-user.pem
BTW: You can see those paths in Keychain Access when you hover over the Keychains list (top/left).
You can combine system and user pems by using the default certificate source
security find-certificate -a -p >certs.pem
This is super useful for node.js, when you want to use require('https').request on typical corporate internal stuff without having to resort to hacks like accepting any certificate without checking. You don't need to include the system roots since nodejs has you covered already for those.
NODE_EXTRA_CA_CERTS=certs.pem node
Answering my own question: On OSX you can invoke a NSTask to get response from the security command line utility:
security find-certificate -a -p /System/Library/Keychains/SystemCACertificates.keychain > allcerts.pem
Hey I know I'm late to this but I came across the same problem today and spent many hours figuring out how to do this. I know that the original poster might not need to know this anymore but hopefully this helps someone.
The following is my code to exactly replicate what you've done without using the command line.
+ (NSURL *)createCertsFileInDirectory:(NSURL *)directory {
NSString *outPath = [directory path];
if (!outPath) {
return nil;
}
outPath = [outPath stringByAppendingPathComponent:@"allcerts.pem"];
NSURL * outURL = [NSURL fileURLWithPath:outPath];
SecKeychainRef keychain;
if (SecKeychainOpen("/System/Library/Keychains/SystemCACertificates.keychain", &keychain) != errSecSuccess) {
return nil;
}
CFMutableArrayRef searchList = CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
CFArrayAppendValue(searchList, keychain);
CFTypeRef keys[] = { kSecClass, kSecMatchLimit, kSecAttrCanVerify, kSecMatchSearchList };
CFTypeRef values[] = { kSecClassCertificate, kSecMatchLimitAll, kCFBooleanTrue, searchList };
CFDictionaryRef dict = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFTypeRef results;
OSStatus status = SecItemCopyMatching(dict, &results);
CFArrayRef arr = (CFArrayRef) results;
NSLog(@"total item count = %ld", CFArrayGetCount(arr));
CFRelease(dict);
CFRelease(searchList);
CFRelease(keychain);
if (status != errSecSuccess) {
return nil;
}
CFDataRef certsData;
status = SecItemExport(results, kSecFormatPEMSequence, kSecItemPemArmour, NULL, &certsData);
CFRelease(results);
if (status != errSecSuccess) {
return nil;
}
NSData *topLevelData = (NSData *) CFBridgingRelease(certsData);
if (![topLevelData writeToURL:outURL atomically:YES]) {
return nil;
}
return outURL;
}
© 2022 - 2024 — McMap. All rights reserved.