X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/SecurityTests/clxutils/findCert/findCert.cpp diff --git a/SecurityTests/clxutils/findCert/findCert.cpp b/SecurityTests/clxutils/findCert/findCert.cpp new file mode 100644 index 00000000..6343719f --- /dev/null +++ b/SecurityTests/clxutils/findCert/findCert.cpp @@ -0,0 +1,144 @@ +/* + * Find all certs in keychain search list matching specified email address. + */ +#include +#include +#include +#include +#include "asnUtils.h" + +static void usage(char **argv) +{ + printf("Usage: %s [emailaddrs] [option...]\n", argv[0]); + printf("Options:\n"); + printf(" -p -- print cert contents\n"); + printf(" -a -- show all certs, no email match\n"); + printf(" -A -- add to default keychain\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + if(argc < 2) { + usage(argv); + } + + bool print_cert = false; + bool allCerts = false; + const char *emailAddress = NULL; + bool addToKC = false; + + extern int optind; + optind = 1; + + if(argv[1][0] != '-') { + /* normal case, email address specified */ + emailAddress = argv[1]; + optind++; + } + + extern char *optarg; + int arg; + while ((arg = getopt(argc, argv, "aphA")) != -1) { + switch (arg) { + case 'p': + print_cert = true; + break; + case 'a': + allCerts = true; + break; + case 'A': + addToKC = true; + break; + case 'h': + default: + usage(argv); + } + } + if(optind != argc) { + usage(argv); + } + if(!allCerts && (emailAddress == NULL)) { + printf("***You must specify either an email address or the -a option.\n"); + exit(1); + } + + OSStatus ortn; + SecKeychainSearchRef srch; + SecKeychainAttributeList attrList; + SecKeychainAttribute attr; + unsigned numCerts = 0; + + if(emailAddress) { + attr.tag = kSecAlias; // i.e., email address + attr.length = strlen(emailAddress); + attr.data = (void *)emailAddress; + attrList.count = 1; + attrList.attr = &attr; + } + else { + attrList.count = 0; + attrList.attr = NULL; + } + ortn = SecKeychainSearchCreateFromAttributes(NULL, // default search list + kSecCertificateItemClass, + &attrList, + &srch); + if(ortn) { + cssmPerror("SecKeychainSearchCreateFromAttributes", ortn); + exit(1); + } + + do { + SecCertificateRef certRef = NULL; + CSSM_DATA certData; + + ortn = SecKeychainSearchCopyNext(srch, (SecKeychainItemRef *)&certRef); + if(ortn) { + break; + } + ortn = SecCertificateGetData(certRef, &certData); + if(ortn) { + cssmPerror("SecCertificateGetData", ortn); + continue; + } + + printf("=== Cert %u ===\n", numCerts); + printCertName(certData.Data, certData.Length, NameBoth); + if(print_cert) { + printCert(certData.Data, certData.Length, CSSM_FALSE); + } + if(addToKC) { + /* + * Can't call SecCertificateAddToKeychain directly since this + * cert already has a keychain. + */ + SecCertificateRef newCertRef = NULL; + ortn = SecCertificateCreateFromData(&certData, + CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, + &newCertRef); + if(ortn) { + cssmPerror("SecCertificateCreateFromData", ortn); + printf("***Error adding this cert to default keychain.\n"); + } + else { + ortn = SecCertificateAddToKeychain(newCertRef, NULL); + if(ortn) { + cssmPerror("SecCertificateAddToKeychain", ortn); + printf("***Error adding this cert to default keychain.\n"); + } + else { + printf("...cert added to default keychain.\n"); + } + CFRelease(newCertRef); + } + } + CFRelease(certRef); + numCerts++; + } while(ortn == noErr); + printf("...%u certs found matching email address \'%s\'\n", numCerts, + emailAddress ? emailAddress : ""); + CFRelease(srch); + return 0; +} +