|
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 /* |
|
6 * Tool for converting builtin CA certs. |
|
7 */ |
|
8 |
|
9 #include "nssrenam.h" |
|
10 #include "nss.h" |
|
11 #include "cert.h" |
|
12 #include "certdb.h" |
|
13 #include "secutil.h" |
|
14 #include "pk11func.h" |
|
15 |
|
16 #if defined(WIN32) |
|
17 #include <fcntl.h> |
|
18 #include <io.h> |
|
19 #endif |
|
20 |
|
21 void dumpbytes(unsigned char *buf, int len) |
|
22 { |
|
23 int i; |
|
24 for (i=0; i < len; i++) { |
|
25 if ((i !=0) && ((i & 0xf) == 0)) { |
|
26 printf("\n"); |
|
27 } |
|
28 printf("\\%03o",buf[i]); |
|
29 } |
|
30 printf("\n"); |
|
31 } |
|
32 |
|
33 char *getTrustString(unsigned int trust) |
|
34 { |
|
35 if (trust & CERTDB_TRUSTED) { |
|
36 if (trust & CERTDB_TRUSTED_CA) { |
|
37 return "CKT_NSS_TRUSTED_DELEGATOR"; |
|
38 } else { |
|
39 return "CKT_NSS_TRUSTED"; |
|
40 } |
|
41 } else { |
|
42 if (trust & CERTDB_TRUSTED_CA) { |
|
43 return "CKT_NSS_TRUSTED_DELEGATOR"; |
|
44 } else if (trust & CERTDB_VALID_CA) { |
|
45 return "CKT_NSS_VALID_DELEGATOR"; |
|
46 } else if (trust & CERTDB_TERMINAL_RECORD) { |
|
47 return "CKT_NSS_NOT_TRUSTED"; |
|
48 } else { |
|
49 return "CKT_NSS_MUST_VERIFY_TRUST"; |
|
50 } |
|
51 } |
|
52 return "CKT_NSS_TRUST_UNKNOWN"; /* not reached */ |
|
53 } |
|
54 |
|
55 static const SEC_ASN1Template serialTemplate[] = { |
|
56 { SEC_ASN1_INTEGER, offsetof(CERTCertificate,serialNumber) }, |
|
57 { 0 } |
|
58 }; |
|
59 |
|
60 void print_crl_info(CERTName *name, SECItem *serial) |
|
61 { |
|
62 PRBool saveWrapeState = SECU_GetWrapEnabled(); |
|
63 SECU_EnableWrap(PR_FALSE); |
|
64 |
|
65 SECU_PrintNameQuotesOptional(stdout, name, "# Issuer", 0, PR_FALSE); |
|
66 printf("\n"); |
|
67 |
|
68 SECU_PrintInteger(stdout, serial, "# Serial Number", 0); |
|
69 |
|
70 SECU_EnableWrap(saveWrapeState); |
|
71 } |
|
72 |
|
73 static SECStatus |
|
74 ConvertCRLEntry(SECItem *sdder, PRInt32 crlentry, char *nickname) |
|
75 { |
|
76 int rv; |
|
77 PLArenaPool *arena = NULL; |
|
78 CERTSignedCrl *newCrl = NULL; |
|
79 CERTCrlEntry *entry; |
|
80 |
|
81 CERTName *name = NULL; |
|
82 SECItem *derName = NULL; |
|
83 SECItem *serial = NULL; |
|
84 |
|
85 rv = SEC_ERROR_NO_MEMORY; |
|
86 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
|
87 if (!arena) |
|
88 return rv; |
|
89 |
|
90 newCrl = CERT_DecodeDERCrlWithFlags(arena, sdder, SEC_CRL_TYPE, |
|
91 CRL_DECODE_DEFAULT_OPTIONS); |
|
92 if (!newCrl) |
|
93 return SECFailure; |
|
94 |
|
95 name = &newCrl->crl.name; |
|
96 derName = &newCrl->crl.derName; |
|
97 |
|
98 if (newCrl->crl.entries != NULL) { |
|
99 PRInt32 iv = 0; |
|
100 while ((entry = newCrl->crl.entries[iv++]) != NULL) { |
|
101 if (crlentry == iv) { |
|
102 serial = &entry->serialNumber; |
|
103 break; |
|
104 } |
|
105 } |
|
106 } |
|
107 |
|
108 if (!name || !derName || !serial) |
|
109 return SECFailure; |
|
110 |
|
111 printf("\n# Distrust \"%s\"\n",nickname); |
|
112 print_crl_info(name, serial); |
|
113 |
|
114 printf("CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST\n"); |
|
115 printf("CKA_TOKEN CK_BBOOL CK_TRUE\n"); |
|
116 printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n"); |
|
117 printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"); |
|
118 printf("CKA_LABEL UTF8 \"%s\"\n",nickname); |
|
119 |
|
120 printf("CKA_ISSUER MULTILINE_OCTAL\n"); |
|
121 dumpbytes(derName->data,derName->len); |
|
122 printf("END\n"); |
|
123 printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n"); |
|
124 printf("\\002\\%03o", serial->len); /* 002: type integer; len >=3 digits */ |
|
125 dumpbytes(serial->data,serial->len); |
|
126 printf("END\n"); |
|
127 |
|
128 printf("CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED\n"); |
|
129 printf("CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED\n"); |
|
130 printf("CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED\n"); |
|
131 printf("CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE\n"); |
|
132 |
|
133 PORT_FreeArena (arena, PR_FALSE); |
|
134 return rv; |
|
135 } |
|
136 |
|
137 void print_info(SECItem *sdder, CERTCertificate *c) |
|
138 { |
|
139 PRBool saveWrapeState = SECU_GetWrapEnabled(); |
|
140 SECU_EnableWrap(PR_FALSE); |
|
141 |
|
142 SECU_PrintNameQuotesOptional(stdout, &c->issuer, "# Issuer", 0, PR_FALSE); |
|
143 printf("\n"); |
|
144 |
|
145 SECU_PrintInteger(stdout, &c->serialNumber, "# Serial Number", 0); |
|
146 |
|
147 SECU_PrintNameQuotesOptional(stdout, &c->subject, "# Subject", 0, PR_FALSE); |
|
148 printf("\n"); |
|
149 |
|
150 SECU_PrintTimeChoice(stdout, &c->validity.notBefore, "# Not Valid Before", 0); |
|
151 SECU_PrintTimeChoice(stdout, &c->validity.notAfter, "# Not Valid After ", 0); |
|
152 |
|
153 SECU_PrintFingerprints(stdout, sdder, "# Fingerprint", 0); |
|
154 |
|
155 SECU_EnableWrap(saveWrapeState); |
|
156 } |
|
157 |
|
158 static SECStatus |
|
159 ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust, |
|
160 PRBool excludeCert, PRBool excludeHash) |
|
161 { |
|
162 SECStatus rv = SECSuccess; |
|
163 CERTCertificate *cert; |
|
164 unsigned char sha1_hash[SHA1_LENGTH]; |
|
165 unsigned char md5_hash[MD5_LENGTH]; |
|
166 SECItem *serial = NULL; |
|
167 PRBool step_up = PR_FALSE; |
|
168 const char *trust_info; |
|
169 |
|
170 cert = CERT_DecodeDERCertificate(sdder, PR_FALSE, nickname); |
|
171 if (!cert) { |
|
172 return SECFailure; |
|
173 } |
|
174 serial = SEC_ASN1EncodeItem(NULL,NULL,cert,serialTemplate); |
|
175 if (!serial) { |
|
176 return SECFailure; |
|
177 } |
|
178 |
|
179 if (!excludeCert) { |
|
180 printf("\n#\n# Certificate \"%s\"\n#\n",nickname); |
|
181 print_info(sdder, cert); |
|
182 printf("CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n"); |
|
183 printf("CKA_TOKEN CK_BBOOL CK_TRUE\n"); |
|
184 printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n"); |
|
185 printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"); |
|
186 printf("CKA_LABEL UTF8 \"%s\"\n",nickname); |
|
187 printf("CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n"); |
|
188 printf("CKA_SUBJECT MULTILINE_OCTAL\n"); |
|
189 dumpbytes(cert->derSubject.data,cert->derSubject.len); |
|
190 printf("END\n"); |
|
191 printf("CKA_ID UTF8 \"0\"\n"); |
|
192 printf("CKA_ISSUER MULTILINE_OCTAL\n"); |
|
193 dumpbytes(cert->derIssuer.data,cert->derIssuer.len); |
|
194 printf("END\n"); |
|
195 printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n"); |
|
196 dumpbytes(serial->data,serial->len); |
|
197 printf("END\n"); |
|
198 printf("CKA_VALUE MULTILINE_OCTAL\n"); |
|
199 dumpbytes(sdder->data,sdder->len); |
|
200 printf("END\n"); |
|
201 } |
|
202 |
|
203 if ((trust->sslFlags | trust->emailFlags | trust->objectSigningFlags) |
|
204 == CERTDB_TERMINAL_RECORD) |
|
205 trust_info = "Distrust"; |
|
206 else |
|
207 trust_info = "Trust for"; |
|
208 |
|
209 printf("\n# %s \"%s\"\n", trust_info, nickname); |
|
210 print_info(sdder, cert); |
|
211 |
|
212 printf("CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST\n"); |
|
213 printf("CKA_TOKEN CK_BBOOL CK_TRUE\n"); |
|
214 printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n"); |
|
215 printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"); |
|
216 printf("CKA_LABEL UTF8 \"%s\"\n",nickname); |
|
217 |
|
218 if (!excludeHash) { |
|
219 PK11_HashBuf(SEC_OID_SHA1, sha1_hash, sdder->data, sdder->len); |
|
220 printf("CKA_CERT_SHA1_HASH MULTILINE_OCTAL\n"); |
|
221 dumpbytes(sha1_hash,SHA1_LENGTH); |
|
222 printf("END\n"); |
|
223 PK11_HashBuf(SEC_OID_MD5, md5_hash, sdder->data, sdder->len); |
|
224 printf("CKA_CERT_MD5_HASH MULTILINE_OCTAL\n"); |
|
225 dumpbytes(md5_hash,MD5_LENGTH); |
|
226 printf("END\n"); |
|
227 } |
|
228 |
|
229 printf("CKA_ISSUER MULTILINE_OCTAL\n"); |
|
230 dumpbytes(cert->derIssuer.data,cert->derIssuer.len); |
|
231 printf("END\n"); |
|
232 printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n"); |
|
233 dumpbytes(serial->data,serial->len); |
|
234 printf("END\n"); |
|
235 |
|
236 printf("CKA_TRUST_SERVER_AUTH CK_TRUST %s\n", |
|
237 getTrustString(trust->sslFlags)); |
|
238 printf("CKA_TRUST_EMAIL_PROTECTION CK_TRUST %s\n", |
|
239 getTrustString(trust->emailFlags)); |
|
240 printf("CKA_TRUST_CODE_SIGNING CK_TRUST %s\n", |
|
241 getTrustString(trust->objectSigningFlags)); |
|
242 #ifdef notdef |
|
243 printf("CKA_TRUST_CLIENT_AUTH CK_TRUST CKT_NSS_TRUSTED\n"); |
|
244 printf("CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
|
245 printf("CKA_TRUST_NON_REPUDIATION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
|
246 printf("CKA_TRUST_KEY_ENCIPHERMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
|
247 printf("CKA_TRUST_DATA_ENCIPHERMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
|
248 printf("CKA_TRUST_KEY_AGREEMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
|
249 printf("CKA_TRUST_KEY_CERT_SIGN CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n"); |
|
250 #endif |
|
251 |
|
252 step_up = (trust->sslFlags & CERTDB_GOVT_APPROVED_CA); |
|
253 printf("CKA_TRUST_STEP_UP_APPROVED CK_BBOOL %s\n", |
|
254 step_up ? "CK_TRUE" : "CK_FALSE"); |
|
255 |
|
256 PORT_Free(sdder->data); |
|
257 return(rv); |
|
258 |
|
259 } |
|
260 |
|
261 void printheader() { |
|
262 printf("# \n" |
|
263 "# This Source Code Form is subject to the terms of the Mozilla Public\n" |
|
264 "# License, v. 2.0. If a copy of the MPL was not distributed with this\n" |
|
265 "# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n" |
|
266 "#\n" |
|
267 "CVS_ID \"@(#) $RCSfile$ $Revision$ $Date$\"\n" |
|
268 "\n" |
|
269 "#\n" |
|
270 "# certdata.txt\n" |
|
271 "#\n" |
|
272 "# This file contains the object definitions for the certs and other\n" |
|
273 "# information \"built into\" NSS.\n" |
|
274 "#\n" |
|
275 "# Object definitions:\n" |
|
276 "#\n" |
|
277 "# Certificates\n" |
|
278 "#\n" |
|
279 "# -- Attribute -- -- type -- -- value --\n" |
|
280 "# CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n" |
|
281 "# CKA_TOKEN CK_BBOOL CK_TRUE\n" |
|
282 "# CKA_PRIVATE CK_BBOOL CK_FALSE\n" |
|
283 "# CKA_MODIFIABLE CK_BBOOL CK_FALSE\n" |
|
284 "# CKA_LABEL UTF8 (varies)\n" |
|
285 "# CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n" |
|
286 "# CKA_SUBJECT DER+base64 (varies)\n" |
|
287 "# CKA_ID byte array (varies)\n" |
|
288 "# CKA_ISSUER DER+base64 (varies)\n" |
|
289 "# CKA_SERIAL_NUMBER DER+base64 (varies)\n" |
|
290 "# CKA_VALUE DER+base64 (varies)\n" |
|
291 "# CKA_NSS_EMAIL ASCII7 (unused here)\n" |
|
292 "#\n" |
|
293 "# Trust\n" |
|
294 "#\n" |
|
295 "# -- Attribute -- -- type -- -- value --\n" |
|
296 "# CKA_CLASS CK_OBJECT_CLASS CKO_TRUST\n" |
|
297 "# CKA_TOKEN CK_BBOOL CK_TRUE\n" |
|
298 "# CKA_PRIVATE CK_BBOOL CK_FALSE\n" |
|
299 "# CKA_MODIFIABLE CK_BBOOL CK_FALSE\n" |
|
300 "# CKA_LABEL UTF8 (varies)\n" |
|
301 "# CKA_ISSUER DER+base64 (varies)\n" |
|
302 "# CKA_SERIAL_NUMBER DER+base64 (varies)\n" |
|
303 "# CKA_CERT_HASH binary+base64 (varies)\n" |
|
304 "# CKA_EXPIRES CK_DATE (not used here)\n" |
|
305 "# CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST (varies)\n" |
|
306 "# CKA_TRUST_NON_REPUDIATION CK_TRUST (varies)\n" |
|
307 "# CKA_TRUST_KEY_ENCIPHERMENT CK_TRUST (varies)\n" |
|
308 "# CKA_TRUST_DATA_ENCIPHERMENT CK_TRUST (varies)\n" |
|
309 "# CKA_TRUST_KEY_AGREEMENT CK_TRUST (varies)\n" |
|
310 "# CKA_TRUST_KEY_CERT_SIGN CK_TRUST (varies)\n" |
|
311 "# CKA_TRUST_CRL_SIGN CK_TRUST (varies)\n" |
|
312 "# CKA_TRUST_SERVER_AUTH CK_TRUST (varies)\n" |
|
313 "# CKA_TRUST_CLIENT_AUTH CK_TRUST (varies)\n" |
|
314 "# CKA_TRUST_CODE_SIGNING CK_TRUST (varies)\n" |
|
315 "# CKA_TRUST_EMAIL_PROTECTION CK_TRUST (varies)\n" |
|
316 "# CKA_TRUST_IPSEC_END_SYSTEM CK_TRUST (varies)\n" |
|
317 "# CKA_TRUST_IPSEC_TUNNEL CK_TRUST (varies)\n" |
|
318 "# CKA_TRUST_IPSEC_USER CK_TRUST (varies)\n" |
|
319 "# CKA_TRUST_TIME_STAMPING CK_TRUST (varies)\n" |
|
320 "# (other trust attributes can be defined)\n" |
|
321 "#\n" |
|
322 "\n" |
|
323 "#\n" |
|
324 "# The object to tell NSS that this is a root list and we don't\n" |
|
325 "# have to go looking for others.\n" |
|
326 "#\n" |
|
327 "BEGINDATA\n" |
|
328 "CKA_CLASS CK_OBJECT_CLASS CKO_NSS_BUILTIN_ROOT_LIST\n" |
|
329 "CKA_TOKEN CK_BBOOL CK_TRUE\n" |
|
330 "CKA_PRIVATE CK_BBOOL CK_FALSE\n" |
|
331 "CKA_MODIFIABLE CK_BBOOL CK_FALSE\n" |
|
332 "CKA_LABEL UTF8 \"Mozilla Builtin Roots\"\n"); |
|
333 } |
|
334 |
|
335 static void Usage(char *progName) |
|
336 { |
|
337 fprintf(stderr, "%s -t trust -n nickname [-i certfile] [-c] [-h]\n", progName); |
|
338 fprintf(stderr, |
|
339 "\tRead a der-encoded cert from certfile or stdin, and output\n" |
|
340 "\tit to stdout in a format suitable for the builtin root module.\n" |
|
341 "\tExample: %s -n MyCA -t \"C,C,C\" -i myca.der >> certdata.txt\n", |
|
342 progName); |
|
343 fprintf(stderr, "%s -D -n label [-i certfile]\n", progName); |
|
344 fprintf(stderr, |
|
345 "\tRead a der-encoded cert from certfile or stdin, and output\n" |
|
346 "\ta distrust record.\n" |
|
347 "\t(-D is equivalent to -t p,p,p -c -h)\n"); |
|
348 fprintf(stderr, "%s -C -e crl-entry-number -n label [-i crlfile]\n", progName); |
|
349 fprintf(stderr, |
|
350 "\tRead a CRL from crlfile or stdin, and output\n" |
|
351 "\ta distrust record (issuer+serial).\n" |
|
352 "\t(-C implies -c -h)\n"); |
|
353 fprintf(stderr, "%-15s trust flags (cCTpPuw).\n", "-t trust"); |
|
354 fprintf(stderr, "%-15s nickname to assign to builtin cert, or\n", |
|
355 "-n nickname"); |
|
356 fprintf(stderr, "%-15s a label for the distrust record.\n", ""); |
|
357 fprintf(stderr, "%-15s exclude the certificate (only add a trust record)\n", "-c"); |
|
358 fprintf(stderr, "%-15s exclude hash from trust record\n", "-h"); |
|
359 fprintf(stderr, "%-15s (useful to distrust any matching issuer/serial)\n", ""); |
|
360 fprintf(stderr, "%-15s (not allowed when adding positive trust)\n", ""); |
|
361 fprintf(stderr, "%-15s a CRL entry number, as shown by \"crlutil -S\"\n", "-e"); |
|
362 fprintf(stderr, "%-15s input file to read (default stdin)\n", "-i file"); |
|
363 fprintf(stderr, "%-15s (pipe through atob if the cert is b64-encoded)\n", ""); |
|
364 exit(-1); |
|
365 } |
|
366 |
|
367 enum { |
|
368 opt_Input = 0, |
|
369 opt_Nickname, |
|
370 opt_Trust, |
|
371 opt_Distrust, |
|
372 opt_ExcludeCert, |
|
373 opt_ExcludeHash, |
|
374 opt_DistrustCRL, |
|
375 opt_CRLEnry |
|
376 }; |
|
377 |
|
378 static secuCommandFlag addbuiltin_options[] = |
|
379 { |
|
380 { /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE }, |
|
381 { /* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE }, |
|
382 { /* opt_Trust */ 't', PR_TRUE, 0, PR_FALSE }, |
|
383 { /* opt_Distrust */ 'D', PR_FALSE, 0, PR_FALSE }, |
|
384 { /* opt_ExcludeCert */ 'c', PR_FALSE, 0, PR_FALSE }, |
|
385 { /* opt_ExcludeHash */ 'h', PR_FALSE, 0, PR_FALSE }, |
|
386 { /* opt_DistrustCRL */ 'C', PR_FALSE, 0, PR_FALSE }, |
|
387 { /* opt_CRLEnry */ 'e', PR_TRUE, 0, PR_FALSE }, |
|
388 }; |
|
389 |
|
390 int main(int argc, char **argv) |
|
391 { |
|
392 SECStatus rv; |
|
393 char *nickname = NULL; |
|
394 char *trusts = NULL; |
|
395 char *progName; |
|
396 PRFileDesc *infile; |
|
397 CERTCertTrust trust = { 0 }; |
|
398 SECItem derItem = { 0 }; |
|
399 PRInt32 crlentry = 0; |
|
400 PRInt32 mutuallyExclusiveOpts = 0; |
|
401 PRBool decodeTrust = PR_FALSE; |
|
402 |
|
403 secuCommand addbuiltin = { 0 }; |
|
404 addbuiltin.numOptions = sizeof(addbuiltin_options)/sizeof(secuCommandFlag); |
|
405 addbuiltin.options = addbuiltin_options; |
|
406 |
|
407 progName = strrchr(argv[0], '/'); |
|
408 progName = progName ? progName+1 : argv[0]; |
|
409 |
|
410 rv = SECU_ParseCommandLine(argc, argv, progName, &addbuiltin); |
|
411 |
|
412 if (rv != SECSuccess) |
|
413 Usage(progName); |
|
414 |
|
415 if (addbuiltin.options[opt_Trust].activated) |
|
416 ++mutuallyExclusiveOpts; |
|
417 if (addbuiltin.options[opt_Distrust].activated) |
|
418 ++mutuallyExclusiveOpts; |
|
419 if (addbuiltin.options[opt_DistrustCRL].activated) |
|
420 ++mutuallyExclusiveOpts; |
|
421 |
|
422 if (mutuallyExclusiveOpts != 1) { |
|
423 fprintf(stderr, "%s: you must specify exactly one of -t or -D or -C\n", |
|
424 progName); |
|
425 Usage(progName); |
|
426 } |
|
427 |
|
428 if (addbuiltin.options[opt_DistrustCRL].activated) { |
|
429 if (!addbuiltin.options[opt_CRLEnry].activated) { |
|
430 fprintf(stderr, "%s: you must specify the CRL entry number.\n", |
|
431 progName); |
|
432 Usage(progName); |
|
433 } |
|
434 else { |
|
435 crlentry = atoi(addbuiltin.options[opt_CRLEnry].arg); |
|
436 if (crlentry < 1) { |
|
437 fprintf(stderr, "%s: The CRL entry number must be > 0.\n", |
|
438 progName); |
|
439 Usage(progName); |
|
440 } |
|
441 } |
|
442 } |
|
443 |
|
444 if (!addbuiltin.options[opt_Nickname].activated) { |
|
445 fprintf(stderr, "%s: you must specify parameter -n (a nickname or a label).\n", |
|
446 progName); |
|
447 Usage(progName); |
|
448 } |
|
449 |
|
450 if (addbuiltin.options[opt_Input].activated) { |
|
451 infile = PR_Open(addbuiltin.options[opt_Input].arg, PR_RDONLY, 00660); |
|
452 if (!infile) { |
|
453 fprintf(stderr, "%s: failed to open input file.\n", progName); |
|
454 exit(1); |
|
455 } |
|
456 } else { |
|
457 #if defined(WIN32) |
|
458 /* If we're going to read binary data from stdin, we must put stdin |
|
459 ** into O_BINARY mode or else incoming \r\n's will become \n's, |
|
460 ** and latin-1 characters will be altered. |
|
461 */ |
|
462 |
|
463 int smrv = _setmode(_fileno(stdin), _O_BINARY); |
|
464 if (smrv == -1) { |
|
465 fprintf(stderr, |
|
466 "%s: Cannot change stdin to binary mode. Use -i option instead.\n", |
|
467 progName); |
|
468 exit(1); |
|
469 } |
|
470 #endif |
|
471 infile = PR_STDIN; |
|
472 } |
|
473 |
|
474 #if defined(WIN32) |
|
475 /* We must put stdout into O_BINARY mode or else the output will include |
|
476 ** carriage returns. |
|
477 */ |
|
478 { |
|
479 int smrv = _setmode(_fileno(stdout), _O_BINARY); |
|
480 if (smrv == -1) { |
|
481 fprintf(stderr, "%s: Cannot change stdout to binary mode.\n", progName); |
|
482 exit(1); |
|
483 } |
|
484 } |
|
485 #endif |
|
486 |
|
487 nickname = strdup(addbuiltin.options[opt_Nickname].arg); |
|
488 |
|
489 NSS_NoDB_Init(NULL); |
|
490 |
|
491 if (addbuiltin.options[opt_Distrust].activated || |
|
492 addbuiltin.options[opt_DistrustCRL].activated) { |
|
493 addbuiltin.options[opt_ExcludeCert].activated = PR_TRUE; |
|
494 addbuiltin.options[opt_ExcludeHash].activated = PR_TRUE; |
|
495 } |
|
496 |
|
497 if (addbuiltin.options[opt_Distrust].activated) { |
|
498 trusts = strdup("p,p,p"); |
|
499 decodeTrust = PR_TRUE; |
|
500 } |
|
501 else if (addbuiltin.options[opt_Trust].activated) { |
|
502 trusts = strdup(addbuiltin.options[opt_Trust].arg); |
|
503 decodeTrust = PR_TRUE; |
|
504 } |
|
505 |
|
506 if (decodeTrust) { |
|
507 rv = CERT_DecodeTrustString(&trust, trusts); |
|
508 if (rv) { |
|
509 fprintf(stderr, "%s: incorrectly formatted trust string.\n", progName); |
|
510 Usage(progName); |
|
511 } |
|
512 } |
|
513 |
|
514 if (addbuiltin.options[opt_Trust].activated && |
|
515 addbuiltin.options[opt_ExcludeHash].activated) { |
|
516 if ((trust.sslFlags | trust.emailFlags | trust.objectSigningFlags) |
|
517 != CERTDB_TERMINAL_RECORD) { |
|
518 fprintf(stderr, "%s: Excluding the hash only allowed with distrust.\n", progName); |
|
519 Usage(progName); |
|
520 } |
|
521 } |
|
522 |
|
523 SECU_FileToItem(&derItem, infile); |
|
524 |
|
525 /*printheader();*/ |
|
526 |
|
527 if (addbuiltin.options[opt_DistrustCRL].activated) { |
|
528 rv = ConvertCRLEntry(&derItem, crlentry, nickname); |
|
529 } |
|
530 else { |
|
531 rv = ConvertCertificate(&derItem, nickname, &trust, |
|
532 addbuiltin.options[opt_ExcludeCert].activated, |
|
533 addbuiltin.options[opt_ExcludeHash].activated); |
|
534 if (rv) { |
|
535 fprintf(stderr, "%s: failed to convert certificate.\n", progName); |
|
536 exit(1); |
|
537 } |
|
538 } |
|
539 |
|
540 if (NSS_Shutdown() != SECSuccess) { |
|
541 exit(1); |
|
542 } |
|
543 |
|
544 return(SECSuccess); |
|
545 } |