]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/clxutils/findCert/findCert.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / findCert / findCert.cpp
diff --git a/SecurityTests/clxutils/findCert/findCert.cpp b/SecurityTests/clxutils/findCert/findCert.cpp
new file mode 100644 (file)
index 0000000..6343719
--- /dev/null
@@ -0,0 +1,144 @@
+/* 
+ * Find all certs in keychain search list matching specified email address.
+ */
+#include <Security/Security.h>
+#include <Security/SecKeychainItemPriv.h>
+#include <unistd.h>
+#include <security_cdsa_utils/cuPrintCert.h>
+#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 : "<any>");
+       CFRelease(srch);
+       return 0;
+}
+