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 revocation lists generation
59 /* these reroutines were taken from secitem.c, which is supposed to
60 * replace this file some day */
62 * This is the hash function. We simply XOR the encoded form with
63 * itself in sizeof(PLHashNumber)-byte chunks. Improving this
64 * routine is left as an excercise for the more mathematically
67 PLHashNumber PR_CALLBACK
68 SECITEM_Hash ( const void *key
)
70 const SECItem
*item
= (const SECItem
*)key
;
73 PRUint8
*data
= (PRUint8
*)item
->data
;
75 PRUint8
*rvc
= (PRUint8
*)&rv
;
77 for( i
= 0; i
< item
->len
; i
++ ) {
78 rvc
[ i
% sizeof(rv
) ] ^= *data
;
86 * This is the key-compare function. It simply does a lexical
87 * comparison on the item data. This does not result in
88 * quite the same ordering as the "sequence of numbers" order,
89 * but heck it's only used internally by the hash table anyway.
92 SECITEM_HashCompare ( const void *k1
, const void *k2
)
94 const SECItem
*i1
= (const SECItem
*)k1
;
95 const SECItem
*i2
= (const SECItem
*)k2
;
97 return SECITEM_ItemsAreEqual(i1
,i2
);
100 /* Destroys extHandle and data. data was create on heap.
101 * extHandle creaded by CERT_StartCRLEntryExtensions. entry
102 * was allocated on arena.*/
104 destroyEntryData(CRLGENEntryData
*data
)
108 PORT_Assert(data
->entry
);
110 CERT_FinishExtensions(data
->extHandle
);
115 /* Prints error messages along with line number */
117 crlgen_PrintError(int line
, char *msg
, ...)
123 fprintf(stderr
, "crlgen: (line: %d) ", line
);
124 vfprintf(stderr
, msg
, args
);
128 /* Finds CRLGENEntryData in hashtable according PRUint64 value
129 * - certId : cert serial number*/
130 static CRLGENEntryData
*
131 crlgen_FindEntry(CRLGENGeneratorData
*crlGenData
, SECItem
*certId
)
133 if (!crlGenData
->entryDataHashTable
|| !certId
)
135 return (CRLGENEntryData
*)
136 PL_HashTableLookup(crlGenData
->entryDataHashTable
,
141 /* Removes CRLGENEntryData from hashtable according to certId
142 * - certId : cert serial number*/
144 crlgen_RmEntry(CRLGENGeneratorData
*crlGenData
, SECItem
*certId
)
146 CRLGENEntryData
*data
= NULL
;
148 if (!crlGenData
->entryDataHashTable
)
150 data
= crlgen_FindEntry(crlGenData
, certId
);
153 if (PL_HashTableRemove(crlGenData
->entryDataHashTable
, certId
))
155 destroyEntryData(data
);
160 /* Stores CRLGENEntryData in hashtable according to certId
161 * - certId : cert serial number*/
162 static CRLGENEntryData
*
163 crlgen_PlaceAnEntry(CRLGENGeneratorData
*crlGenData
,
164 CERTCrlEntry
*entry
, SECItem
*certId
)
166 CRLGENEntryData
*newData
= NULL
;
168 PORT_Assert(crlGenData
&& crlGenData
->entryDataHashTable
&&
170 if (!crlGenData
|| !crlGenData
->entryDataHashTable
|| !entry
) {
171 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
175 newData
= PORT_ZNew(CRLGENEntryData
);
179 newData
->entry
= entry
;
180 newData
->certId
= certId
;
181 if (!PL_HashTableAdd(crlGenData
->entryDataHashTable
,
182 newData
->certId
, newData
)) {
183 crlgen_PrintError(crlGenData
->parsedLineNum
,
184 "Can not add entryData structure\n");
190 /* Use this structure to keep pointer when commiting entries extensions */
193 CERTCrlEntry
**entries
;
196 /* HT PL_HashTableEnumerateEntries callback. Sorts hashtable entries of the
197 * table he. Returns value through arg parameter*/
198 static PRIntn PR_CALLBACK
199 crlgen_CommitEntryData(PLHashEntry
*he
, PRIntn i
, void *arg
)
201 CRLGENEntryData
*data
= NULL
;
205 return HT_ENUMERATE_NEXT
;
207 data
= (CRLGENEntryData
*)he
->value
;
213 struct commitData
*dt
= (struct commitData
*)arg
;
214 dt
->entries
[dt
->pos
++] = data
->entry
;
215 destroyEntryData(data
);
217 return HT_ENUMERATE_NEXT
;
222 /* Copy char * datainto allocated in arena SECItem */
224 crlgen_SetString(PRArenaPool
*arena
, const char *dataIn
, SECItem
*value
)
228 PORT_Assert(arena
&& dataIn
);
229 if (!arena
|| !dataIn
) {
230 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
234 item
.data
= (void*)dataIn
;
235 item
.len
= PORT_Strlen(dataIn
);
237 return SECITEM_CopyItem(arena
, value
, &item
);
240 /* Creates CERTGeneralName from parsed data for the Authority Key Extension */
241 static CERTGeneralName
*
242 crlgen_GetGeneralName (PRArenaPool
*arena
, CRLGENGeneratorData
*crlGenData
,
245 CERTGeneralName
*namesList
= NULL
;
246 CERTGeneralName
*current
;
247 CERTGeneralName
*tail
= NULL
;
248 SECStatus rv
= SECSuccess
;
249 const char *nextChunk
= NULL
;
250 const char *currData
= NULL
;
259 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
263 mark
= PORT_ArenaMark (arena
);
270 const char *sepPrt
= NULL
;
271 nextChunk
= PORT_Strchr(currData
, '|');
273 nextChunk
= data
+ strlen(data
);
274 sepPrt
= PORT_Strchr(currData
, ':');
275 if (sepPrt
== NULL
|| sepPrt
>= nextChunk
) {
279 PORT_Memcpy(buffer
, sepPrt
+ 1,
280 (nextChunk
- sepPrt
- 1));
281 buffer
[nextChunk
- sepPrt
- 1] = '\0';
283 nameLen
= PR_MIN(sepPrt
- currData
, sizeof(name
) - 1 );
284 PORT_Memcpy(name
, currData
, nameLen
);
285 name
[nameLen
] = '\0';
286 currData
= nextChunk
+ 1;
288 if (!PORT_Strcmp(name
, "otherName"))
289 intValue
= certOtherName
;
290 else if (!PORT_Strcmp(name
, "rfc822Name"))
291 intValue
= certRFC822Name
;
292 else if (!PORT_Strcmp(name
, "dnsName"))
293 intValue
= certDNSName
;
294 else if (!PORT_Strcmp(name
, "x400Address"))
295 intValue
= certX400Address
;
296 else if (!PORT_Strcmp(name
, "directoryName"))
297 intValue
= certDirectoryName
;
298 else if (!PORT_Strcmp(name
, "ediPartyName"))
299 intValue
= certEDIPartyName
;
300 else if (!PORT_Strcmp(name
, "URI"))
302 else if (!PORT_Strcmp(name
, "ipAddress"))
303 intValue
= certIPAddress
;
304 else if (!PORT_Strcmp(name
, "registerID"))
305 intValue
= certRegisterID
;
308 if (intValue
>= certOtherName
&& intValue
<= certRegisterID
) {
309 if (namesList
== NULL
) {
310 namesList
= current
= tail
= PORT_ArenaZNew(arena
,
313 current
= PORT_ArenaZNew(arena
, CERTGeneralName
);
315 if (current
== NULL
) {
320 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
323 current
->type
= intValue
;
324 switch (current
->type
) {
328 current
->name
.other
.data
= PORT_ArenaAlloc (arena
, strlen (buffer
));
329 if (current
->name
.other
.data
== NULL
) {
333 PORT_Memcpy(current
->name
.other
.data
, buffer
,
334 current
->name
.other
.len
= strlen(buffer
));
337 case certEDIPartyName
:
341 case certX400Address
: {
343 current
->name
.other
.data
= PORT_ArenaAlloc (arena
, strlen (buffer
) + 2);
344 if (current
->name
.other
.data
== NULL
) {
349 PORT_Memcpy (current
->name
.other
.data
+ 2, buffer
, strlen (buffer
));
350 /* This may not be accurate for all cases.For now, use this tag type */
351 current
->name
.other
.data
[0] = (char)(((current
->type
- 1) & 0x1f)| 0x80);
352 current
->name
.other
.data
[1] = (char)strlen (buffer
);
353 current
->name
.other
.len
= strlen (buffer
) + 2;
357 case certDirectoryName
: {
358 CERTName
*directoryName
= NULL
;
360 directoryName
= CERT_AsciiToName (buffer
);
361 if (!directoryName
) {
366 rv
= CERT_CopyName (arena
, ¤t
->name
.directoryName
, directoryName
);
367 CERT_DestroyName (directoryName
);
372 if (rv
!= SECSuccess
)
374 current
->l
.next
= &(namesList
->l
);
375 current
->l
.prev
= &(tail
->l
);
376 tail
->l
.next
= &(current
->l
);
379 } while(nextChunk
!= data
+ strlen(data
));
381 if (rv
!= SECSuccess
) {
382 PORT_ArenaRelease (arena
, mark
);
388 /* Creates CERTGeneralName from parsed data for the Authority Key Extension */
389 static CERTGeneralName
*
390 crlgen_DistinguishedName (PRArenaPool
*arena
, CRLGENGeneratorData
*crlGenData
,
393 CERTName
*directoryName
= NULL
;
394 CERTGeneralName
*current
;
395 SECStatus rv
= SECFailure
;
402 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
406 mark
= PORT_ArenaMark (arena
);
408 current
= PORT_ArenaZNew(arena
, CERTGeneralName
);
409 if (current
== NULL
) {
412 current
->type
= certDirectoryName
;
413 current
->l
.next
= ¤t
->l
;
414 current
->l
.prev
= ¤t
->l
;
416 directoryName
= CERT_AsciiToName ((char*)data
);
417 if (!directoryName
) {
421 rv
= CERT_CopyName (arena
, ¤t
->name
.directoryName
, directoryName
);
422 CERT_DestroyName (directoryName
);
425 if (rv
!= SECSuccess
) {
427 PORT_ArenaRelease (arena
, mark
);
434 /* Adding Authority Key ID extension to extension handle. */
436 crlgen_AddAuthKeyID (CRLGENGeneratorData
*crlGenData
,
437 const char **dataArr
)
439 void *extHandle
= NULL
;
440 CERTAuthKeyID
*authKeyID
= NULL
;
441 PRArenaPool
*arena
= NULL
;
442 SECStatus rv
= SECSuccess
;
444 PORT_Assert(dataArr
&& crlGenData
);
445 if (!crlGenData
|| !dataArr
) {
449 extHandle
= crlGenData
->crlExtHandle
;
451 if (!dataArr
[0] || !dataArr
[1] || !dataArr
[2]) {
452 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
453 crlgen_PrintError(crlGenData
->parsedLineNum
,
454 "insufficient number of parameters.\n");
458 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
463 authKeyID
= PORT_ArenaZNew(arena
, CERTAuthKeyID
);
464 if (authKeyID
== NULL
) {
469 if (dataArr
[3] == NULL
) {
470 rv
= crlgen_SetString (arena
, dataArr
[2], &authKeyID
->keyID
);
471 if (rv
!= SECSuccess
)
474 rv
= crlgen_SetString (arena
, dataArr
[3],
475 &authKeyID
->authCertSerialNumber
);
476 if (rv
!= SECSuccess
)
479 authKeyID
->authCertIssuer
=
480 crlgen_DistinguishedName (arena
, crlGenData
, dataArr
[2]);
481 if (authKeyID
->authCertIssuer
== NULL
&& SECFailure
== PORT_GetError ()){
482 crlgen_PrintError(crlGenData
->parsedLineNum
, "syntax error.\n");
489 SECU_EncodeAndAddExtensionValue(arena
, extHandle
, authKeyID
,
490 (*dataArr
[1] == '1') ? PR_TRUE
: PR_FALSE
,
491 SEC_OID_X509_AUTH_KEY_ID
,
492 (EXTEN_EXT_VALUE_ENCODER
) CERT_EncodeAuthKeyID
);
495 PORT_FreeArena (arena
, PR_FALSE
);
499 /* Creates and add Subject Alternative Names extension */
501 crlgen_AddIssuerAltNames(CRLGENGeneratorData
*crlGenData
,
502 const char **dataArr
)
504 CERTGeneralName
*nameList
= NULL
;
505 PRArenaPool
*arena
= NULL
;
506 void *extHandle
= NULL
;
507 SECStatus rv
= SECSuccess
;
510 PORT_Assert(dataArr
&& crlGenData
);
511 if (!crlGenData
|| !dataArr
) {
515 if (!dataArr
|| !dataArr
[0] || !dataArr
[1] || !dataArr
[2]) {
516 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
517 crlgen_PrintError(crlGenData
->parsedLineNum
,
518 "insufficient number of arguments.\n");
522 PORT_Assert(dataArr
&& crlGenData
);
523 if (!crlGenData
|| !dataArr
) {
527 extHandle
= crlGenData
->crlExtHandle
;
529 if (!dataArr
[0] || !dataArr
[1] || !dataArr
[2]) {
530 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
531 crlgen_PrintError(crlGenData
->parsedLineNum
,
532 "insufficient number of parameters.\n");
536 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
541 nameList
= crlgen_GetGeneralName(arena
, crlGenData
, dataArr
[2]);
542 if (nameList
== NULL
) {
543 crlgen_PrintError(crlGenData
->parsedLineNum
, "syntax error.\n");
549 SECU_EncodeAndAddExtensionValue(arena
, extHandle
, nameList
,
550 (*dataArr
[1] == '1') ? PR_TRUE
: PR_FALSE
,
551 SEC_OID_X509_ISSUER_ALT_NAME
,
552 (EXTEN_EXT_VALUE_ENCODER
)CERT_EncodeAltNameExtension
);
555 PORT_FreeArena (arena
, PR_FALSE
);
559 /* Creates and adds CRLNumber extension to extension handle.
560 * Since, this is CRL extension, extension handle is the one
561 * related to CRL extensions */
563 crlgen_AddCrlNumber(CRLGENGeneratorData
*crlGenData
, const char **dataArr
)
565 PRArenaPool
*arena
= NULL
;
567 void *extHandle
= crlGenData
->crlExtHandle
;
569 SECStatus rv
= SECFailure
;
572 PORT_Assert(dataArr
&& crlGenData
);
573 if (!crlGenData
|| !dataArr
) {
577 if (!dataArr
[0] || !dataArr
[1] || !dataArr
[2]) {
578 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
579 crlgen_PrintError(crlGenData
->parsedLineNum
,
580 "insufficient number of arguments.\n");
584 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
589 code
= atoi(dataArr
[2]);
590 if (code
== 0 && *dataArr
[2] != '0') {
591 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
595 dummy
= SEC_ASN1EncodeInteger(arena
, &encodedItem
, code
);
601 rv
= CERT_AddExtension (extHandle
, SEC_OID_X509_CRL_NUMBER
, &encodedItem
,
602 (*dataArr
[1] == '1') ? PR_TRUE
: PR_FALSE
,
607 PORT_FreeArena(arena
, PR_FALSE
);
613 /* Creates Cert Revocation Reason code extension. Encodes it and
614 * returns as SECItem structure */
616 crlgen_CreateReasonCode(PRArenaPool
*arena
, const char **dataArr
,
619 SECItem
*encodedItem
;
624 PORT_Assert(arena
&& dataArr
);
625 if (!arena
|| !dataArr
) {
629 mark
= PORT_ArenaMark(arena
);
631 encodedItem
= PORT_ArenaZNew (arena
, SECItem
);
632 if (encodedItem
== NULL
) {
636 if (dataArr
[2] == NULL
) {
637 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
641 code
= atoi(dataArr
[2]);
642 /* aACompromise(10) is the last possible of the values
643 * for the Reason Core Extension */
644 if ((code
== 0 && *dataArr
[2] != '0') || code
> 10) {
646 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
650 dummy
= SEC_ASN1EncodeInteger(arena
, encodedItem
, code
);
655 *extCode
= SEC_OID_X509_REASON_CODE
;
659 PORT_ArenaRelease (arena
, mark
);
663 /* Creates Cert Invalidity Date extension. Encodes it and
664 * returns as SECItem structure */
666 crlgen_CreateInvalidityDate(PRArenaPool
*arena
, const char **dataArr
,
669 SECItem
*encodedItem
;
673 PORT_Assert(arena
&& dataArr
);
674 if (!arena
|| !dataArr
) {
678 mark
= PORT_ArenaMark(arena
);
680 encodedItem
= PORT_ArenaZNew(arena
, SECItem
);
681 if (encodedItem
== NULL
) {
685 length
= PORT_Strlen(dataArr
[2]);
687 encodedItem
->type
= siGeneralizedTime
;
688 encodedItem
->data
= PORT_ArenaAlloc(arena
, length
);
689 if (!encodedItem
->data
) {
693 PORT_Memcpy(encodedItem
->data
, dataArr
[2], (encodedItem
->len
= length
) *
696 *extCode
= SEC_OID_X509_INVALID_DATE
;
700 PORT_ArenaRelease(arena
, mark
);
704 /* Creates(by calling extCreator function) and adds extension to a set
705 * of already added certs. Uses values of rangeFrom and rangeTo from
706 * CRLGENCrlGenCtl structure for identifying the inclusive set of certs */
708 crlgen_AddEntryExtension(CRLGENGeneratorData
*crlGenData
,
709 const char **dataArr
, char *extName
,
710 SECItem
* (*extCreator
)(PRArenaPool
*arena
,
711 const char **dataArr
,
715 SECStatus rv
= SECFailure
;
719 PRArenaPool
*arena
= NULL
;
722 PORT_Assert(crlGenData
&& dataArr
);
723 if (!crlGenData
|| !dataArr
) {
727 if (!dataArr
[0] || !dataArr
[1]) {
728 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
729 crlgen_PrintError(crlGenData
->parsedLineNum
,
730 "insufficient number of arguments.\n");
733 lastRange
= crlGenData
->rangeTo
- crlGenData
->rangeFrom
+ 1;
735 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
740 ext
= extCreator(arena
, dataArr
, &extCode
);
742 crlgen_PrintError(crlGenData
->parsedLineNum
,
743 "got error while creating extension: %s\n",
748 for (i
= 0;i
< lastRange
;i
++) {
749 CRLGENEntryData
* extData
= NULL
;
750 void *extHandle
= NULL
;
751 SECItem
* certIdItem
=
752 SEC_ASN1EncodeInteger(arena
, NULL
,
753 crlGenData
->rangeFrom
+ i
);
759 extData
= crlgen_FindEntry(crlGenData
, certIdItem
);
761 crlgen_PrintError(crlGenData
->parsedLineNum
,
762 "can not add extension: crl entry "
763 "(serial number: %d) is not in the list yet.\n",
764 crlGenData
->rangeFrom
+ i
);
768 extHandle
= extData
->extHandle
;
769 if (extHandle
== NULL
) {
770 extHandle
= extData
->extHandle
=
771 CERT_StartCRLEntryExtensions(&crlGenData
->signCrl
->crl
,
772 (CERTCrlEntry
*)extData
->entry
);
774 rv
= CERT_AddExtension (extHandle
, extCode
, ext
,
775 (*dataArr
[1] == '1') ? PR_TRUE
: PR_FALSE
,
777 if (rv
== SECFailure
) {
784 PORT_FreeArena(arena
, PR_FALSE
);
789 /* Commits all added entries and their's extensions into CRL. */
791 CRLGEN_CommitExtensionsAndEntries(CRLGENGeneratorData
*crlGenData
)
796 SECStatus rv
= SECSuccess
;
799 PORT_Assert(crlGenData
&& crlGenData
->signCrl
&& crlGenData
->signCrl
->arena
);
800 if (!crlGenData
|| !crlGenData
->signCrl
|| !crlGenData
->signCrl
->arena
) {
801 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
805 arena
= crlGenData
->signCrl
->arena
;
806 crl
= &crlGenData
->signCrl
->crl
;
808 mark
= PORT_ArenaMark(arena
);
810 if (crlGenData
->crlExtHandle
)
811 CERT_FinishExtensions(crlGenData
->crlExtHandle
);
813 size
= crlGenData
->entryDataHashTable
->nentries
;
816 crl
->entries
= PORT_ArenaZNewArray(arena
, CERTCrlEntry
*, size
+ 1);
820 struct commitData dt
;
821 dt
.entries
= crl
->entries
;
823 PL_HashTableEnumerateEntries(crlGenData
->entryDataHashTable
,
824 &crlgen_CommitEntryData
, &dt
);
825 /* Last should be NULL */
826 crl
->entries
[size
] = NULL
;
830 if (rv
!= SECSuccess
)
831 PORT_ArenaRelease(arena
, mark
);
835 /* Initializes extHandle with data from extensions array */
837 crlgen_InitExtensionHandle(void *extHandle
,
838 CERTCertExtension
**extensions
)
840 CERTCertExtension
*extension
= NULL
;
845 PORT_Assert(extHandle
!= NULL
);
850 extension
= *extensions
;
852 SECOidTag oidTag
= SECOID_FindOIDTag (&extension
->id
);
853 /* shell we skip unknown extensions? */
854 CERT_AddExtension (extHandle
, oidTag
, &extension
->value
,
855 (extension
->critical
.len
!= 0) ? PR_TRUE
: PR_FALSE
,
857 extension
= *(++extensions
);
862 /* Used for initialization of extension handles for crl and certs
863 * extensions from existing CRL data then modifying existing CRL.*/
865 CRLGEN_ExtHandleInit(CRLGENGeneratorData
*crlGenData
)
870 PORT_Assert(crlGenData
&& crlGenData
->signCrl
&&
871 crlGenData
->entryDataHashTable
);
872 if (!crlGenData
|| !crlGenData
->signCrl
||
873 !crlGenData
->entryDataHashTable
) {
874 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
878 crl
= &crlGenData
->signCrl
->crl
;
879 crlGenData
->crlExtHandle
= CERT_StartCRLExtensions(crl
);
880 crlgen_InitExtensionHandle(crlGenData
->crlExtHandle
,
882 crl
->extensions
= NULL
;
885 CERTCrlEntry
**entry
= crl
->entries
;
887 PRUint64 sn
= DER_GetInteger(&(*entry
)->serialNumber
);
888 CRLGENEntryData
*extData
=
889 crlgen_PlaceAnEntry(crlGenData
, *entry
, &(*entry
)->serialNumber
);
890 if ((*entry
)->extensions
) {
892 CERT_StartCRLEntryExtensions(&crlGenData
->signCrl
->crl
,
893 (CERTCrlEntry
*)extData
->entry
);
894 if (crlgen_InitExtensionHandle(extData
->extHandle
,
895 (*entry
)->extensions
) == SECFailure
)
898 (*entry
)->extensions
= NULL
;
900 maxSN
= PR_MAX(maxSN
, sn
);
904 crlGenData
->rangeFrom
= crlGenData
->rangeTo
= maxSN
+ 1;
908 /*****************************************************************************
909 * Parser trigger functions start here
912 /* Sets new internal range value for add/rm certs.*/
914 crlgen_SetNewRangeField(CRLGENGeneratorData
*crlGenData
, char *value
)
916 long rangeFrom
= 0, rangeTo
= 0;
917 char *dashPos
= NULL
;
919 PORT_Assert(crlGenData
);
921 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
926 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
927 crlgen_PrintError(crlGenData
->parsedLineNum
,
928 "insufficient number of arguments.\n");
932 if ((dashPos
= strchr(value
, '-')) != NULL
) {
933 char *rangeToS
, *rangeFromS
= value
;
935 rangeFrom
= atoi(rangeFromS
);
938 rangeToS
= (char*)(dashPos
+ 1);
939 rangeTo
= atol(rangeToS
);
941 rangeFrom
= atol(value
);
945 if (rangeFrom
< 1 || rangeTo
<rangeFrom
) {
946 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
947 crlgen_PrintError(crlGenData
->parsedLineNum
,
948 "bad cert id range: %s.\n", value
);
952 crlGenData
->rangeFrom
= rangeFrom
;
953 crlGenData
->rangeTo
= rangeTo
;
958 /* Changes issuer subject field in CRL. By default this data is taken from
959 * issuer cert subject field.Not yet implemented */
961 crlgen_SetIssuerField(CRLGENGeneratorData
*crlGenData
, char *value
)
963 crlgen_PrintError(crlGenData
->parsedLineNum
,
964 "Can not change CRL issuer field.\n");
968 /* Encode and sets CRL thisUpdate and nextUpdate time fields*/
970 crlgen_SetTimeField(CRLGENGeneratorData
*crlGenData
, char *value
,
971 PRBool setThisUpdate
)
973 CERTSignedCrl
*signCrl
;
977 SECItem
*timeDest
= NULL
;
979 PORT_Assert(crlGenData
&& crlGenData
->signCrl
&&
980 crlGenData
->signCrl
->arena
);
981 if (!crlGenData
|| !crlGenData
->signCrl
|| !crlGenData
->signCrl
->arena
) {
982 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
986 signCrl
= crlGenData
->signCrl
;
987 arena
= signCrl
->arena
;
991 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
992 crlgen_PrintError(crlGenData
->parsedLineNum
,
993 "insufficient number of arguments.\n");
996 length
= PORT_Strlen(value
);
998 if (setThisUpdate
== PR_TRUE
) {
999 timeDest
= &crl
->lastUpdate
;
1001 timeDest
= &crl
->nextUpdate
;
1004 timeDest
->type
= siGeneralizedTime
;
1005 timeDest
->data
= PORT_ArenaAlloc(arena
, length
);
1006 if (!timeDest
->data
) {
1009 PORT_Memcpy(timeDest
->data
, value
, length
);
1010 timeDest
->len
= length
;
1016 /* Adds new extension into CRL or added cert handles */
1018 crlgen_AddExtension(CRLGENGeneratorData
*crlGenData
, const char **extData
)
1020 PORT_Assert(crlGenData
&& crlGenData
->crlExtHandle
);
1021 if (!crlGenData
|| !crlGenData
->crlExtHandle
) {
1022 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1026 if (extData
== NULL
|| *extData
== NULL
) {
1027 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1028 crlgen_PrintError(crlGenData
->parsedLineNum
,
1029 "insufficient number of arguments.\n");
1032 if (!PORT_Strcmp(*extData
, "authKeyId"))
1033 return crlgen_AddAuthKeyID(crlGenData
, extData
);
1034 else if (!PORT_Strcmp(*extData
, "issuerAltNames"))
1035 return crlgen_AddIssuerAltNames(crlGenData
, extData
);
1036 else if (!PORT_Strcmp(*extData
, "crlNumber"))
1037 return crlgen_AddCrlNumber(crlGenData
, extData
);
1038 else if (!PORT_Strcmp(*extData
, "reasonCode"))
1039 return crlgen_AddEntryExtension(crlGenData
, extData
, "reasonCode",
1040 crlgen_CreateReasonCode
);
1041 else if (!PORT_Strcmp(*extData
, "invalidityDate"))
1042 return crlgen_AddEntryExtension(crlGenData
, extData
, "invalidityDate",
1043 crlgen_CreateInvalidityDate
);
1045 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1046 crlgen_PrintError(crlGenData
->parsedLineNum
,
1047 "insufficient number of arguments.\n");
1054 /* Created CRLGENEntryData for cert with serial number certId and
1055 * adds it to entryDataHashTable. certId can be a single cert serial
1056 * number or an inclusive rage of certs */
1058 crlgen_AddCert(CRLGENGeneratorData
*crlGenData
,
1059 char *certId
, char *revocationDate
)
1061 CERTSignedCrl
*signCrl
;
1062 SECItem
*certIdItem
;
1064 PRUint64 rangeFrom
= 0, rangeTo
= 0, i
= 0;
1065 int timeValLength
= -1;
1066 SECStatus rv
= SECFailure
;
1070 PORT_Assert(crlGenData
&& crlGenData
->signCrl
&&
1071 crlGenData
->signCrl
->arena
);
1072 if (!crlGenData
|| !crlGenData
->signCrl
|| !crlGenData
->signCrl
->arena
) {
1073 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1077 signCrl
= crlGenData
->signCrl
;
1078 arena
= signCrl
->arena
;
1080 if (!certId
|| !revocationDate
) {
1081 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1082 crlgen_PrintError(crlGenData
->parsedLineNum
,
1083 "insufficient number of arguments.\n");
1087 timeValLength
= strlen(revocationDate
);
1089 if (crlgen_SetNewRangeField(crlGenData
, certId
) == SECFailure
&&
1093 rangeFrom
= crlGenData
->rangeFrom
;
1094 rangeTo
= crlGenData
->rangeTo
;
1096 for (i
= 0;i
< rangeTo
- rangeFrom
+ 1;i
++) {
1097 CERTCrlEntry
*entry
;
1098 mark
= PORT_ArenaMark(arena
);
1099 entry
= PORT_ArenaZNew(arena
, CERTCrlEntry
);
1100 if (entry
== NULL
) {
1104 certIdItem
= SEC_ASN1EncodeInteger(arena
, &entry
->serialNumber
,
1110 if (crlgen_FindEntry(crlGenData
, certIdItem
)) {
1111 crlgen_PrintError(crlGenData
->parsedLineNum
,
1112 "entry already exists. Use \"range\" "
1113 "and \"rmcert\" before adding a new one with the "
1114 "same serial number %ld\n", rangeFrom
+ i
);
1118 entry
->serialNumber
.type
= siBuffer
;
1120 entry
->revocationDate
.type
= siGeneralizedTime
;
1122 entry
->revocationDate
.data
=
1123 PORT_ArenaAlloc(arena
, timeValLength
);
1124 if (entry
->revocationDate
.data
== NULL
) {
1128 PORT_Memcpy(entry
->revocationDate
.data
, revocationDate
,
1129 timeValLength
* sizeof(char));
1130 entry
->revocationDate
.len
= timeValLength
;
1133 entry
->extensions
= NULL
;
1134 if (!crlgen_PlaceAnEntry(crlGenData
, entry
, certIdItem
)) {
1143 PORT_ArenaRelease(arena
, mark
);
1149 /* Removes certs from entryDataHashTable which have certId serial number.
1150 * certId can have value of a range of certs */
1152 crlgen_RmCert(CRLGENGeneratorData
*crlGenData
, char *certId
)
1157 PORT_Assert(crlGenData
&& certId
);
1158 if (!crlGenData
|| !certId
) {
1159 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1163 arena
= crlGenData
->signCrl
->arena
;
1165 if (crlgen_SetNewRangeField(crlGenData
, certId
) == SECFailure
&&
1170 for (i
= 0;i
< crlGenData
->rangeTo
- crlGenData
->rangeFrom
+ 1;i
++) {
1171 SECItem
* certIdItem
= SEC_ASN1EncodeInteger(NULL
, NULL
,
1172 crlGenData
->rangeFrom
+ i
);
1174 CRLGENEntryData
*extData
=
1175 crlgen_FindEntry(crlGenData
, certIdItem
);
1177 printf("Cert with id %s is not in the list\n", certId
);
1179 crlgen_RmEntry(crlGenData
, certIdItem
);
1181 SECITEM_FreeItem(certIdItem
, PR_TRUE
);
1188 /*************************************************************************
1189 * Lex Parser Helper functions are used to store parsed information
1190 * in context related structures. Context(or state) is identified base on
1191 * a type of a instruction parser currently is going through. New context
1192 * is identified by first token in a line. It can be addcert context,
1193 * addext context, etc. */
1195 /* Updates CRL field depending on current context */
1197 crlgen_updateCrlFn_field(CRLGENGeneratorData
*crlGenData
, void *str
)
1199 CRLGENCrlField
*fieldStr
= (CRLGENCrlField
*)str
;
1201 PORT_Assert(crlGenData
);
1203 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1207 switch(crlGenData
->contextId
) {
1208 case CRLGEN_ISSUER_CONTEXT
:
1209 crlgen_SetIssuerField(crlGenData
, fieldStr
->value
);
1211 case CRLGEN_UPDATE_CONTEXT
:
1212 return crlgen_SetTimeField(crlGenData
, fieldStr
->value
, PR_TRUE
);
1214 case CRLGEN_NEXT_UPDATE_CONTEXT
:
1215 return crlgen_SetTimeField(crlGenData
, fieldStr
->value
, PR_FALSE
);
1217 case CRLGEN_CHANGE_RANGE_CONTEXT
:
1218 return crlgen_SetNewRangeField(crlGenData
, fieldStr
->value
);
1221 crlgen_PrintError(crlGenData
->parsedLineNum
,
1222 "syntax error (unknow token type: %d)\n",
1223 crlGenData
->contextId
);
1224 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1230 /* Sets parsed data for CRL field update into temporary structure */
1232 crlgen_setNextDataFn_field(CRLGENGeneratorData
*crlGenData
, void *str
,
1233 void *data
, unsigned short dtype
)
1235 CRLGENCrlField
*fieldStr
= (CRLGENCrlField
*)str
;
1237 PORT_Assert(crlGenData
);
1239 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1243 switch (crlGenData
->contextId
) {
1244 case CRLGEN_CHANGE_RANGE_CONTEXT
:
1245 if (dtype
!= CRLGEN_TYPE_DIGIT
|| dtype
!= CRLGEN_TYPE_DIGIT_RANGE
) {
1246 crlgen_PrintError(crlGenData
->parsedLineNum
,
1247 "range value should have "
1248 "numeric or numeric range values.\n");
1252 case CRLGEN_NEXT_UPDATE_CONTEXT
:
1253 case CRLGEN_UPDATE_CONTEXT
:
1254 if (dtype
!= CRLGEN_TYPE_ZDATE
){
1255 crlgen_PrintError(crlGenData
->parsedLineNum
,
1256 "bad formated date. Should be "
1257 "YYYYMMDDHHMMSSZ.\n");
1262 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1263 crlgen_PrintError(crlGenData
->parsedLineNum
,
1264 "syntax error (unknow token type: %d).\n",
1265 crlGenData
->contextId
, data
);
1268 fieldStr
->value
= PORT_Strdup(data
);
1269 if (!fieldStr
->value
) {
1275 /* Triggers cert entries update depending on current context */
1277 crlgen_updateCrlFn_cert(CRLGENGeneratorData
*crlGenData
, void *str
)
1279 CRLGENCertEntry
*certStr
= (CRLGENCertEntry
*)str
;
1281 PORT_Assert(crlGenData
);
1283 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1287 switch(crlGenData
->contextId
) {
1288 case CRLGEN_ADD_CERT_CONTEXT
:
1289 return crlgen_AddCert(crlGenData
, certStr
->certId
,
1290 certStr
->revocationTime
);
1291 case CRLGEN_RM_CERT_CONTEXT
:
1292 return crlgen_RmCert(crlGenData
, certStr
->certId
);
1294 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1295 crlgen_PrintError(crlGenData
->parsedLineNum
,
1296 "syntax error (unknow token type: %d).\n",
1297 crlGenData
->contextId
);
1303 /* Sets parsed data for CRL entries update into temporary structure */
1305 crlgen_setNextDataFn_cert(CRLGENGeneratorData
*crlGenData
, void *str
,
1306 void *data
, unsigned short dtype
)
1308 CRLGENCertEntry
*certStr
= (CRLGENCertEntry
*)str
;
1310 PORT_Assert(crlGenData
);
1312 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1317 case CRLGEN_TYPE_DIGIT
:
1318 case CRLGEN_TYPE_DIGIT_RANGE
:
1319 certStr
->certId
= PORT_Strdup(data
);
1320 if (!certStr
->certId
) {
1324 case CRLGEN_TYPE_DATE
:
1325 case CRLGEN_TYPE_ZDATE
:
1326 certStr
->revocationTime
= PORT_Strdup(data
);
1327 if (!certStr
->revocationTime
) {
1332 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1333 crlgen_PrintError(crlGenData
->parsedLineNum
,
1334 "syntax error (unknow token type: %d).\n",
1335 crlGenData
->contextId
);
1341 /* Triggers cert entries/crl extension update */
1343 crlgen_updateCrlFn_extension(CRLGENGeneratorData
*crlGenData
, void *str
)
1345 CRLGENExtensionEntry
*extStr
= (CRLGENExtensionEntry
*)str
;
1347 return crlgen_AddExtension(crlGenData
, (const char**)extStr
->extData
);
1350 /* Defines maximum number of fields extension may have */
1351 #define MAX_EXT_DATA_LENGTH 10
1353 /* Sets parsed extension data for CRL entries/CRL extensions update
1354 * into temporary structure */
1356 crlgen_setNextDataFn_extension(CRLGENGeneratorData
*crlGenData
, void *str
,
1357 void *data
, unsigned short dtype
)
1359 CRLGENExtensionEntry
*extStr
= (CRLGENExtensionEntry
*)str
;
1361 PORT_Assert(crlGenData
);
1363 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1367 if (extStr
->extData
== NULL
) {
1368 extStr
->extData
= PORT_ZNewArray(char *, MAX_EXT_DATA_LENGTH
);
1369 if (!extStr
->extData
) {
1373 if (extStr
->nextUpdatedData
>= MAX_EXT_DATA_LENGTH
) {
1374 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1375 crlgen_PrintError(crlGenData
->parsedLineNum
,
1376 "number of fields in extension "
1377 "exceeded maximum allowed data length: %d.\n",
1378 MAX_EXT_DATA_LENGTH
);
1381 extStr
->extData
[extStr
->nextUpdatedData
] = PORT_Strdup(data
);
1382 if (!extStr
->extData
[extStr
->nextUpdatedData
]) {
1385 extStr
->nextUpdatedData
+= 1;
1391 /****************************************************************************************
1392 * Top level functions are triggered directly by parser.
1396 * crl generation script parser recreates a temporary data staructure
1397 * for each line it is going through. This function cleans temp structure.
1400 crlgen_destroyTempData(CRLGENGeneratorData
*crlGenData
)
1402 if (crlGenData
->contextId
!= CRLGEN_UNKNOWN_CONTEXT
) {
1403 switch(crlGenData
->contextId
) {
1404 case CRLGEN_ISSUER_CONTEXT
:
1405 case CRLGEN_UPDATE_CONTEXT
:
1406 case CRLGEN_NEXT_UPDATE_CONTEXT
:
1407 case CRLGEN_CHANGE_RANGE_CONTEXT
:
1408 if (crlGenData
->crlField
->value
)
1409 PORT_Free(crlGenData
->crlField
->value
);
1410 PORT_Free(crlGenData
->crlField
);
1412 case CRLGEN_ADD_CERT_CONTEXT
:
1413 case CRLGEN_RM_CERT_CONTEXT
:
1414 if (crlGenData
->certEntry
->certId
)
1415 PORT_Free(crlGenData
->certEntry
->certId
);
1416 if (crlGenData
->certEntry
->revocationTime
)
1417 PORT_Free(crlGenData
->certEntry
->revocationTime
);
1418 PORT_Free(crlGenData
->certEntry
);
1420 case CRLGEN_ADD_EXTENSION_CONTEXT
:
1421 if (crlGenData
->extensionEntry
->extData
) {
1423 for (;i
< crlGenData
->extensionEntry
->nextUpdatedData
;i
++)
1424 PORT_Free(*(crlGenData
->extensionEntry
->extData
+ i
));
1425 PORT_Free(crlGenData
->extensionEntry
->extData
);
1427 PORT_Free(crlGenData
->extensionEntry
);
1430 crlGenData
->contextId
= CRLGEN_UNKNOWN_CONTEXT
;
1435 crlgen_updateCrl(CRLGENGeneratorData
*crlGenData
)
1437 SECStatus rv
= SECSuccess
;
1439 PORT_Assert(crlGenData
);
1441 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1445 switch(crlGenData
->contextId
) {
1446 case CRLGEN_ISSUER_CONTEXT
:
1447 case CRLGEN_UPDATE_CONTEXT
:
1448 case CRLGEN_NEXT_UPDATE_CONTEXT
:
1449 case CRLGEN_CHANGE_RANGE_CONTEXT
:
1450 rv
= crlGenData
->crlField
->updateCrlFn(crlGenData
, crlGenData
->crlField
);
1452 case CRLGEN_RM_CERT_CONTEXT
:
1453 case CRLGEN_ADD_CERT_CONTEXT
:
1454 rv
= crlGenData
->certEntry
->updateCrlFn(crlGenData
, crlGenData
->certEntry
);
1456 case CRLGEN_ADD_EXTENSION_CONTEXT
:
1457 rv
= crlGenData
->extensionEntry
->
1458 updateCrlFn(crlGenData
, crlGenData
->extensionEntry
);
1460 case CRLGEN_UNKNOWN_CONTEXT
:
1463 crlgen_PrintError(crlGenData
->parsedLineNum
,
1464 "unknown lang context type code: %d.\n",
1465 crlGenData
->contextId
);
1469 /* Clrean structures after crl update */
1470 crlgen_destroyTempData(crlGenData
);
1472 crlGenData
->parsedLineNum
+= 1;
1478 crlgen_setNextData(CRLGENGeneratorData
*crlGenData
, void *data
,
1479 unsigned short dtype
)
1481 SECStatus rv
= SECSuccess
;
1483 PORT_Assert(crlGenData
);
1485 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1489 switch(crlGenData
->contextId
) {
1490 case CRLGEN_ISSUER_CONTEXT
:
1491 case CRLGEN_UPDATE_CONTEXT
:
1492 case CRLGEN_NEXT_UPDATE_CONTEXT
:
1493 case CRLGEN_CHANGE_RANGE_CONTEXT
:
1494 rv
= crlGenData
->crlField
->setNextDataFn(crlGenData
, crlGenData
->crlField
,
1497 case CRLGEN_ADD_CERT_CONTEXT
:
1498 case CRLGEN_RM_CERT_CONTEXT
:
1499 rv
= crlGenData
->certEntry
->setNextDataFn(crlGenData
, crlGenData
->certEntry
,
1502 case CRLGEN_ADD_EXTENSION_CONTEXT
:
1504 crlGenData
->extensionEntry
->
1505 setNextDataFn(crlGenData
, crlGenData
->extensionEntry
, data
, dtype
);
1507 case CRLGEN_UNKNOWN_CONTEXT
:
1510 crlgen_PrintError(crlGenData
->parsedLineNum
,
1511 "unknown context type: %d.\n",
1512 crlGenData
->contextId
);
1520 crlgen_createNewLangStruct(CRLGENGeneratorData
*crlGenData
,
1521 unsigned structType
)
1523 PORT_Assert(crlGenData
&&
1524 crlGenData
->contextId
== CRLGEN_UNKNOWN_CONTEXT
);
1526 crlGenData
->contextId
!= CRLGEN_UNKNOWN_CONTEXT
) {
1527 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1531 switch(structType
) {
1532 case CRLGEN_ISSUER_CONTEXT
:
1533 case CRLGEN_UPDATE_CONTEXT
:
1534 case CRLGEN_NEXT_UPDATE_CONTEXT
:
1535 case CRLGEN_CHANGE_RANGE_CONTEXT
:
1536 crlGenData
->crlField
= PORT_New(CRLGENCrlField
);
1537 if (!crlGenData
->crlField
) {
1540 crlGenData
->contextId
= structType
;
1541 crlGenData
->crlField
->value
= NULL
;
1542 crlGenData
->crlField
->updateCrlFn
= &crlgen_updateCrlFn_field
;
1543 crlGenData
->crlField
->setNextDataFn
= &crlgen_setNextDataFn_field
;
1545 case CRLGEN_RM_CERT_CONTEXT
:
1546 case CRLGEN_ADD_CERT_CONTEXT
:
1547 crlGenData
->certEntry
= PORT_New(CRLGENCertEntry
);
1548 if (!crlGenData
->certEntry
) {
1551 crlGenData
->contextId
= structType
;
1552 crlGenData
->certEntry
->certId
= 0;
1553 crlGenData
->certEntry
->revocationTime
= NULL
;
1554 crlGenData
->certEntry
->updateCrlFn
= &crlgen_updateCrlFn_cert
;
1555 crlGenData
->certEntry
->setNextDataFn
= &crlgen_setNextDataFn_cert
;
1557 case CRLGEN_ADD_EXTENSION_CONTEXT
:
1558 crlGenData
->extensionEntry
= PORT_New(CRLGENExtensionEntry
);
1559 if (!crlGenData
->extensionEntry
) {
1562 crlGenData
->contextId
= structType
;
1563 crlGenData
->extensionEntry
->extData
= NULL
;
1564 crlGenData
->extensionEntry
->nextUpdatedData
= 0;
1565 crlGenData
->extensionEntry
->updateCrlFn
=
1566 &crlgen_updateCrlFn_extension
;
1567 crlGenData
->extensionEntry
->setNextDataFn
=
1568 &crlgen_setNextDataFn_extension
;
1570 case CRLGEN_UNKNOWN_CONTEXT
:
1573 crlgen_PrintError(crlGenData
->parsedLineNum
,
1574 "unknown context type: %d.\n", structType
);
1582 /* Parser initialization function */
1583 CRLGENGeneratorData
*
1584 CRLGEN_InitCrlGeneration(CERTSignedCrl
*signCrl
, PRFileDesc
*src
)
1586 CRLGENGeneratorData
*crlGenData
= NULL
;
1588 PORT_Assert(signCrl
&& src
);
1589 if (!signCrl
|| !src
) {
1590 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1594 crlGenData
= PORT_ZNew(CRLGENGeneratorData
);
1599 crlGenData
->entryDataHashTable
=
1600 PL_NewHashTable(0, SECITEM_Hash
, SECITEM_HashCompare
,
1601 PL_CompareValues
, NULL
, NULL
);
1602 if (!crlGenData
->entryDataHashTable
) {
1603 PORT_Free(crlGenData
);
1607 crlGenData
->src
= src
;
1608 crlGenData
->parsedLineNum
= 1;
1609 crlGenData
->contextId
= CRLGEN_UNKNOWN_CONTEXT
;
1610 crlGenData
->signCrl
= signCrl
;
1611 crlGenData
->rangeFrom
= 0;
1612 crlGenData
->rangeTo
= 0;
1613 crlGenData
->crlExtHandle
= NULL
;
1621 CRLGEN_FinalizeCrlGeneration(CRLGENGeneratorData
*crlGenData
)
1625 if (crlGenData
->src
)
1626 PR_Close(crlGenData
->src
);
1627 PL_HashTableDestroy(crlGenData
->entryDataHashTable
);
1628 PORT_Free(crlGenData
);