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 * CRLENTRY Function Definitions
44 #include "pkix_pl_crlentry.h"
46 /* --Private-CRLEntry-Functions------------------------------------- */
49 * FUNCTION: pkix_pl_CRLEntry_Destroy
50 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
53 pkix_pl_CRLEntry_Destroy(
54 PKIX_PL_Object
*object
,
57 PKIX_PL_CRLEntry
*crlEntry
= NULL
;
59 PKIX_ENTER(CRLENTRY
, "pkix_pl_CRLEntry_Destroy");
60 PKIX_NULLCHECK_ONE(object
);
62 PKIX_CHECK(pkix_CheckType(object
, PKIX_CRLENTRY_TYPE
, plContext
),
63 PKIX_OBJECTNOTCRLENTRY
);
65 crlEntry
= (PKIX_PL_CRLEntry
*)object
;
67 /* crlEntry->nssCrlEntry is freed by NSS when freeing CRL */
68 crlEntry
->userReasonCode
= 0;
69 crlEntry
->userReasonCodeAbsent
= PKIX_FALSE
;
70 crlEntry
->nssCrlEntry
= NULL
;
71 PKIX_DECREF(crlEntry
->serialNumber
);
72 PKIX_DECREF(crlEntry
->critExtOids
);
76 PKIX_RETURN(CRLENTRY
);
80 * FUNCTION: pkix_pl_CRLEntry_ToString_Helper
83 * Helper function that creates a string representation of the CRLEntry
84 * pointed to by "crlEntry" and stores it at "pString".
88 * Address of CRLEntry whose string representation is desired.
91 * Address where object pointer will be stored. Must be non-NULL.
93 * Platform-specific context pointer.
95 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
97 * Returns NULL if the function succeeds.
98 * Returns a CRLEntry Error if the function fails in a non-fatal way.
99 * Returns a Fatal Error if the function fails in an unrecoverable way.
102 pkix_pl_CRLEntry_ToString_Helper(
103 PKIX_PL_CRLEntry
*crlEntry
,
104 PKIX_PL_String
**pString
,
107 char *asciiFormat
= NULL
;
108 PKIX_List
*critExtOIDs
= NULL
;
109 PKIX_PL_String
*crlEntryString
= NULL
;
110 PKIX_PL_String
*formatString
= NULL
;
111 PKIX_PL_String
*crlSerialNumberString
= NULL
;
112 PKIX_PL_String
*crlRevocationDateString
= NULL
;
113 PKIX_PL_String
*critExtOIDsString
= NULL
;
114 PKIX_Int32 reasonCode
= 0;
116 PKIX_ENTER(CRLENTRY
, "pkix_pl_CRLEntry_ToString_Helper");
119 crlEntry
->serialNumber
,
120 crlEntry
->nssCrlEntry
,
125 "\tSerialNumber: %s\n"
127 "\tRevocationDate: %s\n"
128 "\tCritExtOIDs: %s\n"
131 PKIX_CHECK(PKIX_PL_String_Create
137 PKIX_STRINGCREATEFAILED
);
140 PKIX_CHECK(PKIX_PL_Object_ToString
141 ((PKIX_PL_Object
*)crlEntry
->serialNumber
,
142 &crlSerialNumberString
,
144 PKIX_BIGINTTOSTRINGHELPERFAILED
);
146 /* RevocationDate - No Date object created, use nss data directly */
147 PKIX_CHECK(pkix_pl_Date_ToString_Helper
148 (&(crlEntry
->nssCrlEntry
->revocationDate
),
149 &crlRevocationDateString
,
151 PKIX_DATETOSTRINGHELPERFAILED
);
153 /* CriticalExtensionOIDs */
154 PKIX_CHECK(PKIX_PL_CRLEntry_GetCriticalExtensionOIDs
155 (crlEntry
, &critExtOIDs
, plContext
),
156 PKIX_CRLENTRYGETCRITICALEXTENSIONOIDSFAILED
);
158 PKIX_TOSTRING(critExtOIDs
, &critExtOIDsString
, plContext
,
159 PKIX_LISTTOSTRINGFAILED
);
161 /* Revocation Reason Code */
162 PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode
163 (crlEntry
, &reasonCode
, plContext
),
164 PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED
);
166 PKIX_CHECK(PKIX_PL_Sprintf
170 crlSerialNumberString
,
172 crlRevocationDateString
,
176 *pString
= crlEntryString
;
180 PKIX_DECREF(critExtOIDs
);
181 PKIX_DECREF(crlSerialNumberString
);
182 PKIX_DECREF(crlRevocationDateString
);
183 PKIX_DECREF(critExtOIDsString
);
184 PKIX_DECREF(formatString
);
186 PKIX_RETURN(CRLENTRY
);
190 * FUNCTION: pkix_pl_CRLEntry_ToString
191 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
194 pkix_pl_CRLEntry_ToString(
195 PKIX_PL_Object
*object
,
196 PKIX_PL_String
**pString
,
199 PKIX_PL_String
*crlEntryString
= NULL
;
200 PKIX_PL_CRLEntry
*crlEntry
= NULL
;
202 PKIX_ENTER(CRLENTRY
, "pkix_pl_CRLEntry_ToString");
203 PKIX_NULLCHECK_TWO(object
, pString
);
205 PKIX_CHECK(pkix_CheckType(object
, PKIX_CRLENTRY_TYPE
, plContext
),
206 PKIX_OBJECTNOTCRLENTRY
);
208 crlEntry
= (PKIX_PL_CRLEntry
*) object
;
210 PKIX_CHECK(pkix_pl_CRLEntry_ToString_Helper
211 (crlEntry
, &crlEntryString
, plContext
),
212 PKIX_CRLENTRYTOSTRINGHELPERFAILED
);
214 *pString
= crlEntryString
;
218 PKIX_RETURN(CRLENTRY
);
222 * FUNCTION: pkix_pl_CRLEntry_Extensions_Hashcode
225 * For each CRL Entry extension stored at NSS structure CERTCertExtension,
226 * get its derbyte data and do the hash.
230 * Address of arrray of CERTCertExtension whose hash value is desired.
233 * Address where the final hash value is returned. Must be non-NULL.
235 * Platform-specific context pointer.
237 * Conditional Thread Safe
238 * Though the value of extensions once created is not supposed to change,
239 * it may be de-allocated while we are accessing it. But since we are
240 * validating the object, it is unlikely we or someone is de-allocating
243 * Returns NULL if the function succeeds.
244 * Returns an OID Error if the function fails in a non-fatal way.
245 * Returns a Fatal Error if the function fails in an unrecoverable way.
248 pkix_pl_CRLEntry_Extensions_Hashcode(
249 CERTCertExtension
**extensions
,
250 PKIX_UInt32
*pHashValue
,
253 CERTCertExtension
*extension
= NULL
;
254 PRArenaPool
*arena
= NULL
;
255 PKIX_UInt32 extHash
= 0;
256 PKIX_UInt32 hashValue
= 0;
257 SECItem
*derBytes
= NULL
;
258 SECItem
*resultSecItem
= NULL
;
260 PKIX_ENTER(CRLENTRY
, "pkix_pl_CRLEntry_Extensions_Hashcode");
261 PKIX_NULLCHECK_TWO(extensions
, pHashValue
);
265 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n");
266 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
268 PKIX_ERROR(PKIX_OUTOFMEMORY
);
271 while (*extensions
) {
273 extension
= *extensions
++;
275 PKIX_NULLCHECK_ONE(extension
);
277 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
278 derBytes
= PORT_ArenaZNew(arena
, SECItem
);
279 if (derBytes
== NULL
) {
280 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED
);
284 ("\t\tCalling SEC_ASN1EncodeItem\n");
285 resultSecItem
= SEC_ASN1EncodeItem
289 CERT_CertExtensionTemplate
);
291 if (resultSecItem
== NULL
){
292 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED
);
302 hashValue
+= (extHash
<< 7);
307 *pHashValue
= hashValue
;
312 /* Note that freeing the arena also frees derBytes */
313 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n");
314 PORT_FreeArena(arena
, PR_FALSE
);
317 PKIX_RETURN(CRLENTRY
);
321 * FUNCTION: pkix_pl_CRLEntry_Hashcode
322 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
325 pkix_pl_CRLEntry_Hashcode(
326 PKIX_PL_Object
*object
,
327 PKIX_UInt32
*pHashcode
,
330 SECItem
*nssDate
= NULL
;
331 PKIX_PL_CRLEntry
*crlEntry
= NULL
;
332 PKIX_UInt32 crlEntryHash
;
333 PKIX_UInt32 hashValue
;
334 PKIX_Int32 reasonCode
= 0;
336 PKIX_ENTER(CRLENTRY
, "pkix_pl_CRLEntry_Hashcode");
337 PKIX_NULLCHECK_TWO(object
, pHashcode
);
339 PKIX_CHECK(pkix_CheckType(object
, PKIX_CRLENTRY_TYPE
, plContext
),
340 PKIX_OBJECTNOTCRLENTRY
);
342 crlEntry
= (PKIX_PL_CRLEntry
*)object
;
344 PKIX_NULLCHECK_ONE(crlEntry
->nssCrlEntry
);
345 nssDate
= &(crlEntry
->nssCrlEntry
->revocationDate
);
347 PKIX_NULLCHECK_ONE(nssDate
->data
);
350 ((const unsigned char *)nssDate
->data
,
354 PKIX_ERRORGETTINGHASHCODE
);
356 PKIX_CHECK(PKIX_PL_Object_Hashcode
357 ((PKIX_PL_Object
*)crlEntry
->serialNumber
,
360 PKIX_OBJECTHASHCODEFAILED
);
362 crlEntryHash
+= (hashValue
<< 7);
366 if (crlEntry
->nssCrlEntry
->extensions
) {
368 PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Hashcode
369 (crlEntry
->nssCrlEntry
->extensions
, &hashValue
, plContext
),
370 PKIX_CRLENTRYEXTENSIONSHASHCODEFAILED
);
373 crlEntryHash
+= (hashValue
<< 7);
375 PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode
376 (crlEntry
, &reasonCode
, plContext
),
377 PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED
);
379 crlEntryHash
+= (reasonCode
+ 777) << 3;
381 *pHashcode
= crlEntryHash
;
385 PKIX_RETURN(CRLENTRY
);
389 * FUNCTION: pkix_pl_CRLENTRY_Extensions_Equals
392 * Compare each extension's DERbyte data in "firstExtensions" with extension
393 * in "secondExtensions" in sequential order and store the result in
398 * Address of first NSS structure CERTCertExtension to be compared.
401 * Address of second NSS structure CERTCertExtension to be compared.
404 * Address where the comparison result is returned. Must be non-NULL.
406 * Platform-specific context pointer.
408 * Conditionally Thread Safe
409 * Though the value of extensions once created is not supposed to change,
410 * it may be de-allocated while we are accessing it. But since we are
411 * validating the object, it is unlikely we or someone is de-allocating
414 * Returns NULL if the function succeeds.
415 * Returns an OID Error if the function fails in a non-fatal way.
416 * Returns a Fatal Error if the function fails in an unrecoverable way.
419 pkix_pl_CRLEntry_Extensions_Equals(
420 CERTCertExtension
**extensions1
,
421 CERTCertExtension
**extensions2
,
422 PKIX_Boolean
*pResult
,
425 CERTCertExtension
**firstExtensions
;
426 CERTCertExtension
**secondExtensions
;
427 CERTCertExtension
*firstExtension
= NULL
;
428 CERTCertExtension
*secondExtension
= NULL
;
429 PRArenaPool
*arena
= NULL
;
430 PKIX_Boolean cmpResult
= PKIX_FALSE
;
431 SECItem
*firstDerBytes
= NULL
;
432 SECItem
*secondDerBytes
= NULL
;
433 SECItem
*firstResultSecItem
= NULL
;
434 SECItem
*secondResultSecItem
= NULL
;
435 PKIX_UInt32 firstNumExt
= 0;
436 PKIX_UInt32 secondNumExt
= 0;
437 SECComparison secResult
;
439 PKIX_ENTER(CRLENTRY
, "pkix_pl_CRLEntry_Extensions_Equals");
440 PKIX_NULLCHECK_THREE(extensions1
, extensions2
, pResult
);
442 firstExtensions
= extensions1
;
443 secondExtensions
= extensions2
;
445 if (firstExtensions
) {
446 while (*firstExtensions
) {
447 firstExtension
= *firstExtensions
++;
452 if (secondExtensions
) {
453 while (*secondExtensions
) {
454 secondExtension
= *secondExtensions
++;
459 if (firstNumExt
!= secondNumExt
) {
460 *pResult
= PKIX_FALSE
;
464 if (firstNumExt
== 0 && secondNumExt
== 0) {
465 *pResult
= PKIX_TRUE
;
469 /* now have equal number, but non-zero extension items to compare */
471 firstExtensions
= extensions1
;
472 secondExtensions
= extensions2
;
474 cmpResult
= PKIX_TRUE
;
476 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n");
477 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
*2);
479 PKIX_ERROR(PKIX_OUTOFMEMORY
);
482 while (firstNumExt
--) {
484 firstExtension
= *firstExtensions
++;
485 secondExtension
= *secondExtensions
++;
487 PKIX_NULLCHECK_TWO(firstExtension
, secondExtension
);
489 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
490 firstDerBytes
= PORT_ArenaZNew(arena
, SECItem
);
491 if (firstDerBytes
== NULL
) {
492 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED
);
495 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
496 secondDerBytes
= PORT_ArenaZNew(arena
, SECItem
);
497 if (secondDerBytes
== NULL
) {
498 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED
);
502 ("\t\tCalling SEC_ASN1EncodeItem\n");
503 firstResultSecItem
= SEC_ASN1EncodeItem
507 CERT_CertExtensionTemplate
);
509 if (firstResultSecItem
== NULL
){
510 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED
);
514 ("\t\tCalling SEC_ASN1EncodeItem\n");
515 secondResultSecItem
= SEC_ASN1EncodeItem
519 CERT_CertExtensionTemplate
);
521 if (secondResultSecItem
== NULL
){
522 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED
);
525 PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
526 secResult
= SECITEM_CompareItem
527 (firstResultSecItem
, secondResultSecItem
);
529 if (secResult
!= SECEqual
) {
530 cmpResult
= PKIX_FALSE
;
536 *pResult
= cmpResult
;
541 /* Note that freeing the arena also frees derBytes */
542 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n");
543 PORT_FreeArena(arena
, PR_FALSE
);
547 PKIX_RETURN(CRLENTRY
);
551 * FUNCTION: pkix_pl_CRLEntry_Equals
552 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
555 pkix_pl_CRLEntry_Equals(
556 PKIX_PL_Object
*firstObject
,
557 PKIX_PL_Object
*secondObject
,
558 PKIX_Boolean
*pResult
,
561 PKIX_PL_CRLEntry
*firstCrlEntry
= NULL
;
562 PKIX_PL_CRLEntry
*secondCrlEntry
= NULL
;
563 PKIX_UInt32 secondType
;
564 PKIX_Boolean cmpResult
= PKIX_FALSE
;
566 PKIX_ENTER(CRLENTRY
, "pkix_pl_CRLEntry_Equals");
567 PKIX_NULLCHECK_THREE(firstObject
, secondObject
, pResult
);
569 /* test that firstObject is a CRLEntry */
570 PKIX_CHECK(pkix_CheckType(firstObject
, PKIX_CRLENTRY_TYPE
, plContext
),
571 PKIX_FIRSTOBJECTNOTCRLENTRY
);
573 firstCrlEntry
= (PKIX_PL_CRLEntry
*)firstObject
;
574 secondCrlEntry
= (PKIX_PL_CRLEntry
*)secondObject
;
577 (firstCrlEntry
->nssCrlEntry
, secondCrlEntry
->nssCrlEntry
);
580 * Since we know firstObject is a CRLEntry, if both references are
581 * identical, they must be equal
583 if (firstCrlEntry
== secondCrlEntry
){
584 *pResult
= PKIX_TRUE
;
589 * If secondCrlEntry isn't a CRL Entry, we don't throw an error.
590 * We simply return a Boolean result of FALSE
592 *pResult
= PKIX_FALSE
;
593 PKIX_CHECK(PKIX_PL_Object_GetType
594 ((PKIX_PL_Object
*)secondCrlEntry
, &secondType
, plContext
),
595 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT
);
596 if (secondType
!= PKIX_CRLENTRY_TYPE
) goto cleanup
;
598 /* Compare userSerialNumber */
599 PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
600 if (SECITEM_CompareItem(
601 &(((PKIX_PL_CRLEntry
*)firstCrlEntry
)->nssCrlEntry
->serialNumber
),
602 &(((PKIX_PL_CRLEntry
*)secondCrlEntry
)->nssCrlEntry
->serialNumber
))
604 *pResult
= PKIX_FALSE
;
608 /* Compare revocationDate */
609 PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
610 if (SECITEM_CompareItem
611 (&(((PKIX_PL_CRLEntry
*)firstCrlEntry
)->nssCrlEntry
->
613 &(((PKIX_PL_CRLEntry
*)secondCrlEntry
)->nssCrlEntry
->
616 *pResult
= PKIX_FALSE
;
620 /* Compare Critical Extension List */
621 PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Equals
622 (firstCrlEntry
->nssCrlEntry
->extensions
,
623 secondCrlEntry
->nssCrlEntry
->extensions
,
626 PKIX_CRLENTRYEXTENSIONSEQUALSFAILED
);
628 if (cmpResult
!= PKIX_TRUE
){
629 *pResult
= PKIX_FALSE
;
633 cmpResult
= (firstCrlEntry
->userReasonCode
==
634 secondCrlEntry
->userReasonCode
);
636 *pResult
= cmpResult
;
640 PKIX_RETURN(CRLENTRY
);
644 * FUNCTION: pkix_pl_CRLEntry_RegisterSelf
646 * Registers PKIX_CRLEntry_TYPE and its related functions with systemClasses[]
648 * Not Thread Safe - for performance and complexity reasons
650 * Since this function is only called by PKIX_PL_Initialize, which should
651 * only be called once, it is acceptable that this function is not
655 pkix_pl_CRLEntry_RegisterSelf(void *plContext
)
658 extern pkix_ClassTable_Entry systemClasses
[PKIX_NUMTYPES
];
659 pkix_ClassTable_Entry entry
;
661 PKIX_ENTER(CRLENTRY
, "pkix_pl_CRLEntry_RegisterSelf");
663 entry
.description
= "CRLEntry";
664 entry
.objCounter
= 0;
665 entry
.typeObjectSize
= sizeof(PKIX_PL_CRLEntry
);
666 entry
.destructor
= pkix_pl_CRLEntry_Destroy
;
667 entry
.equalsFunction
= pkix_pl_CRLEntry_Equals
;
668 entry
.hashcodeFunction
= pkix_pl_CRLEntry_Hashcode
;
669 entry
.toStringFunction
= pkix_pl_CRLEntry_ToString
;
670 entry
.comparator
= NULL
;
671 entry
.duplicateFunction
= pkix_duplicateImmutable
;
673 systemClasses
[PKIX_CRLENTRY_TYPE
] = entry
;
675 PKIX_RETURN(CRLENTRY
);
679 * FUNCTION: pkix_pl_CRLEntry_CreateEntry
682 * Creates a new CRLEntry using the CertCrlEntry pointed to by "nssCrlEntry"
683 * and stores it at "pCrlEntry". Once created, a CRLEntry is immutable.
685 * revokedCertificates SEQUENCE OF SEQUENCE {
686 * userCertificate CertificateSerialNumber,
687 * revocationDate Time,
688 * crlEntryExtensions Extensions OPTIONAL
689 * -- if present, MUST be v2
693 * Address of CERTCrlEntry representing an NSS CRL entry.
696 * Address where object pointer will be stored. Must be non-NULL.
698 * Platform-specific context pointer.
700 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
702 * Returns NULL if the function succeeds.
703 * Returns a CRLEntry Error if the function fails in a non-fatal way.
704 * Returns a Fatal Error if the function fails in an unrecoverable way.
707 pkix_pl_CRLEntry_CreateEntry(
708 CERTCrlEntry
*nssCrlEntry
, /* entry data to be created from */
709 PKIX_PL_CRLEntry
**pCrlEntry
,
712 PKIX_PL_CRLEntry
*crlEntry
= NULL
;
714 PKIX_ENTER(CRLENTRY
, "pkix_pl_CRLEntry_CreateEntry");
715 PKIX_NULLCHECK_TWO(nssCrlEntry
, pCrlEntry
);
717 PKIX_CHECK(PKIX_PL_Object_Alloc
719 sizeof (PKIX_PL_CRLEntry
),
720 (PKIX_PL_Object
**)&crlEntry
,
722 PKIX_COULDNOTCREATECRLENTRYOBJECT
);
724 crlEntry
->nssCrlEntry
= nssCrlEntry
;
725 crlEntry
->serialNumber
= NULL
;
726 crlEntry
->critExtOids
= NULL
;
727 crlEntry
->userReasonCode
= 0;
728 crlEntry
->userReasonCodeAbsent
= PKIX_FALSE
;
730 *pCrlEntry
= crlEntry
;
734 PKIX_RETURN(CRLENTRY
);
738 * FUNCTION: pkix_pl_CRLEntry_Create
741 * Creates a List of CRLEntries using the array of CERTCrlEntries pointed to
742 * by "nssCrlEntries" and stores it at "pCrlEntryList". If "nssCrlEntries" is
743 * NULL, this function stores an empty List at "pCrlEntryList".
747 * Address of array of CERTCrlEntries representing NSS CRL entries.
748 * Can be NULL if CRL has no NSS CRL entries.
750 * Address where object pointer will be stored. Must be non-NULL.
752 * Platform-specific context pointer.
754 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
756 * Returns NULL if the function succeeds.
757 * Returns a CRLEntry Error if the function fails in a non-fatal way.
758 * Returns a Fatal Error if the function fails in an unrecoverable way.
761 pkix_pl_CRLEntry_Create(
762 CERTCrlEntry
**nssCrlEntries
, /* head of entry list */
763 PKIX_List
**pCrlEntryList
,
766 PKIX_List
*entryList
= NULL
;
767 PKIX_PL_CRLEntry
*crlEntry
= NULL
;
768 CERTCrlEntry
**entries
= NULL
;
769 SECItem serialNumberItem
;
770 PKIX_PL_BigInt
*serialNumber
;
774 PKIX_ENTER(CRLENTRY
, "pkix_pl_CRLEntry_Create");
775 PKIX_NULLCHECK_ONE(pCrlEntryList
);
777 entries
= nssCrlEntries
;
779 PKIX_CHECK(PKIX_List_Create(&entryList
, plContext
),
780 PKIX_LISTCREATEFAILED
);
784 PKIX_CHECK(pkix_pl_CRLEntry_CreateEntry
785 (*entries
, &crlEntry
, plContext
),
786 PKIX_COULDNOTCREATECRLENTRYOBJECT
);
788 /* Get Serial Number */
789 serialNumberItem
= (*entries
)->serialNumber
;
790 length
= serialNumberItem
.len
;
791 bytes
= (char *)serialNumberItem
.data
;
793 PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
794 (bytes
, length
, &serialNumber
, plContext
),
795 PKIX_BIGINTCREATEWITHBYTESFAILED
);
797 crlEntry
->serialNumber
= serialNumber
;
798 crlEntry
->nssCrlEntry
= *entries
;
800 PKIX_CHECK(PKIX_List_AppendItem
801 (entryList
, (PKIX_PL_Object
*)crlEntry
, plContext
),
802 PKIX_LISTAPPENDITEMFAILED
);
804 PKIX_DECREF(crlEntry
);
810 *pCrlEntryList
= entryList
;
813 PKIX_DECREF(crlEntry
);
815 if (PKIX_ERROR_RECEIVED
){
816 PKIX_DECREF(entryList
);
819 PKIX_RETURN(CRLENTRY
);
822 /* --Public-CRLENTRY-Functions------------------------------------- */
825 * FUNCTION: PKIX_PL_CRLEntry_GetCRLEntryReasonCode
826 * (see comments in pkix_pl_pki.h)
829 PKIX_PL_CRLEntry_GetCRLEntryReasonCode (
830 PKIX_PL_CRLEntry
*crlEntry
,
835 CERTCRLEntryReasonCode nssReasonCode
;
837 PKIX_ENTER(CRLENTRY
, "PKIX_PL_CRLEntry_GetCRLEntryReasonCode");
838 PKIX_NULLCHECK_TWO(crlEntry
, pReason
);
840 if (!crlEntry
->userReasonCodeAbsent
&& crlEntry
->userReasonCode
== 0) {
842 PKIX_OBJECT_LOCK(crlEntry
);
844 if (!crlEntry
->userReasonCodeAbsent
&&
845 crlEntry
->userReasonCode
== 0) {
847 /* reason code has not been cached in */
848 PKIX_CRLENTRY_DEBUG("\t\tCERT_FindCRLEntryReasonExten.\n");
849 status
= CERT_FindCRLEntryReasonExten
850 (crlEntry
->nssCrlEntry
, &nssReasonCode
);
852 if (status
== SECSuccess
) {
853 crlEntry
->userReasonCode
= (PKIX_Int32
) nssReasonCode
;
855 crlEntry
->userReasonCodeAbsent
= PKIX_TRUE
;
859 PKIX_OBJECT_UNLOCK(crlEntry
);
863 *pReason
= crlEntry
->userReasonCode
;
867 PKIX_RETURN(CRLENTRY
);
871 * FUNCTION: PKIX_PL_CRLEntry_GetCriticalExtensionOIDs
872 * (see comments in pkix_pl_pki.h)
875 PKIX_PL_CRLEntry_GetCriticalExtensionOIDs (
876 PKIX_PL_CRLEntry
*crlEntry
,
877 PKIX_List
**pList
, /* list of PKIX_PL_OID */
880 PKIX_List
*oidsList
= NULL
;
881 CERTCertExtension
**extensions
;
883 PKIX_ENTER(CRLENTRY
, "PKIX_PL_CRLEntry_GetCriticalExtensionOIDs");
884 PKIX_NULLCHECK_THREE(crlEntry
, crlEntry
->nssCrlEntry
, pList
);
886 /* if we don't have a cached copy from before, we create one */
887 if (crlEntry
->critExtOids
== NULL
) {
889 PKIX_OBJECT_LOCK(crlEntry
);
891 if (crlEntry
->critExtOids
== NULL
) {
893 extensions
= crlEntry
->nssCrlEntry
->extensions
;
895 PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
896 (extensions
, &oidsList
, plContext
),
897 PKIX_GETCRITICALEXTENSIONOIDSFAILED
);
899 crlEntry
->critExtOids
= oidsList
;
902 PKIX_OBJECT_UNLOCK(crlEntry
);
906 /* We should return a copy of the List since this list changes */
907 PKIX_DUPLICATE(crlEntry
->critExtOids
, pList
, plContext
,
908 PKIX_OBJECTDUPLICATELISTFAILED
);
912 PKIX_RETURN(CRLENTRY
);