]>
Commit | Line | Data |
---|---|---|
d8f41ccd A |
1 | /* |
2 | * Find all certs in keychain search list matching specified email address. | |
3 | */ | |
4 | #include <Security/Security.h> | |
5 | #include <Security/SecKeychainItemPriv.h> | |
6 | #include <unistd.h> | |
7 | #include <security_cdsa_utils/cuPrintCert.h> | |
8 | #include "asnUtils.h" | |
9 | ||
10 | static void usage(char **argv) | |
11 | { | |
12 | printf("Usage: %s [emailaddrs] [option...]\n", argv[0]); | |
13 | printf("Options:\n"); | |
14 | printf(" -p -- print cert contents\n"); | |
15 | printf(" -a -- show all certs, no email match\n"); | |
16 | printf(" -A -- add to default keychain\n"); | |
17 | exit(1); | |
18 | } | |
19 | ||
20 | int main(int argc, char **argv) | |
21 | { | |
22 | if(argc < 2) { | |
23 | usage(argv); | |
24 | } | |
25 | ||
26 | bool print_cert = false; | |
27 | bool allCerts = false; | |
28 | const char *emailAddress = NULL; | |
29 | bool addToKC = false; | |
30 | ||
31 | extern int optind; | |
32 | optind = 1; | |
33 | ||
34 | if(argv[1][0] != '-') { | |
35 | /* normal case, email address specified */ | |
36 | emailAddress = argv[1]; | |
37 | optind++; | |
38 | } | |
39 | ||
40 | extern char *optarg; | |
41 | int arg; | |
42 | while ((arg = getopt(argc, argv, "aphA")) != -1) { | |
43 | switch (arg) { | |
44 | case 'p': | |
45 | print_cert = true; | |
46 | break; | |
47 | case 'a': | |
48 | allCerts = true; | |
49 | break; | |
50 | case 'A': | |
51 | addToKC = true; | |
52 | break; | |
53 | case 'h': | |
54 | default: | |
55 | usage(argv); | |
56 | } | |
57 | } | |
58 | if(optind != argc) { | |
59 | usage(argv); | |
60 | } | |
61 | if(!allCerts && (emailAddress == NULL)) { | |
62 | printf("***You must specify either an email address or the -a option.\n"); | |
63 | exit(1); | |
64 | } | |
65 | ||
66 | OSStatus ortn; | |
67 | SecKeychainSearchRef srch; | |
68 | SecKeychainAttributeList attrList; | |
69 | SecKeychainAttribute attr; | |
70 | unsigned numCerts = 0; | |
71 | ||
72 | if(emailAddress) { | |
73 | attr.tag = kSecAlias; // i.e., email address | |
74 | attr.length = strlen(emailAddress); | |
75 | attr.data = (void *)emailAddress; | |
76 | attrList.count = 1; | |
77 | attrList.attr = &attr; | |
78 | } | |
79 | else { | |
80 | attrList.count = 0; | |
81 | attrList.attr = NULL; | |
82 | } | |
83 | ortn = SecKeychainSearchCreateFromAttributes(NULL, // default search list | |
84 | kSecCertificateItemClass, | |
85 | &attrList, | |
86 | &srch); | |
87 | if(ortn) { | |
88 | cssmPerror("SecKeychainSearchCreateFromAttributes", ortn); | |
89 | exit(1); | |
90 | } | |
91 | ||
92 | do { | |
93 | SecCertificateRef certRef = NULL; | |
94 | CSSM_DATA certData; | |
95 | ||
96 | ortn = SecKeychainSearchCopyNext(srch, (SecKeychainItemRef *)&certRef); | |
97 | if(ortn) { | |
98 | break; | |
99 | } | |
100 | ortn = SecCertificateGetData(certRef, &certData); | |
101 | if(ortn) { | |
102 | cssmPerror("SecCertificateGetData", ortn); | |
103 | continue; | |
104 | } | |
105 | ||
106 | printf("=== Cert %u ===\n", numCerts); | |
107 | printCertName(certData.Data, certData.Length, NameBoth); | |
108 | if(print_cert) { | |
109 | printCert(certData.Data, certData.Length, CSSM_FALSE); | |
110 | } | |
111 | if(addToKC) { | |
112 | /* | |
113 | * Can't call SecCertificateAddToKeychain directly since this | |
114 | * cert already has a keychain. | |
115 | */ | |
116 | SecCertificateRef newCertRef = NULL; | |
117 | ortn = SecCertificateCreateFromData(&certData, | |
118 | CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, | |
119 | &newCertRef); | |
120 | if(ortn) { | |
121 | cssmPerror("SecCertificateCreateFromData", ortn); | |
122 | printf("***Error adding this cert to default keychain.\n"); | |
123 | } | |
124 | else { | |
125 | ortn = SecCertificateAddToKeychain(newCertRef, NULL); | |
126 | if(ortn) { | |
127 | cssmPerror("SecCertificateAddToKeychain", ortn); | |
128 | printf("***Error adding this cert to default keychain.\n"); | |
129 | } | |
130 | else { | |
131 | printf("...cert added to default keychain.\n"); | |
132 | } | |
133 | CFRelease(newCertRef); | |
134 | } | |
135 | } | |
136 | CFRelease(certRef); | |
137 | numCerts++; | |
138 | } while(ortn == noErr); | |
139 | printf("...%u certs found matching email address \'%s\'\n", numCerts, | |
140 | emailAddress ? emailAddress : "<any>"); | |
141 | CFRelease(srch); | |
142 | return 0; | |
143 | } | |
144 |