|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include "signtool.h" |
|
6 #include "pk11func.h" |
|
7 #include "certdb.h" |
|
8 |
|
9 static int num_trav_certs = 0; |
|
10 static SECStatus cert_trav_callback(CERTCertificate *cert, SECItem *k, |
|
11 void *data); |
|
12 |
|
13 /********************************************************************* |
|
14 * |
|
15 * L i s t C e r t s |
|
16 */ |
|
17 int |
|
18 ListCerts(char *key, int list_certs) |
|
19 { |
|
20 int failed = 0; |
|
21 SECStatus rv; |
|
22 char *ugly_list; |
|
23 CERTCertDBHandle * db; |
|
24 |
|
25 CERTCertificate * cert; |
|
26 CERTVerifyLog errlog; |
|
27 |
|
28 errlog.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
|
29 if ( errlog.arena == NULL) { |
|
30 out_of_memory(); |
|
31 } |
|
32 errlog.head = NULL; |
|
33 errlog.tail = NULL; |
|
34 errlog.count = 0; |
|
35 |
|
36 ugly_list = PORT_ZAlloc (16); |
|
37 |
|
38 if (ugly_list == NULL) { |
|
39 out_of_memory(); |
|
40 } |
|
41 |
|
42 *ugly_list = 0; |
|
43 |
|
44 db = CERT_GetDefaultCertDB(); |
|
45 |
|
46 if (list_certs == 2) { |
|
47 PR_fprintf(outputFD, "\nS Certificates\n"); |
|
48 PR_fprintf(outputFD, "- ------------\n"); |
|
49 } else { |
|
50 PR_fprintf(outputFD, "\nObject signing certificates\n"); |
|
51 PR_fprintf(outputFD, "---------------------------------------\n"); |
|
52 } |
|
53 |
|
54 num_trav_certs = 0; |
|
55 |
|
56 /* Traverse ALL tokens in all slots, authenticating to them all */ |
|
57 rv = PK11_TraverseSlotCerts(cert_trav_callback, (void * )&list_certs, |
|
58 &pwdata); |
|
59 |
|
60 if (rv) { |
|
61 PR_fprintf(outputFD, "**Traverse of ALL slots & tokens failed**\n"); |
|
62 return - 1; |
|
63 } |
|
64 |
|
65 if (num_trav_certs == 0) { |
|
66 PR_fprintf(outputFD, |
|
67 "You don't appear to have any object signing certificates.\n"); |
|
68 } |
|
69 |
|
70 if (list_certs == 2) { |
|
71 PR_fprintf(outputFD, "- ------------\n"); |
|
72 } else { |
|
73 PR_fprintf(outputFD, "---------------------------------------\n"); |
|
74 } |
|
75 |
|
76 if (list_certs == 1) { |
|
77 PR_fprintf(outputFD, |
|
78 "For a list including CA's, use \"%s -L\"\n", PROGRAM_NAME); |
|
79 } |
|
80 |
|
81 if (list_certs == 2) { |
|
82 PR_fprintf(outputFD, |
|
83 "Certificates that can be used to sign objects have *'s to " |
|
84 "their left.\n"); |
|
85 } |
|
86 |
|
87 if (key) { |
|
88 /* Do an analysis of the given cert */ |
|
89 |
|
90 cert = PK11_FindCertFromNickname(key, &pwdata); |
|
91 |
|
92 if (cert) { |
|
93 PR_fprintf(outputFD, |
|
94 "\nThe certificate with nickname \"%s\" was found:\n", |
|
95 cert->nickname); |
|
96 PR_fprintf(outputFD, "\tsubject name: %s\n", cert->subjectName); |
|
97 PR_fprintf(outputFD, "\tissuer name: %s\n", cert->issuerName); |
|
98 |
|
99 PR_fprintf(outputFD, "\n"); |
|
100 |
|
101 rv = CERT_CertTimesValid (cert); |
|
102 if (rv != SECSuccess) { |
|
103 PR_fprintf(outputFD, "**This certificate is expired**\n"); |
|
104 } else { |
|
105 PR_fprintf(outputFD, "This certificate is not expired.\n"); |
|
106 } |
|
107 |
|
108 rv = CERT_VerifyCert (db, cert, PR_TRUE, |
|
109 certUsageObjectSigner, PR_Now(), &pwdata, &errlog); |
|
110 |
|
111 if (rv != SECSuccess) { |
|
112 failed = 1; |
|
113 if (errlog.count > 0) { |
|
114 PR_fprintf(outputFD, |
|
115 "**Certificate validation failed for the " |
|
116 "following reason(s):**\n"); |
|
117 } else { |
|
118 PR_fprintf(outputFD, "**Certificate validation failed**"); |
|
119 } |
|
120 } else { |
|
121 PR_fprintf(outputFD, "This certificate is valid.\n"); |
|
122 } |
|
123 displayVerifyLog(&errlog); |
|
124 |
|
125 |
|
126 } else { |
|
127 failed = 1; |
|
128 PR_fprintf(outputFD, |
|
129 "The certificate with nickname \"%s\" was NOT FOUND\n", key); |
|
130 } |
|
131 } |
|
132 |
|
133 if (errlog.arena != NULL) { |
|
134 PORT_FreeArena(errlog.arena, PR_FALSE); |
|
135 } |
|
136 |
|
137 if (failed) { |
|
138 return - 1; |
|
139 } |
|
140 return 0; |
|
141 } |
|
142 |
|
143 |
|
144 /******************************************************************** |
|
145 * |
|
146 * c e r t _ t r a v _ c a l l b a c k |
|
147 */ |
|
148 static SECStatus |
|
149 cert_trav_callback(CERTCertificate *cert, SECItem *k, void *data) |
|
150 { |
|
151 int list_certs = 1; |
|
152 char *name; |
|
153 |
|
154 if (data) { |
|
155 list_certs = *((int * )data); |
|
156 } |
|
157 |
|
158 #define LISTING_USER_SIGNING_CERTS (list_certs == 1) |
|
159 #define LISTING_ALL_CERTS (list_certs == 2) |
|
160 |
|
161 name = cert->nickname; |
|
162 if (name) { |
|
163 int isSigningCert; |
|
164 |
|
165 isSigningCert = cert->nsCertType & NS_CERT_TYPE_OBJECT_SIGNING; |
|
166 if (!isSigningCert && LISTING_USER_SIGNING_CERTS) |
|
167 return (SECSuccess); |
|
168 |
|
169 /* Display this name or email address */ |
|
170 num_trav_certs++; |
|
171 |
|
172 if (LISTING_ALL_CERTS) { |
|
173 PR_fprintf(outputFD, "%s ", isSigningCert ? "*" : " "); |
|
174 } |
|
175 PR_fprintf(outputFD, "%s\n", name); |
|
176 |
|
177 if (LISTING_USER_SIGNING_CERTS) { |
|
178 int rv = SECFailure; |
|
179 if (rv) { |
|
180 CERTCertificate * issuerCert; |
|
181 issuerCert = CERT_FindCertIssuer(cert, PR_Now(), |
|
182 certUsageObjectSigner); |
|
183 if (issuerCert) { |
|
184 if (issuerCert->nickname && issuerCert->nickname[0]) { |
|
185 PR_fprintf(outputFD, " Issued by: %s\n", |
|
186 issuerCert->nickname); |
|
187 rv = SECSuccess; |
|
188 } |
|
189 CERT_DestroyCertificate(issuerCert); |
|
190 } |
|
191 } |
|
192 if (rv && cert->issuerName && cert->issuerName[0]) { |
|
193 PR_fprintf(outputFD, " Issued by: %s \n", cert->issuerName); |
|
194 } |
|
195 { |
|
196 char *expires; |
|
197 expires = DER_TimeChoiceDayToAscii(&cert->validity.notAfter); |
|
198 if (expires) { |
|
199 PR_fprintf(outputFD, " Expires: %s\n", expires); |
|
200 PORT_Free(expires); |
|
201 } |
|
202 } |
|
203 |
|
204 rv = CERT_VerifyCertNow (cert->dbhandle, cert, |
|
205 PR_TRUE, certUsageObjectSigner, &pwdata); |
|
206 |
|
207 if (rv != SECSuccess) { |
|
208 rv = PORT_GetError(); |
|
209 PR_fprintf(outputFD, |
|
210 " ++ Error ++ THIS CERTIFICATE IS NOT VALID (%s)\n", |
|
211 secErrorString(rv)); |
|
212 } |
|
213 } |
|
214 } |
|
215 |
|
216 return (SECSuccess); |
|
217 } |
|
218 |
|
219 |