File: | s/cmd/crlutil/crlutil.c |
Warning: | line 893, column 13 Although the value stored to 'status' is used in the enclosing expression, the value is never actually read from 'status' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ** certutil.c |
7 | ** |
8 | ** utility for managing certificates and the cert database |
9 | ** |
10 | */ |
11 | /* test only */ |
12 | |
13 | #include "nspr.h" |
14 | #include "plgetopt.h" |
15 | #include "secutil.h" |
16 | #include "cert.h" |
17 | #include "certi.h" |
18 | #include "certdb.h" |
19 | #include "nss.h" |
20 | #include "pk11func.h" |
21 | #include "crlgen.h" |
22 | |
23 | #define SEC_CERT_DB_EXISTS0 0 |
24 | #define SEC_CREATE_CERT_DB1 1 |
25 | |
26 | static char *progName; |
27 | |
28 | static CERTSignedCrl * |
29 | FindCRL(CERTCertDBHandle *certHandle, char *name, int type) |
30 | { |
31 | CERTSignedCrl *crl = NULL((void*)0); |
32 | CERTCertificate *cert = NULL((void*)0); |
33 | SECItem derName; |
34 | |
35 | derName.data = NULL((void*)0); |
36 | derName.len = 0; |
37 | |
38 | cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, name); |
39 | if (!cert) { |
40 | CERTName *certName = NULL((void*)0); |
41 | PLArenaPool *arena = NULL((void*)0); |
42 | SECStatus rv = SECSuccess; |
43 | |
44 | certName = CERT_AsciiToName(name); |
45 | if (certName) { |
46 | arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048)); |
47 | if (arena) { |
48 | SECItem *nameItem = |
49 | SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, NULL((void*)0), (void *)certName, |
50 | SEC_ASN1_GET(CERT_NameTemplate)CERT_NameTemplate); |
51 | if (nameItem) { |
52 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &derName, nameItem); |
53 | } |
54 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0); |
55 | } |
56 | CERT_DestroyName(certName); |
57 | } |
58 | |
59 | if (rv != SECSuccess) { |
60 | SECU_PrintError(progName, "SECITEM_CopyItem failed, out of memory"); |
61 | return ((CERTSignedCrl *)NULL((void*)0)); |
62 | } |
63 | |
64 | if (!derName.len || !derName.data) { |
65 | SECU_PrintError(progName, "could not find certificate named '%s'", name); |
66 | return ((CERTSignedCrl *)NULL((void*)0)); |
67 | } |
68 | } else { |
69 | SECStatus rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &derName, &cert->derSubject); |
70 | CERT_DestroyCertificate(cert); |
71 | if (rv != SECSuccess) { |
72 | return ((CERTSignedCrl *)NULL((void*)0)); |
73 | } |
74 | } |
75 | |
76 | crl = SEC_FindCrlByName(certHandle, &derName, type); |
77 | if (crl == NULL((void*)0)) |
78 | SECU_PrintError(progName, "could not find %s's CRL", name); |
79 | if (derName.data) { |
80 | SECITEM_FreeItemSECITEM_FreeItem_Util(&derName, PR_FALSE0); |
81 | } |
82 | return (crl); |
83 | } |
84 | |
85 | static SECStatus |
86 | DisplayCRL(CERTCertDBHandle *certHandle, char *nickName, int crlType) |
87 | { |
88 | CERTSignedCrl *crl = NULL((void*)0); |
89 | |
90 | crl = FindCRL(certHandle, nickName, crlType); |
91 | |
92 | if (crl) { |
93 | SECU_PrintCRLInfo(stdoutstdout, &crl->crl, "CRL Info:\n", 0); |
94 | SEC_DestroyCrl(crl); |
95 | return SECSuccess; |
96 | } |
97 | return SECFailure; |
98 | } |
99 | |
100 | static void |
101 | ListCRLNames(CERTCertDBHandle *certHandle, int crlType, PRBool deletecrls) |
102 | { |
103 | CERTCrlHeadNode *crlList = NULL((void*)0); |
104 | CERTCrlNode *crlNode = NULL((void*)0); |
105 | CERTName *name = NULL((void*)0); |
106 | PLArenaPool *arena = NULL((void*)0); |
107 | SECStatus rv; |
108 | |
109 | do { |
110 | arena = PORT_NewArenaPORT_NewArena_Util(SEC_ASN1_DEFAULT_ARENA_SIZE(2048)); |
111 | if (arena == NULL((void*)0)) { |
112 | fprintf(stderrstderr, "%s: fail to allocate memory\n", progName); |
113 | break; |
114 | } |
115 | |
116 | name = PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena, sizeof(*name)); |
117 | if (name == NULL((void*)0)) { |
118 | fprintf(stderrstderr, "%s: fail to allocate memory\n", progName); |
119 | break; |
120 | } |
121 | name->arena = arena; |
122 | |
123 | rv = SEC_LookupCrls(certHandle, &crlList, crlType); |
124 | if (rv != SECSuccess) { |
125 | fprintf(stderrstderr, "%s: fail to look up CRLs (%s)\n", progName, |
126 | SECU_Strerror(PORT_GetError())PR_ErrorToString((PORT_GetError_Util()), 0)); |
127 | break; |
128 | } |
129 | |
130 | /* just in case */ |
131 | if (!crlList) |
132 | break; |
133 | |
134 | crlNode = crlList->first; |
135 | |
136 | fprintf(stdoutstdout, "\n"); |
137 | fprintf(stdoutstdout, "\n%-40s %-5s\n\n", "CRL names", "CRL Type"); |
138 | while (crlNode) { |
139 | char *asciiname = NULL((void*)0); |
140 | CERTCertificate *cert = NULL((void*)0); |
141 | if (crlNode->crl && crlNode->crl->crl.derName.data != NULL((void*)0)) { |
142 | cert = CERT_FindCertByName(certHandle, |
143 | &crlNode->crl->crl.derName); |
144 | if (!cert) { |
145 | SECU_PrintError(progName, "could not find signing " |
146 | "certificate in database"); |
147 | } |
148 | } |
149 | if (cert) { |
150 | char *certName = NULL((void*)0); |
151 | if (cert->nickname && PORT_Strlen(cert->nickname)strlen(cert->nickname) > 0) { |
152 | certName = cert->nickname; |
153 | } else if (cert->emailAddr && PORT_Strlen(cert->emailAddr)strlen(cert->emailAddr) > 0) { |
154 | certName = cert->emailAddr; |
155 | } |
156 | if (certName) { |
157 | asciiname = PORT_StrdupPORT_Strdup_Util(certName); |
158 | } |
159 | CERT_DestroyCertificate(cert); |
160 | } |
161 | |
162 | if (!asciiname) { |
163 | name = &crlNode->crl->crl.name; |
164 | if (!name) { |
165 | SECU_PrintError(progName, "fail to get the CRL " |
166 | "issuer name"); |
167 | continue; |
168 | } |
169 | asciiname = CERT_NameToAscii(name); |
170 | } |
171 | fprintf(stdoutstdout, "%-40s %-5s\n", asciiname, "CRL"); |
172 | if (asciiname) { |
173 | PORT_FreePORT_Free_Util(asciiname); |
174 | } |
175 | if (PR_TRUE1 == deletecrls) { |
176 | CERTSignedCrl *acrl = NULL((void*)0); |
177 | SECItem *issuer = &crlNode->crl->crl.derName; |
178 | acrl = SEC_FindCrlByName(certHandle, issuer, crlType); |
179 | if (acrl) { |
180 | SEC_DeletePermCRL(acrl); |
181 | SEC_DestroyCrl(acrl); |
182 | } |
183 | } |
184 | crlNode = crlNode->next; |
185 | } |
186 | |
187 | } while (0); |
188 | if (crlList) |
189 | PORT_FreeArenaPORT_FreeArena_Util(crlList->arena, PR_FALSE0); |
190 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0); |
191 | } |
192 | |
193 | static SECStatus |
194 | ListCRL(CERTCertDBHandle *certHandle, char *nickName, int crlType) |
195 | { |
196 | if (nickName == NULL((void*)0)) { |
197 | ListCRLNames(certHandle, crlType, PR_FALSE0); |
198 | return SECSuccess; |
199 | } |
200 | |
201 | return DisplayCRL(certHandle, nickName, crlType); |
202 | } |
203 | |
204 | static SECStatus |
205 | DeleteCRL(CERTCertDBHandle *certHandle, char *name, int type) |
206 | { |
207 | CERTSignedCrl *crl = NULL((void*)0); |
208 | SECStatus rv = SECFailure; |
209 | |
210 | crl = FindCRL(certHandle, name, type); |
211 | if (!crl) { |
212 | SECU_PrintError(progName, "could not find the issuer %s's CRL", name); |
213 | return SECFailure; |
214 | } |
215 | rv = SEC_DeletePermCRL(crl); |
216 | SEC_DestroyCrl(crl); |
217 | if (rv != SECSuccess) { |
218 | SECU_PrintError(progName, "fail to delete the issuer %s's CRL " |
219 | "from the perm database (reason: %s)", |
220 | name, SECU_Strerror(PORT_GetError())PR_ErrorToString((PORT_GetError_Util()), 0)); |
221 | return SECFailure; |
222 | } |
223 | return (rv); |
224 | } |
225 | |
226 | SECStatus |
227 | ImportCRL(CERTCertDBHandle *certHandle, char *url, int type, |
228 | PRFileDesc *inFile, PRInt32 importOptions, PRInt32 decodeOptions, |
229 | secuPWData *pwdata) |
230 | { |
231 | CERTSignedCrl *crl = NULL((void*)0); |
232 | SECItem crlDER; |
233 | PK11SlotInfo *slot = NULL((void*)0); |
234 | int rv; |
235 | |
236 | crlDER.data = NULL((void*)0); |
237 | |
238 | /* Read in the entire file specified with the -f argument */ |
239 | rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE0, PR_FALSE0); |
240 | if (rv != SECSuccess) { |
241 | SECU_PrintError(progName, "unable to read input file"); |
242 | return (SECFailure); |
243 | } |
244 | |
245 | decodeOptions |= CRL_DECODE_DONT_COPY_DER0x00000001; |
246 | |
247 | slot = PK11_GetInternalKeySlot(); |
248 | |
249 | if (PK11_NeedLogin(slot)) { |
250 | rv = PK11_Authenticate(slot, PR_TRUE1, pwdata); |
251 | if (rv != SECSuccess) |
252 | goto loser; |
253 | } |
254 | |
255 | crl = PK11_ImportCRL(slot, &crlDER, url, type, |
256 | NULL((void*)0), importOptions, NULL((void*)0), decodeOptions); |
257 | |
258 | if (!crl) { |
259 | const char *errString; |
260 | |
261 | rv = SECFailure; |
262 | errString = SECU_Strerror(PORT_GetError())PR_ErrorToString((PORT_GetError_Util()), 0); |
263 | if (errString && PORT_Strlen(errString)strlen(errString) == 0) |
264 | SECU_PrintError(progName, |
265 | "CRL is not imported (error: input CRL is not up to date.)"); |
266 | else |
267 | SECU_PrintError(progName, "unable to import CRL"); |
268 | } else { |
269 | SEC_DestroyCrl(crl); |
270 | } |
271 | loser: |
272 | if (slot) { |
273 | PK11_FreeSlot(slot); |
274 | } |
275 | SECITEM_FreeItemSECITEM_FreeItem_Util(&crlDER, PR_FALSE0); |
276 | return (rv); |
277 | } |
278 | |
279 | SECStatus |
280 | DumpCRL(PRFileDesc *inFile) |
281 | { |
282 | int rv; |
283 | PLArenaPool *arena = NULL((void*)0); |
284 | CERTSignedCrl *newCrl = NULL((void*)0); |
285 | |
286 | SECItem crlDER; |
287 | crlDER.data = NULL((void*)0); |
288 | |
289 | /* Read in the entire file specified with the -f argument */ |
290 | rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE0, PR_FALSE0); |
291 | if (rv != SECSuccess) { |
292 | SECU_PrintError(progName, "unable to read input file"); |
293 | return (SECFailure); |
294 | } |
295 | |
296 | rv = SEC_ERROR_NO_MEMORY; |
297 | arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048)); |
298 | if (!arena) |
299 | return rv; |
300 | |
301 | newCrl = CERT_DecodeDERCrlWithFlags(arena, &crlDER, SEC_CRL_TYPE1, |
302 | CRL_DECODE_DEFAULT_OPTIONS0x00000000); |
303 | if (!newCrl) |
304 | return SECFailure; |
305 | |
306 | SECU_PrintCRLInfo(stdoutstdout, &newCrl->crl, "CRL file contents", 0); |
307 | |
308 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0); |
309 | return rv; |
310 | } |
311 | |
312 | static CERTCertificate * |
313 | FindSigningCert(CERTCertDBHandle *certHandle, CERTSignedCrl *signCrl, |
314 | char *certNickName) |
315 | { |
316 | CERTCertificate *cert = NULL((void*)0), *certTemp = NULL((void*)0); |
317 | SECStatus rv = SECFailure; |
318 | CERTAuthKeyID *authorityKeyID = NULL((void*)0); |
319 | SECItem *subject = NULL((void*)0); |
320 | |
321 | PORT_Assert(certHandle != NULL)((certHandle != ((void*)0))?((void)0):PR_Assert("certHandle != NULL" ,"crlutil.c",321)); |
322 | if (!certHandle || (!signCrl && !certNickName)) { |
323 | SECU_PrintError(progName, "invalid args for function " |
324 | "FindSigningCert \n"); |
325 | return NULL((void*)0); |
326 | } |
327 | |
328 | if (signCrl) { |
329 | #if 0 |
330 | authorityKeyID = SECU_FindCRLAuthKeyIDExten(tmpArena, scrl); |
331 | #endif |
332 | subject = &signCrl->crl.derName; |
333 | } else { |
334 | certTemp = CERT_FindCertByNickname(certHandle, certNickName); |
335 | if (!certTemp) { |
336 | SECU_PrintError(progName, "could not find certificate \"%s\" " |
337 | "in database", |
338 | certNickName); |
339 | goto loser; |
340 | } |
341 | subject = &certTemp->derSubject; |
342 | } |
343 | |
344 | cert = SECU_FindCrlIssuer(certHandle, subject, authorityKeyID, PR_Now()); |
345 | if (!cert) { |
346 | SECU_PrintError(progName, "could not find signing certificate " |
347 | "in database"); |
348 | goto loser; |
349 | } else { |
350 | rv = SECSuccess; |
351 | } |
352 | |
353 | loser: |
354 | if (certTemp) |
355 | CERT_DestroyCertificate(certTemp); |
356 | if (cert && rv != SECSuccess) |
357 | CERT_DestroyCertificate(cert); |
358 | return cert; |
359 | } |
360 | |
361 | static CERTSignedCrl * |
362 | CreateModifiedCRLCopy(PLArenaPool *arena, CERTCertDBHandle *certHandle, |
363 | CERTCertificate **cert, char *certNickName, |
364 | PRFileDesc *inFile, PRInt32 decodeOptions, |
365 | PRInt32 importOptions, secuPWData *pwdata) |
366 | { |
367 | SECItem crlDER = { 0, NULL((void*)0), 0 }; |
368 | CERTSignedCrl *signCrl = NULL((void*)0); |
369 | CERTSignedCrl *modCrl = NULL((void*)0); |
370 | PLArenaPool *modArena = NULL((void*)0); |
371 | SECStatus rv = SECSuccess; |
372 | |
373 | if (!arena || !certHandle || !certNickName) { |
374 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); |
375 | SECU_PrintError(progName, "CreateModifiedCRLCopy: invalid args\n"); |
376 | return NULL((void*)0); |
377 | } |
378 | |
379 | modArena = PORT_NewArenaPORT_NewArena_Util(SEC_ASN1_DEFAULT_ARENA_SIZE(2048)); |
380 | if (!modArena) { |
381 | SECU_PrintError(progName, "fail to allocate memory\n"); |
382 | return NULL((void*)0); |
383 | } |
384 | |
385 | if (inFile != NULL((void*)0)) { |
386 | rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE0, PR_FALSE0); |
387 | if (rv != SECSuccess) { |
388 | SECU_PrintError(progName, "unable to read input file"); |
389 | goto loser; |
390 | } |
391 | |
392 | decodeOptions |= CRL_DECODE_DONT_COPY_DER0x00000001; |
393 | |
394 | modCrl = CERT_DecodeDERCrlWithFlags(modArena, &crlDER, SEC_CRL_TYPE1, |
395 | decodeOptions); |
396 | if (!modCrl) { |
397 | SECU_PrintError(progName, "fail to decode CRL"); |
398 | goto loser; |
399 | } |
400 | |
401 | if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS0x00000001)) { |
402 | /* If caCert is a v2 certificate, make sure that it |
403 | * can be used for crl signing purpose */ |
404 | *cert = FindSigningCert(certHandle, modCrl, NULL((void*)0)); |
405 | if (!*cert) { |
406 | goto loser; |
407 | } |
408 | |
409 | rv = CERT_VerifySignedData(&modCrl->signatureWrap, *cert, |
410 | PR_Now(), pwdata); |
411 | if (rv != SECSuccess) { |
412 | SECU_PrintError(progName, "fail to verify signed data\n"); |
413 | goto loser; |
414 | } |
415 | } |
416 | } else { |
417 | modCrl = FindCRL(certHandle, certNickName, SEC_CRL_TYPE1); |
418 | if (!modCrl) { |
419 | SECU_PrintError(progName, "fail to find crl %s in database\n", |
420 | certNickName); |
421 | goto loser; |
422 | } |
423 | } |
424 | |
425 | signCrl = PORT_ArenaZNew(arena, CERTSignedCrl)(CERTSignedCrl *)PORT_ArenaZAlloc_Util(arena, sizeof(CERTSignedCrl )); |
426 | if (signCrl == NULL((void*)0)) { |
427 | SECU_PrintError(progName, "fail to allocate memory\n"); |
428 | goto loser; |
429 | } |
430 | |
431 | rv = SECU_CopyCRL(arena, &signCrl->crl, &modCrl->crl); |
432 | if (rv != SECSuccess) { |
433 | SECU_PrintError(progName, "unable to dublicate crl for " |
434 | "modification."); |
435 | goto loser; |
436 | } |
437 | |
438 | /* Make sure the update time is current. It can be modified later |
439 | * by "update <time>" command from crl generation script */ |
440 | rv = DER_EncodeTimeChoiceDER_EncodeTimeChoice_Util(arena, &signCrl->crl.lastUpdate, PR_Now()); |
441 | if (rv != SECSuccess) { |
442 | SECU_PrintError(progName, "fail to encode current time\n"); |
443 | goto loser; |
444 | } |
445 | |
446 | signCrl->arena = arena; |
447 | signCrl->referenceCount = 1; |
448 | |
449 | loser: |
450 | if (crlDER.data) { |
451 | SECITEM_FreeItemSECITEM_FreeItem_Util(&crlDER, PR_FALSE0); |
452 | } |
453 | if (modArena && (!modCrl || modCrl->arena != modArena)) { |
454 | PORT_FreeArenaPORT_FreeArena_Util(modArena, PR_FALSE0); |
455 | } |
456 | if (modCrl) |
457 | SEC_DestroyCrl(modCrl); |
458 | if (rv != SECSuccess && signCrl) { |
459 | SEC_DestroyCrl(signCrl); |
460 | signCrl = NULL((void*)0); |
461 | } |
462 | return signCrl; |
463 | } |
464 | |
465 | static CERTSignedCrl * |
466 | CreateNewCrl(PLArenaPool *arena, CERTCertDBHandle *certHandle, |
467 | CERTCertificate *cert) |
468 | { |
469 | CERTSignedCrl *signCrl = NULL((void*)0); |
470 | void *dummy = NULL((void*)0); |
471 | SECStatus rv; |
472 | void *mark = NULL((void*)0); |
473 | |
474 | /* if the CERTSignedCrl structure changes, this function will need to be |
475 | updated as well */ |
476 | if (!cert || !arena) { |
477 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); |
478 | SECU_PrintError(progName, "invalid args for function " |
479 | "CreateNewCrl\n"); |
480 | return NULL((void*)0); |
481 | } |
482 | |
483 | mark = PORT_ArenaMarkPORT_ArenaMark_Util(arena); |
484 | |
485 | signCrl = PORT_ArenaZNew(arena, CERTSignedCrl)(CERTSignedCrl *)PORT_ArenaZAlloc_Util(arena, sizeof(CERTSignedCrl )); |
486 | if (signCrl == NULL((void*)0)) { |
487 | SECU_PrintError(progName, "fail to allocate memory\n"); |
488 | return NULL((void*)0); |
489 | } |
490 | |
491 | dummy = SEC_ASN1EncodeIntegerSEC_ASN1EncodeInteger_Util(arena, &signCrl->crl.version, |
492 | SEC_CRL_VERSION_21); |
493 | /* set crl->version */ |
494 | if (!dummy) { |
495 | SECU_PrintError(progName, "fail to create crl version data " |
496 | "container\n"); |
497 | goto loser; |
498 | } |
499 | |
500 | /* copy SECItem name from cert */ |
501 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &signCrl->crl.derName, &cert->derSubject); |
502 | if (rv != SECSuccess) { |
503 | SECU_PrintError(progName, "fail to duplicate der name from " |
504 | "certificate.\n"); |
505 | goto loser; |
506 | } |
507 | |
508 | /* copy CERTName name structure from cert issuer */ |
509 | rv = CERT_CopyName(arena, &signCrl->crl.name, &cert->subject); |
510 | if (rv != SECSuccess) { |
511 | SECU_PrintError(progName, "fail to duplicate RD name from " |
512 | "certificate.\n"); |
513 | goto loser; |
514 | } |
515 | |
516 | rv = DER_EncodeTimeChoiceDER_EncodeTimeChoice_Util(arena, &signCrl->crl.lastUpdate, PR_Now()); |
517 | if (rv != SECSuccess) { |
518 | SECU_PrintError(progName, "fail to encode current time\n"); |
519 | goto loser; |
520 | } |
521 | |
522 | /* set fields */ |
523 | signCrl->arena = arena; |
524 | signCrl->dbhandle = certHandle; |
525 | signCrl->crl.arena = arena; |
526 | |
527 | PORT_ArenaUnmarkPORT_ArenaUnmark_Util(arena, mark); |
528 | |
529 | return signCrl; |
530 | |
531 | loser: |
532 | PORT_ArenaReleasePORT_ArenaRelease_Util(arena, mark); |
533 | return NULL((void*)0); |
534 | } |
535 | |
536 | static SECStatus |
537 | UpdateCrl(CERTSignedCrl *signCrl, PRFileDesc *inCrlInitFile) |
538 | { |
539 | CRLGENGeneratorData *crlGenData = NULL((void*)0); |
540 | SECStatus rv; |
541 | |
542 | if (!signCrl || !inCrlInitFile) { |
543 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS); |
544 | SECU_PrintError(progName, "invalid args for function " |
545 | "CreateNewCrl\n"); |
546 | return SECFailure; |
547 | } |
548 | |
549 | crlGenData = CRLGEN_InitCrlGeneration(signCrl, inCrlInitFile); |
550 | if (!crlGenData) { |
551 | SECU_PrintError(progName, "can not initialize parser structure.\n"); |
552 | return SECFailure; |
553 | } |
554 | |
555 | rv = CRLGEN_ExtHandleInit(crlGenData); |
556 | if (rv == SECFailure) { |
557 | SECU_PrintError(progName, "can not initialize entries handle.\n"); |
558 | goto loser; |
559 | } |
560 | |
561 | rv = CRLGEN_StartCrlGen(crlGenData); |
562 | if (rv != SECSuccess) { |
563 | SECU_PrintError(progName, "crl generation failed"); |
564 | goto loser; |
565 | } |
566 | |
567 | loser: |
568 | /* CommitExtensionsAndEntries is partially responsible for freeing |
569 | * up memory that was used for CRL generation. Should be called regardless |
570 | * of previouse call status, but only after initialization of |
571 | * crlGenData was done. It will commit all changes that was done before |
572 | * an error has occurred. |
573 | */ |
574 | if (SECSuccess != CRLGEN_CommitExtensionsAndEntries(crlGenData)) { |
575 | SECU_PrintError(progName, "crl generation failed"); |
576 | rv = SECFailure; |
577 | } |
578 | CRLGEN_FinalizeCrlGeneration(crlGenData); |
579 | return rv; |
580 | } |
581 | |
582 | static SECStatus |
583 | SignAndStoreCrl(CERTSignedCrl *signCrl, CERTCertificate *cert, |
584 | char *outFileName, SECOidTag hashAlgTag, int ascii, |
585 | char *slotName, char *url, secuPWData *pwdata) |
586 | { |
587 | PK11SlotInfo *slot = NULL((void*)0); |
588 | PRFileDesc *outFile = NULL((void*)0); |
589 | SECStatus rv; |
590 | SignAndEncodeFuncExitStat errCode; |
591 | |
592 | PORT_Assert(signCrl && (!ascii || outFileName))((signCrl && (!ascii || outFileName))?((void)0):PR_Assert ("signCrl && (!ascii || outFileName)","crlutil.c",592 )); |
593 | if (!signCrl || (ascii && !outFileName)) { |
594 | SECU_PrintError(progName, "invalid args for function " |
595 | "SignAndStoreCrl\n"); |
596 | return SECFailure; |
597 | } |
598 | |
599 | if (!slotName || !PL_strcmp(slotName, "internal")) |
600 | slot = PK11_GetInternalKeySlot(); |
601 | else |
602 | slot = PK11_FindSlotByName(slotName); |
603 | if (!slot) { |
604 | SECU_PrintError(progName, "can not find requested slot"); |
605 | return SECFailure; |
606 | } |
607 | |
608 | if (PK11_NeedLogin(slot)) { |
609 | rv = PK11_Authenticate(slot, PR_TRUE1, pwdata); |
610 | if (rv != SECSuccess) |
611 | goto loser; |
612 | } |
613 | |
614 | rv = SECU_SignAndEncodeCRL(cert, signCrl, hashAlgTag, &errCode); |
615 | if (rv != SECSuccess) { |
616 | char *errMsg = NULL((void*)0); |
617 | switch (errCode) { |
618 | case noKeyFound: |
619 | errMsg = "No private key found of signing cert"; |
620 | break; |
621 | |
622 | case noSignatureMatch: |
623 | errMsg = "Key and Algorithm OId are do not match"; |
624 | break; |
625 | |
626 | default: |
627 | case failToEncode: |
628 | errMsg = "Failed to encode crl structure"; |
629 | break; |
630 | |
631 | case failToSign: |
632 | errMsg = "Failed to sign crl structure"; |
633 | break; |
634 | |
635 | case noMem: |
636 | errMsg = "Can not allocate memory"; |
637 | break; |
638 | } |
639 | SECU_PrintError(progName, "%s\n", errMsg); |
640 | goto loser; |
641 | } |
642 | |
643 | if (outFileName) { |
644 | outFile = PR_Open(outFileName, PR_WRONLY0x02 | PR_CREATE_FILE0x08, PR_IRUSR00400 | PR_IWUSR00200); |
645 | if (!outFile) { |
646 | SECU_PrintError(progName, "unable to open \"%s\" for writing\n", |
647 | outFileName); |
648 | goto loser; |
649 | } |
650 | } |
651 | |
652 | rv = SECU_StoreCRL(slot, signCrl->derCrl, outFile, ascii, url); |
653 | if (rv != SECSuccess) { |
654 | SECU_PrintError(progName, "fail to save CRL\n"); |
655 | } |
656 | |
657 | loser: |
658 | if (outFile) |
659 | PR_Close(outFile); |
660 | if (slot) |
661 | PK11_FreeSlot(slot); |
662 | return rv; |
663 | } |
664 | |
665 | static SECStatus |
666 | GenerateCRL(CERTCertDBHandle *certHandle, char *certNickName, |
667 | PRFileDesc *inCrlInitFile, PRFileDesc *inFile, |
668 | char *outFileName, int ascii, char *slotName, |
669 | PRInt32 importOptions, char *alg, PRBool quiet, |
670 | PRInt32 decodeOptions, char *url, secuPWData *pwdata, |
671 | int modifyFlag) |
672 | { |
673 | CERTCertificate *cert = NULL((void*)0); |
674 | CERTSignedCrl *signCrl = NULL((void*)0); |
675 | PLArenaPool *arena = NULL((void*)0); |
676 | SECStatus rv; |
677 | SECOidTag hashAlgTag = SEC_OID_UNKNOWN; |
678 | |
679 | if (alg) { |
680 | hashAlgTag = SECU_StringToSignatureAlgTag(alg); |
681 | if (hashAlgTag == SEC_OID_UNKNOWN) { |
682 | SECU_PrintError(progName, "%s -Z: %s is not a recognized type.\n", |
683 | progName, alg); |
684 | return SECFailure; |
685 | } |
686 | } else { |
687 | hashAlgTag = SEC_OID_UNKNOWN; |
688 | } |
689 | |
690 | arena = PORT_NewArenaPORT_NewArena_Util(SEC_ASN1_DEFAULT_ARENA_SIZE(2048)); |
691 | if (!arena) { |
692 | SECU_PrintError(progName, "fail to allocate memory\n"); |
693 | return SECFailure; |
694 | } |
695 | |
696 | if (modifyFlag == PR_TRUE1) { |
697 | signCrl = CreateModifiedCRLCopy(arena, certHandle, &cert, certNickName, |
698 | inFile, decodeOptions, importOptions, |
699 | pwdata); |
700 | if (signCrl == NULL((void*)0)) { |
701 | rv = SECFailure; |
702 | goto loser; |
703 | } |
704 | } |
705 | |
706 | if (!cert) { |
707 | cert = FindSigningCert(certHandle, signCrl, certNickName); |
708 | if (cert == NULL((void*)0)) { |
709 | rv = SECFailure; |
710 | goto loser; |
711 | } |
712 | } |
713 | |
714 | if (!signCrl) { |
715 | if (modifyFlag == PR_TRUE1) { |
716 | if (!outFileName) { |
717 | int len = strlen(certNickName) + 5; |
718 | outFileName = PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, len); |
719 | PR_snprintf(outFileName, len, "%s.crl", certNickName); |
720 | } |
721 | SECU_PrintError(progName, "Will try to generate crl. " |
722 | "It will be saved in file: %s", |
723 | outFileName); |
724 | } |
725 | signCrl = CreateNewCrl(arena, certHandle, cert); |
726 | if (!signCrl) { |
727 | rv = SECFailure; |
728 | goto loser; |
729 | } |
730 | } |
731 | |
732 | rv = UpdateCrl(signCrl, inCrlInitFile); |
733 | if (rv != SECSuccess) { |
734 | goto loser; |
735 | } |
736 | |
737 | rv = SignAndStoreCrl(signCrl, cert, outFileName, hashAlgTag, ascii, |
738 | slotName, url, pwdata); |
739 | if (rv != SECSuccess) { |
740 | goto loser; |
741 | } |
742 | |
743 | if (signCrl && !quiet) { |
744 | SECU_PrintCRLInfo(stdoutstdout, &signCrl->crl, "CRL Info:\n", 0); |
745 | } |
746 | |
747 | loser: |
748 | if (arena && (!signCrl || !signCrl->arena)) |
749 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0); |
750 | if (signCrl) |
751 | SEC_DestroyCrl(signCrl); |
752 | if (cert) |
753 | CERT_DestroyCertificate(cert); |
754 | return (rv); |
755 | } |
756 | |
757 | static void |
758 | Usage() |
759 | { |
760 | fprintf(stderrstderr, |
761 | "Usage: %s -L [-n nickname] [-d keydir] [-P dbprefix] [-t crlType]\n" |
762 | " %s -D -n nickname [-d keydir] [-P dbprefix]\n" |
763 | " %s -S -i crl\n" |
764 | " %s -I -i crl -t crlType [-u url] [-d keydir] [-P dbprefix] [-B] " |
765 | "[-p pwd-file] -w [pwd-string]\n" |
766 | " %s -E -t crlType [-d keydir] [-P dbprefix]\n" |
767 | " %s -T\n" |
768 | " %s -G|-M -c crl-init-file -n nickname [-i crl] [-u url] " |
769 | "[-d keydir] [-P dbprefix] [-Z alg] ] [-p pwd-file] -w [pwd-string] " |
770 | "[-a] [-B]\n", |
771 | progName, progName, progName, progName, progName, progName, progName); |
772 | |
773 | fprintf(stderrstderr, "%-15s List CRL\n", "-L"); |
774 | fprintf(stderrstderr, "%-20s Specify the nickname of the CA certificate\n", |
775 | "-n nickname"); |
776 | fprintf(stderrstderr, "%-20s Key database directory (default is ~/.netscape)\n", |
777 | "-d keydir"); |
778 | fprintf(stderrstderr, "%-20s Cert & Key database prefix (default is \"\")\n", |
779 | "-P dbprefix"); |
780 | |
781 | fprintf(stderrstderr, "%-15s Delete a CRL from the cert database\n", "-D"); |
782 | fprintf(stderrstderr, "%-20s Specify the nickname for the CA certificate\n", |
783 | "-n nickname"); |
784 | fprintf(stderrstderr, "%-20s Specify the crl type.\n", "-t crlType"); |
785 | fprintf(stderrstderr, "%-20s Key database directory (default is ~/.netscape)\n", |
786 | "-d keydir"); |
787 | fprintf(stderrstderr, "%-20s Cert & Key database prefix (default is \"\")\n", |
788 | "-P dbprefix"); |
789 | |
790 | fprintf(stderrstderr, "%-15s Erase all CRLs of specified type from hte cert database\n", "-E"); |
791 | fprintf(stderrstderr, "%-20s Specify the crl type.\n", "-t crlType"); |
792 | fprintf(stderrstderr, "%-20s Key database directory (default is ~/.netscape)\n", |
793 | "-d keydir"); |
794 | fprintf(stderrstderr, "%-20s Cert & Key database prefix (default is \"\")\n", |
795 | "-P dbprefix"); |
796 | |
797 | fprintf(stderrstderr, "%-15s Show contents of a CRL file (without database)\n", "-S"); |
798 | fprintf(stderrstderr, "%-20s Specify the file which contains the CRL to show\n", |
799 | "-i crl"); |
800 | |
801 | fprintf(stderrstderr, "%-15s Import a CRL to the cert database\n", "-I"); |
802 | fprintf(stderrstderr, "%-20s Specify the file which contains the CRL to import\n", |
803 | "-i crl"); |
804 | fprintf(stderrstderr, "%-20s Specify the url.\n", "-u url"); |
805 | fprintf(stderrstderr, "%-20s Specify the crl type.\n", "-t crlType"); |
806 | fprintf(stderrstderr, "%-20s Key database directory (default is ~/.netscape)\n", |
807 | "-d keydir"); |
808 | fprintf(stderrstderr, "%-20s Cert & Key database prefix (default is \"\")\n", |
809 | "-P dbprefix"); |
810 | #ifdef DEBUG1 |
811 | fprintf(stderrstderr, "%-15s Test . Only for debugging purposes. See source code\n", "-T"); |
812 | #endif |
813 | fprintf(stderrstderr, "%-20s CRL Types (default is SEC_CRL_TYPE):\n", " "); |
814 | fprintf(stderrstderr, "%-20s \t 0 - SEC_KRL_TYPE\n", " "); |
815 | fprintf(stderrstderr, "%-20s \t 1 - SEC_CRL_TYPE\n", " "); |
816 | fprintf(stderrstderr, "\n%-20s Bypass CA certificate checks.\n", "-B"); |
817 | fprintf(stderrstderr, "\n%-20s Partial decode for faster operation.\n", "-p"); |
818 | fprintf(stderrstderr, "%-20s Repeat the operation.\n", "-r <iterations>"); |
819 | fprintf(stderrstderr, "\n%-15s Create CRL\n", "-G"); |
820 | fprintf(stderrstderr, "%-15s Modify CRL\n", "-M"); |
821 | fprintf(stderrstderr, "%-20s Specify crl initialization file\n", |
822 | "-c crl-conf-file"); |
823 | fprintf(stderrstderr, "%-20s Specify the nickname of the CA certificate\n", |
824 | "-n nickname"); |
825 | fprintf(stderrstderr, "%-20s Specify the file which contains the CRL to import\n", |
826 | "-i crl"); |
827 | fprintf(stderrstderr, "%-20s Specify a CRL output file\n", |
828 | "-o crl-output-file"); |
829 | fprintf(stderrstderr, "%-20s Specify to use base64 encoded CRL output format\n", |
830 | "-a"); |
831 | fprintf(stderrstderr, "%-20s Key database directory (default is ~/.netscape)\n", |
832 | "-d keydir"); |
833 | fprintf(stderrstderr, "%-20s Provide path to a default pwd file\n", |
834 | "-f pwd-file"); |
835 | fprintf(stderrstderr, "%-20s Provide db password in command line\n", |
836 | "-w pwd-string"); |
837 | fprintf(stderrstderr, "%-20s Cert & Key database prefix (default is \"\")\n", |
838 | "-P dbprefix"); |
839 | fprintf(stderrstderr, "%-20s Specify the url.\n", "-u url"); |
840 | fprintf(stderrstderr, "\n%-20s Bypass CA certificate checks.\n", "-B"); |
841 | |
842 | exit(-1); |
843 | } |
844 | |
845 | int |
846 | main(int argc, char **argv) |
847 | { |
848 | CERTCertDBHandle *certHandle; |
849 | PRFileDesc *inFile; |
850 | PRFileDesc *inCrlInitFile = NULL((void*)0); |
851 | int generateCRL; |
852 | int modifyCRL; |
853 | int listCRL; |
854 | int importCRL; |
855 | int showFileCRL; |
856 | int deleteCRL; |
857 | int rv; |
858 | char *nickName; |
859 | char *url; |
860 | char *dbPrefix = PORT_StrdupPORT_Strdup_Util(""); |
861 | char *alg = NULL((void*)0); |
862 | char *outFile = NULL((void*)0); |
863 | char *slotName = NULL((void*)0); |
864 | int ascii = 0; |
865 | int crlType; |
866 | PLOptState *optstate; |
867 | PLOptStatus status; |
868 | SECStatus secstatus; |
869 | PRInt32 decodeOptions = CRL_DECODE_DEFAULT_OPTIONS0x00000000; |
870 | PRInt32 importOptions = CRL_IMPORT_DEFAULT_OPTIONS0x00000000; |
871 | PRBool quiet = PR_FALSE0; |
872 | PRBool test = PR_FALSE0; |
873 | PRBool erase = PR_FALSE0; |
874 | PRInt32 i = 0; |
875 | PRInt32 iterations = 1; |
876 | PRBool readonly = PR_FALSE0; |
877 | |
878 | secuPWData pwdata = { PW_NONE, 0 }; |
879 | |
880 | progName = strrchr(argv[0], '/'); |
881 | progName = progName ? progName + 1 : argv[0]; |
882 | |
883 | rv = 0; |
884 | deleteCRL = importCRL = listCRL = generateCRL = modifyCRL = showFileCRL = 0; |
885 | inFile = NULL((void*)0); |
886 | nickName = url = NULL((void*)0); |
887 | certHandle = NULL((void*)0); |
888 | crlType = SEC_CRL_TYPE1; |
889 | /* |
890 | * Parse command line arguments |
891 | */ |
892 | optstate = PL_CreateOptState(argc, argv, "sqBCDGILMSTEP:f:d:i:h:n:p:t:u:r:aZ:o:c:"); |
893 | while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { |
Although the value stored to 'status' is used in the enclosing expression, the value is never actually read from 'status' | |
894 | switch (optstate->option) { |
895 | case '?': |
896 | Usage(); |
897 | break; |
898 | |
899 | case 'T': |
900 | test = PR_TRUE1; |
901 | break; |
902 | |
903 | case 'E': |
904 | erase = PR_TRUE1; |
905 | break; |
906 | |
907 | case 'B': |
908 | importOptions |= CRL_IMPORT_BYPASS_CHECKS0x00000001; |
909 | break; |
910 | |
911 | case 'G': |
912 | generateCRL = 1; |
913 | break; |
914 | |
915 | case 'M': |
916 | modifyCRL = 1; |
917 | break; |
918 | |
919 | case 'D': |
920 | deleteCRL = 1; |
921 | break; |
922 | |
923 | case 'I': |
924 | importCRL = 1; |
925 | break; |
926 | |
927 | case 'S': |
928 | showFileCRL = 1; |
929 | break; |
930 | |
931 | case 'C': |
932 | case 'L': |
933 | listCRL = 1; |
934 | break; |
935 | |
936 | case 'P': |
937 | PORT_FreePORT_Free_Util(dbPrefix); |
938 | dbPrefix = PORT_StrdupPORT_Strdup_Util(optstate->value); |
939 | break; |
940 | |
941 | case 'Z': |
942 | alg = PORT_StrdupPORT_Strdup_Util(optstate->value); |
943 | break; |
944 | |
945 | case 'a': |
946 | ascii = 1; |
947 | break; |
948 | |
949 | case 'c': |
950 | inCrlInitFile = PR_Open(optstate->value, PR_RDONLY0x01, 0); |
951 | if (!inCrlInitFile) { |
952 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "%s: unable to open \"%s\" for reading\n", |
953 | progName, optstate->value); |
954 | rv = SECFailure; |
955 | goto loser; |
956 | } |
957 | break; |
958 | |
959 | case 'd': |
960 | SECU_ConfigDirectory(optstate->value); |
961 | break; |
962 | |
963 | case 'f': |
964 | pwdata.source = PW_FROMFILE; |
965 | pwdata.data = PORT_StrdupPORT_Strdup_Util(optstate->value); |
966 | break; |
967 | |
968 | case 'h': |
969 | slotName = PORT_StrdupPORT_Strdup_Util(optstate->value); |
970 | break; |
971 | |
972 | case 'i': |
973 | inFile = PR_Open(optstate->value, PR_RDONLY0x01, 0); |
974 | if (!inFile) { |
975 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "%s: unable to open \"%s\" for reading\n", |
976 | progName, optstate->value); |
977 | rv = SECFailure; |
978 | goto loser; |
979 | } |
980 | break; |
981 | |
982 | case 'n': |
983 | nickName = PORT_StrdupPORT_Strdup_Util(optstate->value); |
984 | break; |
985 | |
986 | case 'o': |
987 | outFile = PORT_StrdupPORT_Strdup_Util(optstate->value); |
988 | break; |
989 | |
990 | case 'p': |
991 | decodeOptions |= CRL_DECODE_SKIP_ENTRIES0x00000002; |
992 | break; |
993 | |
994 | case 'r': { |
995 | const char *str = optstate->value; |
996 | if (str && atoi(str) > 0) |
997 | iterations = atoi(str); |
998 | } break; |
999 | |
1000 | case 't': { |
1001 | crlType = atoi(optstate->value); |
1002 | if (crlType != SEC_CRL_TYPE1 && crlType != SEC_KRL_TYPE0) { |
1003 | PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "%s: invalid crl type\n", progName); |
1004 | rv = SECFailure; |
1005 | goto loser; |
1006 | } |
1007 | break; |
1008 | |
1009 | case 'q': |
1010 | quiet = PR_TRUE1; |
1011 | break; |
1012 | |
1013 | case 'w': |
1014 | pwdata.source = PW_PLAINTEXT; |
1015 | pwdata.data = PORT_StrdupPORT_Strdup_Util(optstate->value); |
1016 | break; |
1017 | |
1018 | case 'u': |
1019 | url = PORT_StrdupPORT_Strdup_Util(optstate->value); |
1020 | break; |
1021 | } |
1022 | } |
1023 | } |
1024 | |
1025 | if (deleteCRL && !nickName) |
1026 | Usage(); |
1027 | if (importCRL && !inFile) |
1028 | Usage(); |
1029 | if (showFileCRL && !inFile) |
1030 | Usage(); |
1031 | if ((generateCRL && !nickName) || |
1032 | (modifyCRL && !inFile && !nickName)) |
1033 | Usage(); |
1034 | if (!(listCRL || deleteCRL || importCRL || showFileCRL || generateCRL || |
1035 | modifyCRL || test || erase)) |
1036 | Usage(); |
1037 | |
1038 | if (listCRL || showFileCRL) { |
1039 | readonly = PR_TRUE1; |
1040 | } |
1041 | |
1042 | PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); |
1043 | |
1044 | PK11_SetPasswordFunc(SECU_GetModulePassword); |
1045 | |
1046 | if (showFileCRL) { |
1047 | rv = NSS_NoDB_Init(NULL((void*)0)); |
1048 | if (rv != SECSuccess) { |
1049 | goto loser; |
1050 | } |
1051 | } else { |
1052 | secstatus = NSS_Initialize(SECU_ConfigDirectory(NULL((void*)0)), dbPrefix, dbPrefix, |
1053 | "secmod.db", readonly ? NSS_INIT_READONLY0x1 : 0); |
1054 | if (secstatus != SECSuccess) { |
1055 | SECU_PrintPRandOSError(progName); |
1056 | rv = SECFailure; |
1057 | goto loser; |
1058 | } |
1059 | } |
1060 | |
1061 | SECU_RegisterDynamicOids(); |
1062 | |
1063 | certHandle = CERT_GetDefaultCertDB(); |
1064 | if (certHandle == NULL((void*)0)) { |
1065 | SECU_PrintError(progName, "unable to open the cert db"); |
1066 | rv = SECFailure; |
1067 | goto loser; |
1068 | } |
1069 | |
1070 | CRLGEN_InitCrlGenParserLock(); |
1071 | |
1072 | for (i = 0; i < iterations; i++) { |
1073 | /* Read in the private key info */ |
1074 | if (deleteCRL) |
1075 | DeleteCRL(certHandle, nickName, crlType); |
1076 | else if (listCRL) { |
1077 | rv = ListCRL(certHandle, nickName, crlType); |
1078 | } else if (importCRL) { |
1079 | rv = ImportCRL(certHandle, url, crlType, inFile, importOptions, |
1080 | decodeOptions, &pwdata); |
1081 | } else if (showFileCRL) { |
1082 | rv = DumpCRL(inFile); |
1083 | } else if (generateCRL || modifyCRL) { |
1084 | if (!inCrlInitFile) |
1085 | inCrlInitFile = PR_STDINPR_GetSpecialFD(PR_StandardInput); |
1086 | rv = GenerateCRL(certHandle, nickName, inCrlInitFile, |
1087 | inFile, outFile, ascii, slotName, |
1088 | importOptions, alg, quiet, |
1089 | decodeOptions, url, &pwdata, |
1090 | modifyCRL); |
1091 | } else if (erase) { |
1092 | /* list and delete all CRLs */ |
1093 | ListCRLNames(certHandle, crlType, PR_TRUE1); |
1094 | } |
1095 | #ifdef DEBUG1 |
1096 | else if (test) { |
1097 | /* list and delete all CRLs */ |
1098 | ListCRLNames(certHandle, crlType, PR_TRUE1); |
1099 | /* list CRLs */ |
1100 | ListCRLNames(certHandle, crlType, PR_FALSE0); |
1101 | /* import CRL as a blob */ |
1102 | rv = ImportCRL(certHandle, url, crlType, inFile, importOptions, |
1103 | decodeOptions, &pwdata); |
1104 | /* list CRLs */ |
1105 | ListCRLNames(certHandle, crlType, PR_FALSE0); |
1106 | } |
1107 | #endif |
1108 | } |
1109 | |
1110 | CRLGEN_DestroyCrlGenParserLock(); |
1111 | |
1112 | loser: |
1113 | PL_DestroyOptState(optstate); |
1114 | |
1115 | if (inFile) { |
1116 | PR_Close(inFile); |
1117 | } |
1118 | if (alg) { |
1119 | PORT_FreePORT_Free_Util(alg); |
1120 | } |
1121 | if (slotName) { |
1122 | PORT_FreePORT_Free_Util(slotName); |
1123 | } |
1124 | if (nickName) { |
1125 | PORT_FreePORT_Free_Util(nickName); |
1126 | } |
1127 | if (outFile) { |
1128 | PORT_FreePORT_Free_Util(outFile); |
1129 | } |
1130 | if (url) { |
1131 | PORT_FreePORT_Free_Util(url); |
1132 | } |
1133 | if (pwdata.data) { |
1134 | PORT_FreePORT_Free_Util(pwdata.data); |
1135 | } |
1136 | |
1137 | PORT_FreePORT_Free_Util(dbPrefix); |
1138 | |
1139 | if (NSS_Shutdown() != SECSuccess) { |
1140 | rv = SECFailure; |
1141 | } |
1142 | |
1143 | return (rv != SECSuccess); |
1144 | } |