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 PKIX-C library.
16 * The Initial Developer of the Original Code is
17 * Sun Microsystems, Inc.
18 * Portions created by the Initial Developer are
19 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
22 * Sun Microsystems, Inc.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
40 * CRL Function Definitions
44 #include "pkix_pl_crl.h"
46 extern PKIX_PL_HashTable
*cachedCrlSigTable
;
48 /* --Private-CRL-Functions------------------------------------- */
51 * FUNCTION: pkix_pl_CRL_GetVersion
54 * Retrieves the version of the CRL pointed to by "crl" and stores it at
55 * "pVersion". The version number will either be 0 or 1 (corresponding to
56 * v1 or v2, respectively).
58 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
62 * Address of CRL whose version is to be stored. Must be non-NULL.
64 * Address where a version will be stored. Must be non-NULL.
66 * Platform-specific context pointer.
68 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
70 * Returns NULL if the function succeeds.
71 * Returns a CRL Error if the function fails in a non-fatal way.
72 * Returns a Fatal Error if the function fails in an unrecoverable way.
75 pkix_pl_CRL_GetVersion(
77 PKIX_UInt32
*pVersion
,
80 PKIX_UInt32 myVersion
;
82 PKIX_ENTER(CRL
, "pkix_pl_CRL_GetVersion");
83 PKIX_NULLCHECK_THREE(crl
, crl
->nssSignedCrl
, pVersion
);
85 PKIX_NULLCHECK_ONE(crl
->nssSignedCrl
->crl
.version
.data
);
87 myVersion
= *(crl
->nssSignedCrl
->crl
.version
.data
);
90 PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1ORV2
);
93 *pVersion
= myVersion
;
101 * FUNCTION: PKIX_PL_CRL_GetCRLNumber (see comments in pkix_pl_pki.h)
104 PKIX_PL_CRL_GetCRLNumber(
106 PKIX_PL_BigInt
**pCrlNumber
,
109 PKIX_PL_BigInt
*crlNumber
= NULL
;
110 SECItem nssCrlNumber
;
111 PLArenaPool
*arena
= NULL
;
113 PKIX_UInt32 length
= 0;
116 PKIX_ENTER(CRL
, "PKIX_PL_CRL_GetCRLNumber");
117 PKIX_NULLCHECK_THREE(crl
, crl
->nssSignedCrl
, pCrlNumber
);
119 if (!crl
->crlNumberAbsent
&& crl
->crlNumber
== NULL
) {
121 PKIX_OBJECT_LOCK(crl
);
123 if (!crl
->crlNumberAbsent
&& crl
->crlNumber
== NULL
) {
125 nssCrlNumber
.type
= 0;
126 nssCrlNumber
.len
= 0;
127 nssCrlNumber
.data
= NULL
;
129 PKIX_CRL_DEBUG("\t\tCalling PORT_NewArena).\n");
130 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
132 PKIX_ERROR(PKIX_OUTOFMEMORY
);
135 PKIX_CRL_DEBUG("\t\tCalling CERT_FindCRLNumberExten\n");
136 status
= CERT_FindCRLNumberExten
137 (arena
, &crl
->nssSignedCrl
->crl
, &nssCrlNumber
);
139 if (status
== SECSuccess
) {
140 /* Get data in bytes then convert to bigint */
141 length
= nssCrlNumber
.len
;
142 bytes
= (char *)nssCrlNumber
.data
;
144 PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
145 (bytes
, length
, &crlNumber
, plContext
),
146 PKIX_BIGINTCREATEWITHBYTESFAILED
);
148 /* arena release does the job
149 PKIX_CRL_DEBUG("\t\tCalling SECITEM_FreeItem\n");
150 SECITEM_FreeItem(&nssCrlNumber, PKIX_FALSE);
152 crl
->crlNumber
= crlNumber
;
156 crl
->crlNumberAbsent
= PKIX_TRUE
;
160 PKIX_OBJECT_UNLOCK(crl
);
164 PKIX_INCREF(crl
->crlNumber
);
166 *pCrlNumber
= crl
->crlNumber
;
171 PKIX_CRL_DEBUG("\t\tCalling PORT_FreeArena).\n");
172 PORT_FreeArena(arena
, PR_FALSE
);
179 * FUNCTION: pkix_pl_CRL_GetSignatureAlgId
182 * Retrieves a pointer to the OID that represents the signature algorithm of
183 * the CRL pointed to by "crl" and stores it at "pSignatureAlgId".
185 * AlgorithmIdentifier ::= SEQUENCE {
186 * algorithm OBJECT IDENTIFIER,
187 * parameters ANY DEFINED BY algorithm OPTIONAL }
191 * Address of CRL whose signature algorithm OID is to be stored.
194 * Address where object pointer will be stored. Must be non-NULL.
196 * Platform-specific context pointer.
198 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
200 * Returns NULL if the function succeeds.
201 * Returns a CRL Error if the function fails in a non-fatal way.
202 * Returns a Fatal Error if the function fails in an unrecoverable way.
205 pkix_pl_CRL_GetSignatureAlgId(
207 PKIX_PL_OID
**pSignatureAlgId
,
210 CERTCrl
*nssCrl
= NULL
;
211 PKIX_PL_OID
*signatureAlgId
= NULL
;
212 SECAlgorithmID algorithm
;
214 char *asciiOID
= NULL
;
216 PKIX_ENTER(CRL
, "pkix_pl_CRL_GetSignatureAlgId");
217 PKIX_NULLCHECK_THREE(crl
, crl
->nssSignedCrl
, pSignatureAlgId
);
219 /* if we don't have a cached copy from before, we create one */
220 if (crl
->signatureAlgId
== NULL
){
222 PKIX_OBJECT_LOCK(crl
);
224 if (crl
->signatureAlgId
== NULL
){
226 nssCrl
= &(crl
->nssSignedCrl
->crl
);
227 algorithm
= nssCrl
->signatureAlg
;
228 algBytes
= algorithm
.algorithm
;
230 PKIX_NULLCHECK_ONE(algBytes
.data
);
231 if (algBytes
.len
== 0) {
232 PKIX_ERROR_FATAL(PKIX_OIDBYTESLENGTH0
);
235 PKIX_CHECK(pkix_pl_oidBytes2Ascii
236 (&algBytes
, &asciiOID
, plContext
),
237 PKIX_OIDBYTES2ASCIIFAILED
);
239 PKIX_CHECK(PKIX_PL_OID_Create
240 (asciiOID
, &signatureAlgId
, plContext
),
241 PKIX_OIDCREATEFAILED
);
243 /* save a cached copy in case it is asked for again */
244 crl
->signatureAlgId
= signatureAlgId
;
247 PKIX_OBJECT_UNLOCK(crl
);
251 PKIX_INCREF(crl
->signatureAlgId
);
252 *pSignatureAlgId
= crl
->signatureAlgId
;
262 * FUNCTION: pkix_pl_CRL_GetCRLEntries
265 * Retrieves a pointer to the List of CRLEntries found in the CRL pointed to
266 * by "crl" and stores it at "pCRLEntries". If there are no CRLEntries,
267 * this functions stores NULL at "pCRLEntries".
271 * Address of CRL whose CRL Entries are to be retrieved. Must be non-NULL.
273 * Address where object pointer will be stored. Must be non-NULL.
275 * Platform-specific context pointer.
277 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
279 * Returns NULL if the function succeeds.
280 * Returns a CRL Error if the function fails in a non-fatal way.
281 * Returns a Fatal Error if the function fails in an unrecoverable way.
284 pkix_pl_CRL_GetCRLEntries(
286 PKIX_List
**pCrlEntries
,
289 PKIX_List
*entryList
= NULL
;
290 CERTCrl
*nssCrl
= NULL
;
292 PKIX_ENTER(CRL
, "pkix_pl_CRL_GetCRLEntries");
293 PKIX_NULLCHECK_THREE(crl
, crl
->nssSignedCrl
, pCrlEntries
);
295 /* if we don't have a cached copy from before, we create one */
296 if (crl
->crlEntryList
== NULL
) {
298 PKIX_OBJECT_LOCK(crl
);
300 if (crl
->crlEntryList
== NULL
){
302 nssCrl
= &(crl
->nssSignedCrl
->crl
);
304 PKIX_CHECK(pkix_pl_CRLEntry_Create
305 (nssCrl
->entries
, &entryList
, plContext
),
306 PKIX_CRLENTRYCREATEFAILED
);
308 PKIX_CHECK(PKIX_List_SetImmutable
309 (entryList
, plContext
),
310 PKIX_LISTSETIMMUTABLEFAILED
);
312 crl
->crlEntryList
= entryList
;
315 PKIX_OBJECT_UNLOCK(crl
);
319 PKIX_INCREF(crl
->crlEntryList
);
321 *pCrlEntries
= crl
->crlEntryList
;
329 * FUNCTION: pkix_pl_CRL_Destroy
330 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
334 PKIX_PL_Object
*object
,
337 PKIX_PL_CRL
*crl
= NULL
;
339 PKIX_ENTER(CRL
, "pkix_pl_CRL_Destroy");
340 PKIX_NULLCHECK_ONE(object
);
342 PKIX_CHECK(pkix_CheckType(object
, PKIX_CRL_TYPE
, plContext
),
345 crl
= (PKIX_PL_CRL
*)object
;
347 PKIX_NULLCHECK_ONE(crl
->nssSignedCrl
);
349 PKIX_CRL_DEBUG("\t\tCalling CERT_DestroyCrl\n");
350 CERT_DestroyCrl(crl
->nssSignedCrl
);
351 crl
->nssSignedCrl
= NULL
;
352 crl
->crlNumberAbsent
= PKIX_FALSE
;
354 PKIX_DECREF(crl
->issuer
);
355 PKIX_DECREF(crl
->signatureAlgId
);
356 PKIX_DECREF(crl
->crlNumber
);
357 PKIX_DECREF(crl
->crlEntryList
);
358 PKIX_DECREF(crl
->critExtOids
);
366 * FUNCTION: pkix_pl_CRL_ToString_Helper
369 * Helper function that creates a string representation of the CRL pointed
370 * to by "crl" and stores it at "pString".
374 * Address of CRL whose string representation is desired.
377 * Address where object pointer will be stored. Must be non-NULL.
379 * Platform-specific context pointer.
381 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
383 * Returns NULL if the function succeeds.
384 * Returns a CRL Error if the function fails in a non-fatal way.
385 * Returns a Fatal Error if the function fails in an unrecoverable way.
388 pkix_pl_CRL_ToString_Helper(
390 PKIX_PL_String
**pString
,
393 char *asciiFormat
= NULL
;
394 PKIX_UInt32 crlVersion
;
395 PKIX_PL_X500Name
*crlIssuer
= NULL
;
396 PKIX_PL_OID
*nssSignatureAlgId
= NULL
;
397 PKIX_PL_BigInt
*crlNumber
= NULL
;
398 PKIX_List
*crlEntryList
= NULL
;
399 PKIX_List
*critExtOIDs
= NULL
;
400 PKIX_PL_String
*formatString
= NULL
;
401 PKIX_PL_String
*crlIssuerString
= NULL
;
402 PKIX_PL_String
*lastUpdateString
= NULL
;
403 PKIX_PL_String
*nextUpdateString
= NULL
;
404 PKIX_PL_String
*nssSignatureAlgIdString
= NULL
;
405 PKIX_PL_String
*crlNumberString
= NULL
;
406 PKIX_PL_String
*crlEntryListString
= NULL
;
407 PKIX_PL_String
*critExtOIDsString
= NULL
;
408 PKIX_PL_String
*crlString
= NULL
;
410 PKIX_ENTER(CRL
, "pkix_pl_CRL_ToString_Helper");
411 PKIX_NULLCHECK_THREE(crl
, crl
->nssSignedCrl
, pString
);
417 "\tUpdate: [Last: %s\n"
419 "\tSignatureAlgId: %s\n"
420 "\tCRL Number : %s\n"
424 "\tCritExtOIDs: %s\n"
427 PKIX_CHECK(PKIX_PL_String_Create
433 PKIX_STRINGCREATEFAILED
);
436 PKIX_CHECK(pkix_pl_CRL_GetVersion(crl
, &crlVersion
, plContext
),
437 PKIX_CRLGETVERSIONFAILED
);
440 PKIX_CHECK(PKIX_PL_CRL_GetIssuer(crl
, &crlIssuer
, plContext
),
441 PKIX_CRLGETISSUERFAILED
);
443 PKIX_CHECK(PKIX_PL_Object_ToString
444 ((PKIX_PL_Object
*)crlIssuer
, &crlIssuerString
, plContext
),
445 PKIX_X500NAMETOSTRINGFAILED
);
447 /* This update - No Date object created, use nss data directly */
448 PKIX_CHECK(pkix_pl_Date_ToString_Helper
449 (&(crl
->nssSignedCrl
->crl
.lastUpdate
),
452 PKIX_DATETOSTRINGHELPERFAILED
);
454 /* Next update - No Date object created, use nss data directly */
455 PKIX_CHECK(pkix_pl_Date_ToString_Helper
456 (&(crl
->nssSignedCrl
->crl
.nextUpdate
),
459 PKIX_DATETOSTRINGHELPERFAILED
);
461 /* Signature Algorithm Id */
462 PKIX_CHECK(pkix_pl_CRL_GetSignatureAlgId
463 (crl
, &nssSignatureAlgId
, plContext
),
464 PKIX_CRLGETSIGNATUREALGIDFAILED
);
466 PKIX_CHECK(PKIX_PL_Object_ToString
467 ((PKIX_PL_Object
*)nssSignatureAlgId
,
468 &nssSignatureAlgIdString
,
470 PKIX_OIDTOSTRINGFAILED
);
473 PKIX_CHECK(PKIX_PL_CRL_GetCRLNumber
474 (crl
, &crlNumber
, plContext
),
475 PKIX_CRLGETCRLNUMBERFAILED
);
477 PKIX_TOSTRING(crlNumber
, &crlNumberString
, plContext
,
478 PKIX_BIGINTTOSTRINGFAILED
);
481 PKIX_CHECK(pkix_pl_CRL_GetCRLEntries(crl
, &crlEntryList
, plContext
),
482 PKIX_CRLGETCRLENTRIESFAILED
);
484 PKIX_TOSTRING(crlEntryList
, &crlEntryListString
, plContext
,
485 PKIX_LISTTOSTRINGFAILED
);
487 /* CriticalExtensionOIDs */
488 PKIX_CHECK(PKIX_PL_CRL_GetCriticalExtensionOIDs
489 (crl
, &critExtOIDs
, plContext
),
490 PKIX_CRLGETCRITICALEXTENSIONOIDSFAILED
);
492 PKIX_TOSTRING(critExtOIDs
, &critExtOIDsString
, plContext
,
493 PKIX_LISTTOSTRINGFAILED
);
495 PKIX_CHECK(PKIX_PL_Sprintf
503 nssSignatureAlgIdString
,
509 *pString
= crlString
;
513 PKIX_DECREF(crlIssuer
);
514 PKIX_DECREF(nssSignatureAlgId
);
515 PKIX_DECREF(crlNumber
);
516 PKIX_DECREF(crlEntryList
);
517 PKIX_DECREF(critExtOIDs
);
518 PKIX_DECREF(crlIssuerString
);
519 PKIX_DECREF(lastUpdateString
);
520 PKIX_DECREF(nextUpdateString
);
521 PKIX_DECREF(nssSignatureAlgIdString
);
522 PKIX_DECREF(crlNumberString
);
523 PKIX_DECREF(crlEntryListString
);
524 PKIX_DECREF(critExtOIDsString
);
525 PKIX_DECREF(formatString
);
531 * FUNCTION: pkix_pl_CRL_ToString
532 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
535 pkix_pl_CRL_ToString(
536 PKIX_PL_Object
*object
,
537 PKIX_PL_String
**pString
,
540 PKIX_PL_String
*crlString
= NULL
;
541 PKIX_PL_CRL
*crl
= NULL
;
543 PKIX_ENTER(CRL
, "pkix_pl_CRL_ToString");
544 PKIX_NULLCHECK_TWO(object
, pString
);
546 PKIX_CHECK(pkix_CheckType(object
, PKIX_CRL_TYPE
, plContext
),
549 crl
= (PKIX_PL_CRL
*) object
;
551 PKIX_CHECK(pkix_pl_CRL_ToString_Helper(crl
, &crlString
, plContext
),
552 PKIX_CRLTOSTRINGHELPERFAILED
);
554 *pString
= crlString
;
562 * FUNCTION: pkix_pl_CRL_Hashcode
563 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
566 pkix_pl_CRL_Hashcode(
567 PKIX_PL_Object
*object
,
568 PKIX_UInt32
*pHashcode
,
571 PKIX_PL_CRL
*crl
= NULL
;
572 unsigned char *derBytes
= NULL
;
573 PKIX_UInt32 derLength
;
574 PKIX_UInt32 certHash
;
576 PKIX_ENTER(CRL
, "pkix_pl_CRL_Hashcode");
577 PKIX_NULLCHECK_TWO(object
, pHashcode
);
579 PKIX_CHECK(pkix_CheckType(object
, PKIX_CRL_TYPE
, plContext
),
582 crl
= (PKIX_PL_CRL
*)object
;
584 PKIX_NULLCHECK_TWO(crl
->nssSignedCrl
, crl
->nssSignedCrl
->derCrl
);
586 derBytes
= (crl
->nssSignedCrl
->derCrl
)->data
;
587 derLength
= (crl
->nssSignedCrl
->derCrl
)->len
;
589 PKIX_NULLCHECK_ONE(derBytes
);
590 PKIX_CHECK(pkix_hash(derBytes
, derLength
, &certHash
, plContext
),
593 *pHashcode
= certHash
;
601 * FUNCTION: pkix_pl_CRL_Equals
602 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
606 PKIX_PL_Object
*firstObject
,
607 PKIX_PL_Object
*secondObject
,
608 PKIX_Boolean
*pResult
,
611 PKIX_PL_CRL
*firstCrl
= NULL
;
612 PKIX_PL_CRL
*secondCrl
= NULL
;
613 PKIX_UInt32 secondType
;
615 PKIX_ENTER(CRL
, "pkix_pl_CRL_Equals");
616 PKIX_NULLCHECK_THREE(firstObject
, secondObject
, pResult
);
618 /* test that firstObject is a CRL */
619 PKIX_CHECK(pkix_CheckType(firstObject
, PKIX_CRL_TYPE
, plContext
),
620 PKIX_FIRSTOBJECTNOTCRL
);
622 firstCrl
= (PKIX_PL_CRL
*)firstObject
;
623 secondCrl
= (PKIX_PL_CRL
*)secondObject
;
626 * Since we know firstObject is a CRL, if both references are
627 * identical, they must be equal
629 if (firstCrl
== secondCrl
){
630 *pResult
= PKIX_TRUE
;
635 * If secondCrl isn't a CRL, we don't throw an error.
636 * We simply return a Boolean result of FALSE
638 *pResult
= PKIX_FALSE
;
639 PKIX_CHECK(PKIX_PL_Object_GetType
640 ((PKIX_PL_Object
*)secondCrl
, &secondType
, plContext
),
641 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT
);
642 if (secondType
!= PKIX_CRL_TYPE
) goto cleanup
;
644 /* Compare DER Bytes */
646 (firstCrl
->nssSignedCrl
,
647 firstCrl
->nssSignedCrl
->derCrl
);
650 (secondCrl
->nssSignedCrl
,
651 secondCrl
->nssSignedCrl
->derCrl
);
653 PKIX_CRL_DEBUG("\t\tCalling SECITEM_CompareItem on derCrl\n");
654 if (SECITEM_CompareItem(firstCrl
->nssSignedCrl
->derCrl
,
655 secondCrl
->nssSignedCrl
->derCrl
) == SECEqual
) {
656 *pResult
= PKIX_TRUE
;
665 * FUNCTION: pkix_pl_CRL_RegisterSelf
668 * Registers PKIX_CRL_TYPE and its related functions with systemClasses[]
671 * Not Thread Safe - for performance and complexity reasons
673 * Since this function is only called by PKIX_PL_Initialize, which should
674 * only be called once, it is acceptable that this function is not
678 pkix_pl_CRL_RegisterSelf(void *plContext
)
681 extern pkix_ClassTable_Entry systemClasses
[PKIX_NUMTYPES
];
682 pkix_ClassTable_Entry entry
;
684 PKIX_ENTER(CRL
, "pkix_pl_CRL_RegisterSelf");
686 entry
.description
= "CRL";
687 entry
.objCounter
= 0;
688 entry
.typeObjectSize
= sizeof(PKIX_PL_CRL
);
689 entry
.destructor
= pkix_pl_CRL_Destroy
;
690 entry
.equalsFunction
= pkix_pl_CRL_Equals
;
691 entry
.hashcodeFunction
= pkix_pl_CRL_Hashcode
;
692 entry
.toStringFunction
= pkix_pl_CRL_ToString
;
693 entry
.comparator
= NULL
;
694 entry
.duplicateFunction
= pkix_duplicateImmutable
;
696 systemClasses
[PKIX_CRL_TYPE
] = entry
;
702 * FUNCTION: PKIX_PL_CRL_VerifyUpdateTime (see comments in pkix_pl_pki.h)
705 PKIX_PL_CRL_VerifyUpdateTime(
708 PKIX_Boolean
*pResult
,
715 CERTCrl
*nssCrl
= NULL
;
716 SECItem
*nextUpdateDer
= NULL
;
717 PKIX_Boolean haveNextUpdate
= PR_FALSE
;
719 PKIX_ENTER(CRL
, "PKIX_PL_CRL_VerifyUpdateTime");
720 PKIX_NULLCHECK_FOUR(crl
, crl
->nssSignedCrl
, date
, pResult
);
722 nssCrl
= &(crl
->nssSignedCrl
->crl
);
724 PKIX_CRL_DEBUG("\t\tCalling DER_DecodeTimeChoice on date\n");
725 status
= DER_DecodeTimeChoice(&timeToCheck
, &(date
->nssTime
));
726 if (status
!= SECSuccess
) {
727 PKIX_ERROR(PKIX_DERDECODETIMECHOICEFAILED
);
730 /* nextUpdate can be NULL. Checking before using it */
731 nextUpdateDer
= &nssCrl
->nextUpdate
;
732 if (nextUpdateDer
->data
&& nextUpdateDer
->len
) {
733 haveNextUpdate
= PR_TRUE
;
734 status
= DER_DecodeTimeChoice(&nextUpdate
, nextUpdateDer
);
735 if (status
!= SECSuccess
) {
736 PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORNEXTUPDATEFAILED
);
740 status
= DER_DecodeTimeChoice(&lastUpdate
, &(nssCrl
->lastUpdate
));
741 if (status
!= SECSuccess
) {
742 PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORLASTUPDATEFAILED
);
745 if (!haveNextUpdate
|| nextUpdate
< timeToCheck
) {
746 *pResult
= PKIX_FALSE
;
750 if (lastUpdate
<= timeToCheck
) {
751 *pResult
= PKIX_TRUE
;
753 *pResult
= PKIX_FALSE
;
762 * FUNCTION: pkix_pl_CRL_CreateWithSignedCRL
765 * Creates a new CRL using the CERTSignedCrl pointed to by "nssSignedCrl"
766 * and stores it at "pCRL". If the decoding of the CERTSignedCrl fails,
767 * a PKIX_Error is returned.
771 * Address of CERTSignedCrl. Must be non-NULL.
773 * Address where object pointer will be stored. Must be non-NULL.
775 * Platform-specific context pointer.
777 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
779 * Returns NULL if the function succeeds.
780 * Returns a CRL Error if the function fails in a non-fatal way.
781 * Returns a Fatal Error if the function fails in an unrecoverable way.
784 pkix_pl_CRL_CreateWithSignedCRL(
785 CERTSignedCrl
*nssSignedCrl
,
790 PKIX_PL_CRL
*crl
= NULL
;
792 PKIX_ENTER(CRL
, "pkix_pl_CRL_CreateWithSignedCRL");
793 PKIX_NULLCHECK_TWO(nssSignedCrl
, pCrl
);
795 /* create a PKIX_PL_CRL object */
796 PKIX_CHECK(PKIX_PL_Object_Alloc
798 sizeof (PKIX_PL_CRL
),
799 (PKIX_PL_Object
**)&crl
,
801 PKIX_COULDNOTCREATECRLOBJECT
);
803 /* populate the nssSignedCrl field */
804 crl
->nssSignedCrl
= nssSignedCrl
;
806 PKIX_CRL_DEBUG("\t\tCalling CERT_CompleteCRLDecodeEntries\n");
807 status
= CERT_CompleteCRLDecodeEntries(crl
->nssSignedCrl
);
809 if (status
!= SECSuccess
) {
810 PKIX_ERROR(PKIX_CERTCOMPLETECRLDECODEDENTRIESFAILED
);
814 crl
->signatureAlgId
= NULL
;
815 crl
->crlNumber
= NULL
;
816 crl
->crlNumberAbsent
= PKIX_FALSE
;
817 crl
->crlEntryList
= NULL
;
818 crl
->critExtOids
= NULL
;
824 if (PKIX_ERROR_RECEIVED
){
832 * FUNCTION: pkix_pl_CRL_CreateToList
835 * This function decodes a DER-encoded Certificate Revocation List pointed to
836 * by "derCrlItem", adding the resulting PKIX_PL_CRL, if the decoding was
837 * successful, to the List (possibly empty) pointed to by "crlList".
841 * The address of the SECItem containing the DER-encoded Certificate
842 * Revocation List. Must be non-NULL.
844 * The address of the List to which the decoded CRL is added. May be
845 * empty, but must be non-NULL.
847 * Platform-specific context pointer.
849 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
851 * Returns NULL if the function succeeds.
852 * Returns a CertStore Error if the function fails in a non-fatal way.
853 * Returns a Fatal Error if the function fails in an unrecoverable way.
856 pkix_pl_CRL_CreateToList(
861 CERTSignedCrl
*nssCrl
= NULL
;
862 PKIX_PL_CRL
*crl
= NULL
;
864 PKIX_ENTER(CRL
, "pkix_pl_CRL_CreateToList");
865 PKIX_NULLCHECK_TWO(derCrlItem
, crlList
);
867 nssCrl
= CERT_DecodeDERCrl(NULL
, derCrlItem
, SEC_CRL_TYPE
);
868 if (nssCrl
== NULL
) {
872 PKIX_CHECK(pkix_pl_CRL_CreateWithSignedCRL
873 (nssCrl
, &crl
, plContext
),
874 PKIX_CRLCREATEWITHSIGNEDCRLFAILED
);
878 PKIX_CHECK(PKIX_List_AppendItem
879 (crlList
, (PKIX_PL_Object
*) crl
, plContext
),
880 PKIX_LISTAPPENDITEMFAILED
);
884 SEC_DestroyCrl(nssCrl
);
892 /* --Public-CRL-Functions------------------------------------- */
895 * FUNCTION: PKIX_PL_CRL_Create (see comments in pkix_pl_pki.h)
899 PKIX_PL_ByteArray
*byteArray
,
903 CERTSignedCrl
*nssSignedCrl
= NULL
;
904 SECItem
*derCrlItem
= NULL
;
905 void *derBytes
= NULL
;
906 PKIX_UInt32 derLength
;
907 PKIX_PL_CRL
*crl
= NULL
;
909 PKIX_ENTER(CRL
, "PKIX_PL_CRL_Create");
910 PKIX_NULLCHECK_TWO(byteArray
, pCrl
);
912 PKIX_CHECK(PKIX_PL_ByteArray_GetLength
913 (byteArray
, &derLength
, plContext
),
914 PKIX_BYTEARRAYGETLENGTHFAILED
);
917 PKIX_ERROR(PKIX_ZEROLENGTHBYTEARRAYFORCRLENCODING
);
920 PKIX_CHECK(PKIX_PL_ByteArray_GetPointer
921 (byteArray
, &derBytes
, plContext
),
922 PKIX_BYTEARRAYGETPOINTERFAILED
);
924 PKIX_CRL_DEBUG("\t\tCalling SECITEM_AllocItem\n");
925 derCrlItem
= SECITEM_AllocItem(NULL
, NULL
, derLength
);
926 if (derCrlItem
== NULL
){
927 PKIX_ERROR(PKIX_OUTOFMEMORY
);
930 PKIX_CRL_DEBUG("\t\tCalling PORT_Memcpy\n");
931 (void) PORT_Memcpy(derCrlItem
->data
, derBytes
, derLength
);
933 PKIX_CRL_DEBUG("\t\tCalling CERT_DecodeDERCrl\n");
934 nssSignedCrl
= CERT_DecodeDERCrl(NULL
, derCrlItem
, SEC_CRL_TYPE
);
935 if (nssSignedCrl
== NULL
){
936 PKIX_ERROR(PKIX_CERTDECODEDERCRLFAILED
);
939 PKIX_CHECK(pkix_pl_CRL_CreateWithSignedCRL
940 (nssSignedCrl
, &crl
, plContext
),
941 PKIX_CRLCREATEWITHSIGNEDCRLFAILED
);
947 if (derCrlItem
!= NULL
){
948 PKIX_CRL_DEBUG("\t\tCalling SECITEM_FreeItem\n");
949 SECITEM_FreeItem(derCrlItem
, PKIX_TRUE
);
953 if (PKIX_ERROR_RECEIVED
){
954 if (nssSignedCrl
!= NULL
) {
955 PKIX_CRL_DEBUG("\t\tCalling CERT_DestroyCrl\n");
956 CERT_DestroyCrl(nssSignedCrl
);
969 * FUNCTION: PKIX_PL_CRL_GetIssuer (see comments in pkix_pl_pki.h)
972 PKIX_PL_CRL_GetIssuer(
974 PKIX_PL_X500Name
**pCRLIssuer
,
977 PKIX_PL_String
*crlString
= NULL
;
978 PKIX_PL_X500Name
*issuer
= NULL
;
979 SECItem
*derIssuerName
= NULL
;
980 CERTName
*issuerName
= NULL
;
982 PKIX_ENTER(CRL
, "PKIX_PL_CRL_GetIssuer");
983 PKIX_NULLCHECK_THREE(crl
, crl
->nssSignedCrl
, pCRLIssuer
);
985 /* if we don't have a cached copy from before, we create one */
986 if (crl
->issuer
== NULL
){
988 PKIX_OBJECT_LOCK(crl
);
990 if (crl
->issuer
== NULL
) {
992 issuerName
= &crl
->nssSignedCrl
->crl
.name
;
993 derIssuerName
= &crl
->nssSignedCrl
->crl
.derName
;
996 PKIX_PL_X500Name_CreateFromCERTName(derIssuerName
,
1000 PKIX_X500NAMECREATEFROMCERTNAMEFAILED
);
1002 /* save a cached copy in case it is asked for again */
1003 crl
->issuer
= issuer
;
1006 PKIX_OBJECT_UNLOCK(crl
);
1010 PKIX_INCREF(crl
->issuer
);
1012 *pCRLIssuer
= crl
->issuer
;
1016 PKIX_DECREF(crlString
);
1023 * FUNCTION: PKIX_PL_CRL_GetCriticalExtensionOIDs
1024 * (see comments in pkix_pl_pki.h)
1027 PKIX_PL_CRL_GetCriticalExtensionOIDs(
1029 PKIX_List
**pExtensions
, /* list of PKIX_PL_OID */
1032 PKIX_List
*oidsList
= NULL
;
1033 CERTCertExtension
**extensions
= NULL
;
1034 CERTCrl
*nssSignedCrl
= NULL
;
1036 PKIX_ENTER(CRL
, "PKIX_PL_CRL_GetCriticalExtensionOIDs");
1037 PKIX_NULLCHECK_THREE(crl
, crl
->nssSignedCrl
, pExtensions
);
1039 /* if we don't have a cached copy from before, we create one */
1040 if (crl
->critExtOids
== NULL
) {
1042 PKIX_OBJECT_LOCK(crl
);
1044 nssSignedCrl
= &(crl
->nssSignedCrl
->crl
);
1045 extensions
= nssSignedCrl
->extensions
;
1047 if (crl
->critExtOids
== NULL
) {
1049 PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
1050 (extensions
, &oidsList
, plContext
),
1051 PKIX_GETCRITICALEXTENSIONOIDSFAILED
);
1053 crl
->critExtOids
= oidsList
;
1056 PKIX_OBJECT_UNLOCK(crl
);
1060 /* We should return a copy of the List since this list changes */
1061 PKIX_DUPLICATE(crl
->critExtOids
, pExtensions
, plContext
,
1062 PKIX_OBJECTDUPLICATELISTFAILED
);
1071 * FUNCTION: PKIX_PL_CRL_GetCRLEntryForSerialNumber
1072 * (see comments in pkix_pl_pki.h)
1075 PKIX_PL_CRL_GetCRLEntryForSerialNumber(
1077 PKIX_PL_BigInt
*serialNumber
,
1078 PKIX_PL_CRLEntry
**pCRLEntry
,
1081 PKIX_PL_CRLEntry
*crlEntry
= NULL
;
1082 PKIX_List
*crlEntryList
= NULL
;
1083 PKIX_UInt32 numEntries
= 0;
1085 PKIX_Boolean cmpResult
= PKIX_FALSE
;
1087 PKIX_ENTER(CRL
, "PKIX_PL_CRL_GetCRLEntryForSerialNumber");
1088 PKIX_NULLCHECK_THREE(crl
, serialNumber
, pCRLEntry
);
1090 /* Assume there is no entry for Serial Number at start */
1093 PKIX_CHECK(pkix_pl_CRL_GetCRLEntries(crl
, &crlEntryList
, plContext
),
1094 PKIX_CRLGETCRLENTRIESFAILED
);
1096 if (crlEntryList
== NULL
) {
1100 PKIX_CHECK(PKIX_List_GetLength(crlEntryList
, &numEntries
, plContext
),
1101 PKIX_LISTGETLENGTHFAILED
);
1103 for (i
= 0; i
< numEntries
; i
++){
1105 PKIX_CHECK(PKIX_List_GetItem
1108 (PKIX_PL_Object
**)&crlEntry
,
1110 PKIX_LISTGETITEMFAILED
);
1112 PKIX_CHECK(PKIX_PL_Object_Equals
1113 ((PKIX_PL_Object
*)crlEntry
->serialNumber
,
1114 (PKIX_PL_Object
*)serialNumber
,
1117 PKIX_OBJECTEQUALSFAILED
);
1119 /* Found the entry for Serial Number */
1120 if (cmpResult
== PKIX_TRUE
) {
1121 *pCRLEntry
= crlEntry
;
1125 PKIX_DECREF(crlEntry
);
1130 PKIX_DECREF(crlEntryList
);
1132 if (PKIX_ERROR_RECEIVED
){
1133 PKIX_DECREF(crlEntry
);
1140 * FUNCTION: PKIX_PL_CRL_VerifySignature (see comments in pkix_pl_pki.h)
1143 PKIX_PL_CRL_VerifySignature(
1145 PKIX_PL_PublicKey
*pubKey
,
1148 PKIX_PL_CRL
*cachedCrl
= NULL
;
1149 PKIX_Error
*verifySig
= NULL
;
1150 PKIX_Error
*cachedSig
= NULL
;
1151 PKIX_Boolean crlEqual
= PKIX_FALSE
;
1152 PKIX_Boolean crlInHash
= PKIX_FALSE
;
1153 CERTSignedCrl
*nssSignedCrl
= NULL
;
1154 SECKEYPublicKey
*nssPubKey
= NULL
;
1155 CERTSignedData
*tbsCrl
= NULL
;
1158 PKIX_ENTER(CRL
, "PKIX_PL_CRL_VerifySignature");
1159 PKIX_NULLCHECK_THREE(crl
, crl
->nssSignedCrl
, pubKey
);
1161 verifySig
= PKIX_PL_HashTable_Lookup
1163 (PKIX_PL_Object
*) pubKey
,
1164 (PKIX_PL_Object
**) &cachedCrl
,
1167 if (cachedCrl
!= NULL
&& verifySig
== NULL
) {
1168 /* Cached Signature Table lookup succeed */
1169 PKIX_EQUALS(crl
, cachedCrl
, &crlEqual
, plContext
,
1170 PKIX_OBJECTEQUALSFAILED
);
1171 if (crlEqual
== PKIX_TRUE
) {
1174 /* Different PubKey may hash to same value, skip add */
1175 crlInHash
= PKIX_TRUE
;
1178 nssSignedCrl
= crl
->nssSignedCrl
;
1179 tbsCrl
= &nssSignedCrl
->signatureWrap
;
1181 PKIX_CRL_DEBUG("\t\tCalling SECKEY_ExtractPublicKey\n");
1182 nssPubKey
= SECKEY_ExtractPublicKey(pubKey
->nssSPKI
);
1184 PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED
);
1187 PKIX_CRL_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey\n");
1188 status
= CERT_VerifySignedDataWithPublicKey(tbsCrl
, nssPubKey
, NULL
);
1190 if (status
!= SECSuccess
) {
1191 PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHEPUBLICKEY
);
1194 if (crlInHash
== PKIX_FALSE
) {
1195 cachedSig
= PKIX_PL_HashTable_Add
1197 (PKIX_PL_Object
*) pubKey
,
1198 (PKIX_PL_Object
*) crl
,
1201 if (cachedSig
!= NULL
) {
1202 PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed\n");
1209 PKIX_CRL_DEBUG("\t\tCalling SECKEY_DestroyPublicKey\n");
1210 SECKEY_DestroyPublicKey(nssPubKey
);
1214 PKIX_DECREF(cachedCrl
);
1215 PKIX_DECREF(verifySig
);
1216 PKIX_DECREF(cachedSig
);