1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
40 ** utility for managing certificates and the cert database
55 #define SEC_CERT_DB_EXISTS 0
56 #define SEC_CREATE_CERT_DB 1
58 static char *progName
;
60 static CERTSignedCrl
*FindCRL
61 (CERTCertDBHandle
*certHandle
, char *name
, int type
)
63 CERTSignedCrl
*crl
= NULL
;
64 CERTCertificate
*cert
= NULL
;
70 cert
= CERT_FindCertByNicknameOrEmailAddr(certHandle
, name
);
72 CERTName
*certName
= NULL
;
73 PRArenaPool
*arena
= NULL
;
75 certName
= CERT_AsciiToName(name
);
77 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
80 SEC_ASN1EncodeItem (arena
, NULL
, (void *)certName
,
81 SEC_ASN1_GET(CERT_NameTemplate
));
83 SECITEM_CopyItem(NULL
, &derName
, nameItem
);
85 PORT_FreeArena(arena
, PR_FALSE
);
87 CERT_DestroyName(certName
);
90 if (!derName
.len
|| !derName
.data
) {
91 SECU_PrintError(progName
, "could not find certificate named '%s'", name
);
92 return ((CERTSignedCrl
*)NULL
);
95 SECITEM_CopyItem(NULL
, &derName
, &cert
->derSubject
);
96 CERT_DestroyCertificate (cert
);
99 crl
= SEC_FindCrlByName(certHandle
, &derName
, type
);
102 (progName
, "could not find %s's CRL", name
);
104 SECITEM_FreeItem(&derName
, PR_FALSE
);
109 static SECStatus
DisplayCRL (CERTCertDBHandle
*certHandle
, char *nickName
, int crlType
)
111 CERTSignedCrl
*crl
= NULL
;
113 crl
= FindCRL (certHandle
, nickName
, crlType
);
116 SECU_PrintCRLInfo (stdout
, &crl
->crl
, "CRL Info:\n", 0);
117 SEC_DestroyCrl (crl
);
123 static void ListCRLNames (CERTCertDBHandle
*certHandle
, int crlType
, PRBool deletecrls
)
125 CERTCrlHeadNode
*crlList
= NULL
;
126 CERTCrlNode
*crlNode
= NULL
;
127 CERTName
*name
= NULL
;
128 PRArenaPool
*arena
= NULL
;
132 arena
= PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE
);
134 fprintf(stderr
, "%s: fail to allocate memory\n", progName
);
138 name
= PORT_ArenaZAlloc (arena
, sizeof(*name
));
140 fprintf(stderr
, "%s: fail to allocate memory\n", progName
);
145 rv
= SEC_LookupCrls (certHandle
, &crlList
, crlType
);
146 if (rv
!= SECSuccess
) {
147 fprintf(stderr
, "%s: fail to look up CRLs (%s)\n", progName
,
148 SECU_Strerror(PORT_GetError()));
156 crlNode
= crlList
->first
;
158 fprintf (stdout
, "\n");
159 fprintf (stdout
, "\n%-40s %-5s\n\n", "CRL names", "CRL Type");
161 char* asciiname
= NULL
;
162 CERTCertificate
*cert
= NULL
;
163 if (crlNode
->crl
&& &crlNode
->crl
->crl
.derName
) {
164 cert
= CERT_FindCertByName(certHandle
,
165 &crlNode
->crl
->crl
.derName
);
167 SECU_PrintError(progName
, "could not find signing "
168 "certificate in database");
172 char* certName
= NULL
;
173 if (cert
->nickname
&& PORT_Strlen(cert
->nickname
) > 0) {
174 certName
= cert
->nickname
;
175 } else if (cert
->emailAddr
&& PORT_Strlen(cert
->emailAddr
) > 0) {
176 certName
= cert
->emailAddr
;
179 asciiname
= PORT_Strdup(certName
);
181 CERT_DestroyCertificate(cert
);
185 name
= &crlNode
->crl
->crl
.name
;
187 SECU_PrintError(progName
, "fail to get the CRL "
191 asciiname
= CERT_NameToAscii(name
);
193 fprintf (stdout
, "%-40s %-5s\n", asciiname
, "CRL");
195 PORT_Free(asciiname
);
197 if ( PR_TRUE
== deletecrls
) {
198 CERTSignedCrl
* acrl
= NULL
;
199 SECItem
* issuer
= &crlNode
->crl
->crl
.derName
;
200 acrl
= SEC_FindCrlByName(certHandle
, issuer
, crlType
);
203 SEC_DeletePermCRL(acrl
);
204 SEC_DestroyCrl(acrl
);
207 crlNode
= crlNode
->next
;
212 PORT_FreeArena (crlList
->arena
, PR_FALSE
);
213 PORT_FreeArena (arena
, PR_FALSE
);
216 static SECStatus
ListCRL (CERTCertDBHandle
*certHandle
, char *nickName
, int crlType
)
218 if (nickName
== NULL
) {
219 ListCRLNames (certHandle
, crlType
, PR_FALSE
);
223 return DisplayCRL (certHandle
, nickName
, crlType
);
228 static SECStatus
DeleteCRL (CERTCertDBHandle
*certHandle
, char *name
, int type
)
230 CERTSignedCrl
*crl
= NULL
;
231 SECStatus rv
= SECFailure
;
233 crl
= FindCRL (certHandle
, name
, type
);
236 (progName
, "could not find the issuer %s's CRL", name
);
239 rv
= SEC_DeletePermCRL (crl
);
241 if (rv
!= SECSuccess
) {
242 SECU_PrintError(progName
, "fail to delete the issuer %s's CRL "
243 "from the perm database (reason: %s)",
244 name
, SECU_Strerror(PORT_GetError()));
250 SECStatus
ImportCRL (CERTCertDBHandle
*certHandle
, char *url
, int type
,
251 PRFileDesc
*inFile
, PRInt32 importOptions
, PRInt32 decodeOptions
)
253 CERTSignedCrl
*crl
= NULL
;
255 PK11SlotInfo
* slot
= NULL
;
257 #if defined(DEBUG_jpierre)
258 PRIntervalTime starttime
, endtime
, elapsed
;
259 PRUint32 mins
, secs
, msecs
;
265 /* Read in the entire file specified with the -f argument */
266 rv
= SECU_ReadDERFromFile(&crlDER
, inFile
, PR_FALSE
);
267 if (rv
!= SECSuccess
) {
268 SECU_PrintError(progName
, "unable to read input file");
272 decodeOptions
|= CRL_DECODE_DONT_COPY_DER
;
274 slot
= PK11_GetInternalKeySlot();
276 #if defined(DEBUG_jpierre)
277 starttime
= PR_IntervalNow();
279 crl
= PK11_ImportCRL(slot
, &crlDER
, url
, type
,
280 NULL
, importOptions
, NULL
, decodeOptions
);
281 #if defined(DEBUG_jpierre)
282 endtime
= PR_IntervalNow();
283 elapsed
= endtime
- starttime
;
284 mins
= PR_IntervalToSeconds(elapsed
) / 60;
285 secs
= PR_IntervalToSeconds(elapsed
) % 60;
286 msecs
= PR_IntervalToMilliseconds(elapsed
) % 1000;
287 printf("Elapsed : %2d:%2d.%3d\n", mins
, secs
, msecs
);
290 const char *errString
;
293 errString
= SECU_Strerror(PORT_GetError());
294 if ( errString
&& PORT_Strlen (errString
) == 0)
295 SECU_PrintError (progName
,
296 "CRL is not imported (error: input CRL is not up to date.)");
298 SECU_PrintError (progName
, "unable to import CRL");
300 SEC_DestroyCrl (crl
);
309 static CERTCertificate
*
310 FindSigningCert(CERTCertDBHandle
*certHandle
, CERTSignedCrl
*signCrl
,
313 CERTCertificate
*cert
= NULL
, *certTemp
= NULL
;
314 SECStatus rv
= SECFailure
;
315 CERTAuthKeyID
* authorityKeyID
= NULL
;
316 SECItem
* subject
= NULL
;
318 PORT_Assert(certHandle
!= NULL
);
319 if (!certHandle
|| (!signCrl
&& !certNickName
)) {
320 SECU_PrintError(progName
, "invalid args for function "
321 "FindSigningCert \n");
327 authorityKeyID
= SECU_FindCRLAuthKeyIDExten(tmpArena
, scrl
);
329 subject
= &signCrl
->crl
.derName
;
331 certTemp
= CERT_FindCertByNickname(certHandle
, certNickName
);
333 SECU_PrintError(progName
, "could not find certificate \"%s\" "
334 "in database", certNickName
);
337 subject
= &certTemp
->derSubject
;
340 cert
= SECU_FindCrlIssuer(certHandle
, subject
, authorityKeyID
, PR_Now());
342 SECU_PrintError(progName
, "could not find signing certificate "
351 CERT_DestroyCertificate(certTemp
);
352 if (cert
&& rv
!= SECSuccess
)
353 CERT_DestroyCertificate(cert
);
357 static CERTSignedCrl
*
358 CreateModifiedCRLCopy(PRArenaPool
*arena
, CERTCertDBHandle
*certHandle
,
359 CERTCertificate
**cert
, char *certNickName
,
360 PRFileDesc
*inFile
, PRInt32 decodeOptions
,
361 PRInt32 importOptions
)
364 CERTSignedCrl
*signCrl
= NULL
;
365 CERTSignedCrl
*modCrl
= NULL
;
366 PRArenaPool
*modArena
= NULL
;
367 SECStatus rv
= SECSuccess
;
369 PORT_Assert(arena
!= NULL
&& certHandle
!= NULL
&&
370 certNickName
!= NULL
);
371 if (!arena
|| !certHandle
|| !certNickName
) {
372 SECU_PrintError(progName
, "CreateModifiedCRLCopy: invalid args\n");
376 modArena
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
378 SECU_PrintError(progName
, "fail to allocate memory\n");
382 if (inFile
!= NULL
) {
383 rv
= SECU_ReadDERFromFile(&crlDER
, inFile
, PR_FALSE
);
384 if (rv
!= SECSuccess
) {
385 SECU_PrintError(progName
, "unable to read input file");
386 PORT_FreeArena(modArena
, PR_FALSE
);
390 decodeOptions
|= CRL_DECODE_DONT_COPY_DER
;
392 modCrl
= CERT_DecodeDERCrlWithFlags(modArena
, &crlDER
, SEC_CRL_TYPE
,
395 SECU_PrintError(progName
, "fail to decode CRL");
399 if (0 == (importOptions
& CRL_IMPORT_BYPASS_CHECKS
)){
400 /* If caCert is a v2 certificate, make sure that it
401 * can be used for crl signing purpose */
402 *cert
= FindSigningCert(certHandle
, modCrl
, NULL
);
407 rv
= CERT_VerifySignedData(&modCrl
->signatureWrap
, *cert
,
409 if (rv
!= SECSuccess
) {
410 SECU_PrintError(progName
, "fail to verify signed data\n");
415 modCrl
= FindCRL(certHandle
, certNickName
, SEC_CRL_TYPE
);
417 SECU_PrintError(progName
, "fail to find crl %s in database\n",
423 signCrl
= PORT_ArenaZNew(arena
, CERTSignedCrl
);
424 if (signCrl
== NULL
) {
425 SECU_PrintError(progName
, "fail to allocate memory\n");
429 rv
= SECU_CopyCRL(arena
, &signCrl
->crl
, &modCrl
->crl
);
430 if (rv
!= SECSuccess
) {
431 SECU_PrintError(progName
, "unable to dublicate crl for "
436 /* Make sure the update time is current. It can be modified later
437 * by "update <time>" command from crl generation script */
438 rv
= DER_EncodeTimeChoice(arena
, &signCrl
->crl
.lastUpdate
, PR_Now());
439 if (rv
!= SECSuccess
) {
440 SECU_PrintError(progName
, "fail to encode current time\n");
444 signCrl
->arena
= arena
;
447 SECITEM_FreeItem(&crlDER
, PR_FALSE
);
449 SEC_DestroyCrl(modCrl
);
450 if (rv
!= SECSuccess
&& signCrl
) {
451 SEC_DestroyCrl(signCrl
);
458 static CERTSignedCrl
*
459 CreateNewCrl(PRArenaPool
*arena
, CERTCertDBHandle
*certHandle
,
460 CERTCertificate
*cert
)
462 CERTSignedCrl
*signCrl
= NULL
;
467 /* if the CERTSignedCrl structure changes, this function will need to be
469 PORT_Assert(cert
!= NULL
);
470 if (!cert
|| !arena
) {
471 SECU_PrintError(progName
, "invalid args for function "
476 mark
= PORT_ArenaMark(arena
);
478 signCrl
= PORT_ArenaZNew(arena
, CERTSignedCrl
);
479 if (signCrl
== NULL
) {
480 SECU_PrintError(progName
, "fail to allocate memory\n");
484 dummy
= SEC_ASN1EncodeInteger(arena
, &signCrl
->crl
.version
,
486 /* set crl->version */
488 SECU_PrintError(progName
, "fail to create crl version data "
493 /* copy SECItem name from cert */
494 rv
= SECITEM_CopyItem(arena
, &signCrl
->crl
.derName
, &cert
->derSubject
);
495 if (rv
!= SECSuccess
) {
496 SECU_PrintError(progName
, "fail to duplicate der name from "
501 /* copy CERTName name structure from cert issuer */
502 rv
= CERT_CopyName (arena
, &signCrl
->crl
.name
, &cert
->subject
);
503 if (rv
!= SECSuccess
) {
504 SECU_PrintError(progName
, "fail to duplicate RD name from "
509 rv
= DER_EncodeTimeChoice(arena
, &signCrl
->crl
.lastUpdate
, PR_Now());
510 if (rv
!= SECSuccess
) {
511 SECU_PrintError(progName
, "fail to encode current time\n");
516 signCrl
->arena
= arena
;
517 signCrl
->dbhandle
= certHandle
;
518 signCrl
->crl
.arena
= arena
;
523 PORT_ArenaRelease(arena
, mark
);
529 UpdateCrl(CERTSignedCrl
*signCrl
, PRFileDesc
*inCrlInitFile
)
531 CRLGENGeneratorData
*crlGenData
= NULL
;
534 PORT_Assert(signCrl
!= NULL
&& inCrlInitFile
!= NULL
);
535 if (!signCrl
|| !inCrlInitFile
) {
536 SECU_PrintError(progName
, "invalid args for function "
541 crlGenData
= CRLGEN_InitCrlGeneration(signCrl
, inCrlInitFile
);
543 SECU_PrintError(progName
, "can not initialize parser structure.\n");
547 rv
= CRLGEN_ExtHandleInit(crlGenData
);
548 if (rv
== SECFailure
) {
549 SECU_PrintError(progName
, "can not initialize entries handle.\n");
553 rv
= CRLGEN_StartCrlGen(crlGenData
);
554 if (rv
!= SECSuccess
) {
555 SECU_PrintError(progName
, "crl generation failed");
560 /* CommitExtensionsAndEntries is partially responsible for freeing
561 * up memory that was used for CRL generation. Should be called regardless
562 * of previouse call status, but only after initialization of
563 * crlGenData was done. It will commit all changes that was done before
564 * an error has occured.
566 if (SECSuccess
!= CRLGEN_CommitExtensionsAndEntries(crlGenData
)) {
567 SECU_PrintError(progName
, "crl generation failed");
570 CRLGEN_FinalizeCrlGeneration(crlGenData
);
575 SignAndStoreCrl(CERTSignedCrl
*signCrl
, CERTCertificate
*cert
,
576 char *outFileName
, SECOidTag hashAlgTag
, int ascii
,
577 char *slotName
, char *url
, secuPWData
*pwdata
)
579 PK11SlotInfo
*slot
= NULL
;
580 PRFileDesc
*outFile
= NULL
;
582 SignAndEncodeFuncExitStat errCode
;
584 PORT_Assert(signCrl
&& (!ascii
|| outFileName
));
585 if (!signCrl
|| (ascii
&& !outFileName
)) {
586 SECU_PrintError(progName
, "invalid args for function "
587 "SignAndStoreCrl\n");
591 if (!slotName
|| !PL_strcmp(slotName
, "internal"))
592 slot
= PK11_GetInternalKeySlot();
594 slot
= PK11_FindSlotByName(slotName
);
596 SECU_PrintError(progName
, "can not find requested slot");
600 if (PK11_NeedLogin(slot
)) {
601 rv
= PK11_Authenticate(slot
, PR_TRUE
, pwdata
);
602 if (rv
!= SECSuccess
)
606 rv
= SECU_SignAndEncodeCRL(cert
, signCrl
, hashAlgTag
, &errCode
);
607 if (rv
!= SECSuccess
) {
612 errMsg
= "No private key found of signing cert";
615 case noSignatureMatch
:
616 errMsg
= "Key and Algorithm OId are do not match";
621 errMsg
= "Failed to encode crl structure";
625 errMsg
= "Failed to sign crl structure";
629 errMsg
= "Can not allocate memory";
632 SECU_PrintError(progName
, "%s\n", errMsg
);
637 outFile
= PR_Open(outFileName
, PR_WRONLY
|PR_CREATE_FILE
, PR_IRUSR
| PR_IWUSR
);
639 SECU_PrintError(progName
, "unable to open \"%s\" for writing\n",
645 rv
= SECU_StoreCRL(slot
, signCrl
->derCrl
, outFile
, ascii
, url
);
646 if (rv
!= SECSuccess
) {
647 SECU_PrintError(progName
, "fail to save CRL\n");
659 GenerateCRL (CERTCertDBHandle
*certHandle
, char *certNickName
,
660 PRFileDesc
*inCrlInitFile
, PRFileDesc
*inFile
,
661 char *outFileName
, int ascii
, char *slotName
,
662 PRInt32 importOptions
, char *alg
, PRBool quiet
,
663 PRInt32 decodeOptions
, char *url
, secuPWData
*pwdata
,
666 CERTCertificate
*cert
= NULL
;
667 CERTSignedCrl
*signCrl
= NULL
;
668 PRArenaPool
*arena
= NULL
;
670 SECOidTag hashAlgTag
= SEC_OID_UNKNOWN
;
673 hashAlgTag
= SECU_StringToSignatureAlgTag(alg
);
674 if (hashAlgTag
== SEC_OID_UNKNOWN
) {
675 SECU_PrintError(progName
, "%s -Z: %s is not a recognized type.\n",
680 hashAlgTag
= SEC_OID_UNKNOWN
;
683 arena
= PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE
);
685 SECU_PrintError(progName
, "fail to allocate memory\n");
689 if (modifyFlag
== PR_TRUE
) {
690 signCrl
= CreateModifiedCRLCopy(arena
, certHandle
, &cert
, certNickName
,
691 inFile
, decodeOptions
, importOptions
);
692 if (signCrl
== NULL
) {
698 cert
= FindSigningCert(certHandle
, signCrl
, certNickName
);
705 if (modifyFlag
== PR_TRUE
) {
707 int len
= strlen(certNickName
) + 5;
708 outFileName
= PORT_ArenaAlloc(arena
, len
);
709 PR_snprintf(outFileName
, len
, "%s.crl", certNickName
);
711 SECU_PrintError(progName
, "Will try to generate crl. "
712 "It will be saved in file: %s",
715 signCrl
= CreateNewCrl(arena
, certHandle
, cert
);
720 rv
= UpdateCrl(signCrl
, inCrlInitFile
);
721 if (rv
!= SECSuccess
) {
725 rv
= SignAndStoreCrl(signCrl
, cert
, outFileName
, hashAlgTag
, ascii
,
726 slotName
, url
, pwdata
);
727 if (rv
!= SECSuccess
) {
731 if (signCrl
&& !quiet
) {
732 SECU_PrintCRLInfo (stdout
, &signCrl
->crl
, "CRL Info:\n", 0);
736 if (arena
&& (!signCrl
|| !signCrl
->arena
))
737 PORT_FreeArena (arena
, PR_FALSE
);
739 SEC_DestroyCrl (signCrl
);
741 CERT_DestroyCertificate (cert
);
745 static void Usage(char *progName
)
748 "Usage: %s -L [-n nickname] [-d keydir] [-P dbprefix] [-t crlType]\n"
749 " %s -D -n nickname [-d keydir] [-P dbprefix]\n"
750 " %s -I -i crl -t crlType [-u url] [-d keydir] [-P dbprefix] [-B] "
751 "[-p pwd-file] -w [pwd-string]\n"
752 " %s -E -t crlType [-d keydir] [-P dbprefix]\n"
754 " %s -G|-M -c crl-init-file -n nickname [-i crl] [-u url] "
755 "[-d keydir] [-P dbprefix] [-Z alg] ] [-p pwd-file] -w [pwd-string] "
757 progName
, progName
, progName
, progName
, progName
, progName
);
759 fprintf (stderr
, "%-15s List CRL\n", "-L");
760 fprintf(stderr
, "%-20s Specify the nickname of the CA certificate\n",
762 fprintf(stderr
, "%-20s Key database directory (default is ~/.netscape)\n",
764 fprintf(stderr
, "%-20s Cert & Key database prefix (default is \"\")\n",
767 fprintf (stderr
, "%-15s Delete a CRL from the cert database\n", "-D");
768 fprintf(stderr
, "%-20s Specify the nickname for the CA certificate\n",
770 fprintf(stderr
, "%-20s Specify the crl type.\n", "-t crlType");
771 fprintf(stderr
, "%-20s Key database directory (default is ~/.netscape)\n",
773 fprintf(stderr
, "%-20s Cert & Key database prefix (default is \"\")\n",
776 fprintf (stderr
, "%-15s Erase all CRLs of specified type from hte cert database\n", "-E");
777 fprintf(stderr
, "%-20s Specify the crl type.\n", "-t crlType");
778 fprintf(stderr
, "%-20s Key database directory (default is ~/.netscape)\n",
780 fprintf(stderr
, "%-20s Cert & Key database prefix (default is \"\")\n",
783 fprintf (stderr
, "%-15s Import a CRL to the cert database\n", "-I");
784 fprintf(stderr
, "%-20s Specify the file which contains the CRL to import\n",
786 fprintf(stderr
, "%-20s Specify the url.\n", "-u url");
787 fprintf(stderr
, "%-20s Specify the crl type.\n", "-t crlType");
788 fprintf(stderr
, "%-20s Key database directory (default is ~/.netscape)\n",
790 fprintf(stderr
, "%-20s Cert & Key database prefix (default is \"\")\n",
793 fprintf (stderr
, "%-15s Test . Only for debugging purposes. See source code\n", "-T");
795 fprintf(stderr
, "%-20s CRL Types (default is SEC_CRL_TYPE):\n", " ");
796 fprintf(stderr
, "%-20s \t 0 - SEC_KRL_TYPE\n", " ");
797 fprintf(stderr
, "%-20s \t 1 - SEC_CRL_TYPE\n", " ");
798 fprintf(stderr
, "\n%-20s Bypass CA certificate checks.\n", "-B");
799 fprintf(stderr
, "\n%-20s Partial decode for faster operation.\n", "-p");
800 fprintf(stderr
, "%-20s Repeat the operation.\n", "-r <iterations>");
801 fprintf(stderr
, "\n%-15s Create CRL\n", "-G");
802 fprintf(stderr
, "%-15s Modify CRL\n", "-M");
803 fprintf(stderr
, "%-20s Specify crl initialization file\n",
805 fprintf(stderr
, "%-20s Specify the nickname of the CA certificate\n",
807 fprintf(stderr
, "%-20s Specify the file which contains the CRL to import\n",
809 fprintf(stderr
, "%-20s Specify a CRL output file\n",
810 "-o crl-output-file");
811 fprintf(stderr
, "%-20s Specify to use base64 encoded CRL output format\n",
813 fprintf(stderr
, "%-20s Key database directory (default is ~/.netscape)\n",
815 fprintf(stderr
, "%-20s Provide path to a default pwd file\n",
817 fprintf(stderr
, "%-20s Provide db password in command line\n",
819 fprintf(stderr
, "%-20s Cert & Key database prefix (default is \"\")\n",
821 fprintf(stderr
, "%-20s Specify the url.\n", "-u url");
822 fprintf(stderr
, "\n%-20s Bypass CA certificate checks.\n", "-B");
827 int main(int argc
, char **argv
)
830 CERTCertDBHandle
*certHandle
;
833 PRFileDesc
*inCrlInitFile
= NULL
;
844 char *outFile
= NULL
;
845 char *slotName
= NULL
;
848 PLOptState
*optstate
;
851 PRInt32 decodeOptions
= CRL_DECODE_DEFAULT_OPTIONS
;
852 PRInt32 importOptions
= CRL_IMPORT_DEFAULT_OPTIONS
;
853 PRBool quiet
= PR_FALSE
;
854 PRBool test
= PR_FALSE
;
855 PRBool erase
= PR_FALSE
;
857 PRInt32 iterations
= 1;
858 PRBool readonly
= PR_FALSE
;
860 secuPWData pwdata
= { PW_NONE
, 0 };
862 progName
= strrchr(argv
[0], '/');
863 progName
= progName
? progName
+1 : argv
[0];
866 deleteCRL
= importCRL
= listCRL
= generateCRL
= modifyCRL
= 0;
869 nickName
= url
= NULL
;
870 privKeyDER
.data
= NULL
;
872 crlType
= SEC_CRL_TYPE
;
874 * Parse command line arguments
876 optstate
= PL_CreateOptState(argc
, argv
, "sqBCDGILMTEP:f:d:i:h:n:p:t:u:r:aZ:o:c:");
877 while ((status
= PL_GetNextOpt(optstate
)) == PL_OPT_OK
) {
878 switch (optstate
->option
) {
892 importOptions
|= CRL_IMPORT_BYPASS_CHECKS
;
917 dbPrefix
= strdup(optstate
->value
);
921 alg
= strdup(optstate
->value
);
929 inCrlInitFile
= PR_Open(optstate
->value
, PR_RDONLY
, 0);
930 if (!inCrlInitFile
) {
931 PR_fprintf(PR_STDERR
, "%s: unable to open \"%s\" for reading\n",
932 progName
, optstate
->value
);
933 PL_DestroyOptState(optstate
);
939 SECU_ConfigDirectory(optstate
->value
);
943 pwdata
.source
= PW_FROMFILE
;
944 pwdata
.data
= strdup(optstate
->value
);
948 slotName
= strdup(optstate
->value
);
952 inFile
= PR_Open(optstate
->value
, PR_RDONLY
, 0);
954 PR_fprintf(PR_STDERR
, "%s: unable to open \"%s\" for reading\n",
955 progName
, optstate
->value
);
956 PL_DestroyOptState(optstate
);
962 nickName
= strdup(optstate
->value
);
966 outFile
= strdup(optstate
->value
);
970 decodeOptions
|= CRL_DECODE_SKIP_ENTRIES
;
974 const char* str
= optstate
->value
;
975 if (str
&& atoi(str
)>0)
976 iterations
= atoi(str
);
983 type
= strdup(optstate
->value
);
984 crlType
= atoi (type
);
985 if (crlType
!= SEC_CRL_TYPE
&& crlType
!= SEC_KRL_TYPE
) {
986 PR_fprintf(PR_STDERR
, "%s: invalid crl type\n", progName
);
987 PL_DestroyOptState(optstate
);
997 pwdata
.source
= PW_PLAINTEXT
;
998 pwdata
.data
= strdup(optstate
->value
);
1002 url
= strdup(optstate
->value
);
1008 PL_DestroyOptState(optstate
);
1010 if (deleteCRL
&& !nickName
) Usage (progName
);
1011 if (importCRL
&& !inFile
) Usage (progName
);
1012 if ((generateCRL
&& !nickName
) ||
1013 (modifyCRL
&& !inFile
&& !nickName
)) Usage (progName
);
1014 if (!(listCRL
|| deleteCRL
|| importCRL
|| generateCRL
||
1015 modifyCRL
|| test
|| erase
)) Usage (progName
);
1021 PR_Init( PR_SYSTEM_THREAD
, PR_PRIORITY_NORMAL
, 1);
1023 PK11_SetPasswordFunc(SECU_GetModulePassword
);
1025 secstatus
= NSS_Initialize(SECU_ConfigDirectory(NULL
), dbPrefix
, dbPrefix
,
1026 "secmod.db", readonly
? NSS_INIT_READONLY
: 0);
1027 if (secstatus
!= SECSuccess
) {
1028 SECU_PrintPRandOSError(progName
);
1031 SECU_RegisterDynamicOids();
1033 certHandle
= CERT_GetDefaultCertDB();
1034 if (certHandle
== NULL
) {
1035 SECU_PrintError(progName
, "unable to open the cert db");
1036 /*ignoring return value of NSS_Shutdown() as code returns -1*/
1037 (void) NSS_Shutdown();
1041 CRLGEN_InitCrlGenParserLock();
1043 for (i
=0; i
<iterations
; i
++) {
1044 /* Read in the private key info */
1046 DeleteCRL (certHandle
, nickName
, crlType
);
1048 rv
= ListCRL (certHandle
, nickName
, crlType
);
1050 else if (importCRL
) {
1051 rv
= ImportCRL (certHandle
, url
, crlType
, inFile
, importOptions
,
1053 } else if (generateCRL
|| modifyCRL
) {
1055 inCrlInitFile
= PR_STDIN
;
1056 rv
= GenerateCRL (certHandle
, nickName
, inCrlInitFile
,
1057 inFile
, outFile
, ascii
, slotName
,
1058 importOptions
, alg
, quiet
,
1059 decodeOptions
, url
, &pwdata
,
1063 /* list and delete all CRLs */
1064 ListCRLNames (certHandle
, crlType
, PR_TRUE
);
1068 /* list and delete all CRLs */
1069 ListCRLNames (certHandle
, crlType
, PR_TRUE
);
1071 ListCRLNames (certHandle
, crlType
, PR_FALSE
);
1072 /* import CRL as a blob */
1073 rv
= ImportCRL (certHandle
, url
, crlType
, inFile
, importOptions
,
1076 ListCRLNames (certHandle
, crlType
, PR_FALSE
);
1081 CRLGEN_DestroyCrlGenParserLock();
1083 if (NSS_Shutdown() != SECSuccess
) {
1087 return (rv
!= SECSuccess
);