summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c')
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c880
1 files changed, 880 insertions, 0 deletions
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c
new file mode 100644
index 0000000000..e2b3e02688
--- /dev/null
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c
@@ -0,0 +1,880 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * pkix_pl_crlentry.c
+ *
+ * CRLENTRY Function Definitions
+ *
+ */
+
+#include "pkix_pl_crlentry.h"
+
+/* --Private-CRLEntry-Functions------------------------------------- */
+
+/*
+ * FUNCTION: pkix_pl_CRLEntry_Destroy
+ * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_pl_CRLEntry_Destroy(
+ PKIX_PL_Object *object,
+ void *plContext)
+{
+ PKIX_PL_CRLEntry *crlEntry = NULL;
+
+ PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Destroy");
+ PKIX_NULLCHECK_ONE(object);
+
+ PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext),
+ PKIX_OBJECTNOTCRLENTRY);
+
+ crlEntry = (PKIX_PL_CRLEntry*)object;
+
+ /* crlEntry->nssCrlEntry is freed by NSS when freeing CRL */
+ crlEntry->userReasonCode = 0;
+ crlEntry->userReasonCodeAbsent = PKIX_FALSE;
+ crlEntry->nssCrlEntry = NULL;
+ PKIX_DECREF(crlEntry->serialNumber);
+ PKIX_DECREF(crlEntry->critExtOids);
+
+cleanup:
+
+ PKIX_RETURN(CRLENTRY);
+}
+
+/*
+ * FUNCTION: pkix_pl_CRLEntry_ToString_Helper
+ *
+ * DESCRIPTION:
+ * Helper function that creates a string representation of the CRLEntry
+ * pointed to by "crlEntry" and stores it at "pString".
+ *
+ * PARAMETERS
+ * "crlEntry"
+ * Address of CRLEntry whose string representation is desired.
+ * Must be non-NULL.
+ * "pString"
+ * Address where object pointer will be stored. Must be non-NULL.
+ * "plContext"
+ * Platform-specific context pointer.
+ * THREAD SAFETY:
+ * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ * Returns NULL if the function succeeds.
+ * Returns a CRLEntry Error if the function fails in a non-fatal way.
+ * Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+pkix_pl_CRLEntry_ToString_Helper(
+ PKIX_PL_CRLEntry *crlEntry,
+ PKIX_PL_String **pString,
+ void *plContext)
+{
+ char *asciiFormat = NULL;
+ PKIX_List *critExtOIDs = NULL;
+ PKIX_PL_String *crlEntryString = NULL;
+ PKIX_PL_String *formatString = NULL;
+ PKIX_PL_String *crlSerialNumberString = NULL;
+ PKIX_PL_String *crlRevocationDateString = NULL;
+ PKIX_PL_String *critExtOIDsString = NULL;
+ PKIX_Int32 reasonCode = 0;
+
+ PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_ToString_Helper");
+ PKIX_NULLCHECK_FOUR
+ (crlEntry,
+ crlEntry->serialNumber,
+ crlEntry->nssCrlEntry,
+ pString);
+
+ asciiFormat =
+ "\n\t[\n"
+ "\tSerialNumber: %s\n"
+ "\tReasonCode: %d\n"
+ "\tRevocationDate: %s\n"
+ "\tCritExtOIDs: %s\n"
+ "\t]\n\t";
+
+ PKIX_CHECK(PKIX_PL_String_Create
+ (PKIX_ESCASCII,
+ asciiFormat,
+ 0,
+ &formatString,
+ plContext),
+ PKIX_STRINGCREATEFAILED);
+
+ /* SerialNumber */
+ PKIX_CHECK(PKIX_PL_Object_ToString
+ ((PKIX_PL_Object *)crlEntry->serialNumber,
+ &crlSerialNumberString,
+ plContext),
+ PKIX_BIGINTTOSTRINGHELPERFAILED);
+
+ /* RevocationDate - No Date object created, use nss data directly */
+ PKIX_CHECK(pkix_pl_Date_ToString_Helper
+ (&(crlEntry->nssCrlEntry->revocationDate),
+ &crlRevocationDateString,
+ plContext),
+ PKIX_DATETOSTRINGHELPERFAILED);
+
+ /* CriticalExtensionOIDs */
+ PKIX_CHECK(PKIX_PL_CRLEntry_GetCriticalExtensionOIDs
+ (crlEntry, &critExtOIDs, plContext),
+ PKIX_CRLENTRYGETCRITICALEXTENSIONOIDSFAILED);
+
+ PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext,
+ PKIX_LISTTOSTRINGFAILED);
+
+ /* Revocation Reason Code */
+ PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode
+ (crlEntry, &reasonCode, plContext),
+ PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED);
+
+ PKIX_CHECK(PKIX_PL_Sprintf
+ (&crlEntryString,
+ plContext,
+ formatString,
+ crlSerialNumberString,
+ reasonCode,
+ crlRevocationDateString,
+ critExtOIDsString),
+ PKIX_SPRINTFFAILED);
+
+ *pString = crlEntryString;
+
+cleanup:
+
+ PKIX_DECREF(critExtOIDs);
+ PKIX_DECREF(crlSerialNumberString);
+ PKIX_DECREF(crlRevocationDateString);
+ PKIX_DECREF(critExtOIDsString);
+ PKIX_DECREF(formatString);
+
+ PKIX_RETURN(CRLENTRY);
+}
+
+/*
+ * FUNCTION: pkix_pl_CRLEntry_ToString
+ * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_pl_CRLEntry_ToString(
+ PKIX_PL_Object *object,
+ PKIX_PL_String **pString,
+ void *plContext)
+{
+ PKIX_PL_String *crlEntryString = NULL;
+ PKIX_PL_CRLEntry *crlEntry = NULL;
+
+ PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_ToString");
+ PKIX_NULLCHECK_TWO(object, pString);
+
+ PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext),
+ PKIX_OBJECTNOTCRLENTRY);
+
+ crlEntry = (PKIX_PL_CRLEntry *) object;
+
+ PKIX_CHECK(pkix_pl_CRLEntry_ToString_Helper
+ (crlEntry, &crlEntryString, plContext),
+ PKIX_CRLENTRYTOSTRINGHELPERFAILED);
+
+ *pString = crlEntryString;
+
+cleanup:
+
+ PKIX_RETURN(CRLENTRY);
+}
+
+/*
+ * FUNCTION: pkix_pl_CRLEntry_Extensions_Hashcode
+ * DESCRIPTION:
+ *
+ * For each CRL Entry extension stored at NSS structure CERTCertExtension,
+ * get its derbyte data and do the hash.
+ *
+ * PARAMETERS
+ * "extensions"
+ * Address of arrray of CERTCertExtension whose hash value is desired.
+ * Must be non-NULL.
+ * "pHashValue"
+ * Address where the final hash value is returned. Must be non-NULL.
+ * "plContext"
+ * Platform-specific context pointer.
+ * THREAD SAFETY:
+ * Conditional Thread Safe
+ * Though the value of extensions once created is not supposed to change,
+ * it may be de-allocated while we are accessing it. But since we are
+ * validating the object, it is unlikely we or someone is de-allocating
+ * at the moment.
+ * RETURNS:
+ * Returns NULL if the function succeeds.
+ * Returns an OID Error if the function fails in a non-fatal way.
+ * Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_pl_CRLEntry_Extensions_Hashcode(
+ CERTCertExtension **extensions,
+ PKIX_UInt32 *pHashValue,
+ void *plContext)
+{
+ CERTCertExtension *extension = NULL;
+ PLArenaPool *arena = NULL;
+ PKIX_UInt32 extHash = 0;
+ PKIX_UInt32 hashValue = 0;
+ SECItem *derBytes = NULL;
+ SECItem *resultSecItem = NULL;
+
+ PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Extensions_Hashcode");
+ PKIX_NULLCHECK_TWO(extensions, pHashValue);
+
+ if (extensions) {
+
+ PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n");
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) {
+ PKIX_ERROR(PKIX_OUTOFMEMORY);
+ }
+
+ while (*extensions) {
+
+ extension = *extensions++;
+
+ PKIX_NULLCHECK_ONE(extension);
+
+ PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
+ derBytes = PORT_ArenaZNew(arena, SECItem);
+ if (derBytes == NULL) {
+ PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
+ }
+
+ PKIX_CRLENTRY_DEBUG
+ ("\t\tCalling SEC_ASN1EncodeItem\n");
+ resultSecItem = SEC_ASN1EncodeItem
+ (arena,
+ derBytes,
+ extension,
+ CERT_CertExtensionTemplate);
+
+ if (resultSecItem == NULL){
+ PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
+ }
+
+ PKIX_CHECK(pkix_hash
+ (derBytes->data,
+ derBytes->len,
+ &extHash,
+ plContext),
+ PKIX_HASHFAILED);
+
+ hashValue += (extHash << 7);
+
+ }
+ }
+
+ *pHashValue = hashValue;
+
+cleanup:
+
+ if (arena){
+ /* Note that freeing the arena also frees derBytes */
+ PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n");
+ PORT_FreeArena(arena, PR_FALSE);
+ arena = NULL;
+ }
+ PKIX_RETURN(CRLENTRY);
+}
+
+/*
+ * FUNCTION: pkix_pl_CRLEntry_Hashcode
+ * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_pl_CRLEntry_Hashcode(
+ PKIX_PL_Object *object,
+ PKIX_UInt32 *pHashcode,
+ void *plContext)
+{
+ SECItem *nssDate = NULL;
+ PKIX_PL_CRLEntry *crlEntry = NULL;
+ PKIX_UInt32 crlEntryHash;
+ PKIX_UInt32 hashValue;
+ PKIX_Int32 reasonCode = 0;
+
+ PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Hashcode");
+ PKIX_NULLCHECK_TWO(object, pHashcode);
+
+ PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext),
+ PKIX_OBJECTNOTCRLENTRY);
+
+ crlEntry = (PKIX_PL_CRLEntry *)object;
+
+ PKIX_NULLCHECK_ONE(crlEntry->nssCrlEntry);
+ nssDate = &(crlEntry->nssCrlEntry->revocationDate);
+
+ PKIX_NULLCHECK_ONE(nssDate->data);
+
+ PKIX_CHECK(pkix_hash
+ ((const unsigned char *)nssDate->data,
+ nssDate->len,
+ &crlEntryHash,
+ plContext),
+ PKIX_ERRORGETTINGHASHCODE);
+
+ PKIX_CHECK(PKIX_PL_Object_Hashcode
+ ((PKIX_PL_Object *)crlEntry->serialNumber,
+ &hashValue,
+ plContext),
+ PKIX_OBJECTHASHCODEFAILED);
+
+ crlEntryHash += (hashValue << 7);
+
+ hashValue = 0;
+
+ if (crlEntry->nssCrlEntry->extensions) {
+
+ PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Hashcode
+ (crlEntry->nssCrlEntry->extensions, &hashValue, plContext),
+ PKIX_CRLENTRYEXTENSIONSHASHCODEFAILED);
+ }
+
+ crlEntryHash += (hashValue << 7);
+
+ PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode
+ (crlEntry, &reasonCode, plContext),
+ PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED);
+
+ crlEntryHash += (reasonCode + 777) << 3;
+
+ *pHashcode = crlEntryHash;
+
+cleanup:
+
+ PKIX_RETURN(CRLENTRY);
+}
+
+/*
+ * FUNCTION: pkix_pl_CRLENTRY_Extensions_Equals
+ * DESCRIPTION:
+ *
+ * Compare each extension's DERbyte data in "firstExtensions" with extension
+ * in "secondExtensions" in sequential order and store the result in
+ * "pResult".
+ *
+ * PARAMETERS
+ * "firstExtensions"
+ * Address of first NSS structure CERTCertExtension to be compared.
+ * Must be non-NULL.
+ * "secondExtensions"
+ * Address of second NSS structure CERTCertExtension to be compared.
+ * Must be non-NULL.
+ * "pResult"
+ * Address where the comparison result is returned. Must be non-NULL.
+ * "plContext"
+ * Platform-specific context pointer.
+ * THREAD SAFETY:
+ * Conditionally Thread Safe
+ * Though the value of extensions once created is not supposed to change,
+ * it may be de-allocated while we are accessing it. But since we are
+ * validating the object, it is unlikely we or someone is de-allocating
+ * at the moment.
+ * RETURNS:
+ * Returns NULL if the function succeeds.
+ * Returns an OID Error if the function fails in a non-fatal way.
+ * Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_pl_CRLEntry_Extensions_Equals(
+ CERTCertExtension **extensions1,
+ CERTCertExtension **extensions2,
+ PKIX_Boolean *pResult,
+ void *plContext)
+{
+ CERTCertExtension **firstExtensions;
+ CERTCertExtension **secondExtensions;
+ CERTCertExtension *firstExtension = NULL;
+ CERTCertExtension *secondExtension = NULL;
+ PLArenaPool *arena = NULL;
+ PKIX_Boolean cmpResult = PKIX_FALSE;
+ SECItem *firstDerBytes = NULL;
+ SECItem *secondDerBytes = NULL;
+ SECItem *firstResultSecItem = NULL;
+ SECItem *secondResultSecItem = NULL;
+ PKIX_UInt32 firstNumExt = 0;
+ PKIX_UInt32 secondNumExt = 0;
+ SECComparison secResult;
+
+ PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Extensions_Equals");
+ PKIX_NULLCHECK_THREE(extensions1, extensions2, pResult);
+
+ firstExtensions = extensions1;
+ secondExtensions = extensions2;
+
+ if (firstExtensions) {
+ while (*firstExtensions) {
+ firstExtension = *firstExtensions++;
+ firstNumExt++;
+ }
+ }
+
+ if (secondExtensions) {
+ while (*secondExtensions) {
+ secondExtension = *secondExtensions++;
+ secondNumExt++;
+ }
+ }
+
+ if (firstNumExt != secondNumExt) {
+ *pResult = PKIX_FALSE;
+ goto cleanup;
+ }
+
+ if (firstNumExt == 0 && secondNumExt == 0) {
+ *pResult = PKIX_TRUE;
+ goto cleanup;
+ }
+
+ /* now have equal number, but non-zero extension items to compare */
+
+ firstExtensions = extensions1;
+ secondExtensions = extensions2;
+
+ cmpResult = PKIX_TRUE;
+
+ PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n");
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE*2);
+ if (arena == NULL) {
+ PKIX_ERROR(PKIX_OUTOFMEMORY);
+ }
+
+ while (firstNumExt--) {
+
+ firstExtension = *firstExtensions++;
+ secondExtension = *secondExtensions++;
+
+ PKIX_NULLCHECK_TWO(firstExtension, secondExtension);
+
+ PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
+ firstDerBytes = PORT_ArenaZNew(arena, SECItem);
+ if (firstDerBytes == NULL) {
+ PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
+ }
+
+ PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
+ secondDerBytes = PORT_ArenaZNew(arena, SECItem);
+ if (secondDerBytes == NULL) {
+ PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
+ }
+
+ PKIX_CRLENTRY_DEBUG
+ ("\t\tCalling SEC_ASN1EncodeItem\n");
+ firstResultSecItem = SEC_ASN1EncodeItem
+ (arena,
+ firstDerBytes,
+ firstExtension,
+ CERT_CertExtensionTemplate);
+
+ if (firstResultSecItem == NULL){
+ PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
+ }
+
+ PKIX_CRLENTRY_DEBUG
+ ("\t\tCalling SEC_ASN1EncodeItem\n");
+ secondResultSecItem = SEC_ASN1EncodeItem
+ (arena,
+ secondDerBytes,
+ secondExtension,
+ CERT_CertExtensionTemplate);
+
+ if (secondResultSecItem == NULL){
+ PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
+ }
+
+ PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
+ secResult = SECITEM_CompareItem
+ (firstResultSecItem, secondResultSecItem);
+
+ if (secResult != SECEqual) {
+ cmpResult = PKIX_FALSE;
+ break;
+ }
+
+ }
+
+ *pResult = cmpResult;
+
+cleanup:
+
+ if (arena){
+ /* Note that freeing the arena also frees derBytes */
+ PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n");
+ PORT_FreeArena(arena, PR_FALSE);
+ arena = NULL;
+ }
+
+ PKIX_RETURN(CRLENTRY);
+}
+
+/*
+ * FUNCTION: pkix_pl_CRLEntry_Equals
+ * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_pl_CRLEntry_Equals(
+ PKIX_PL_Object *firstObject,
+ PKIX_PL_Object *secondObject,
+ PKIX_Boolean *pResult,
+ void *plContext)
+{
+ PKIX_PL_CRLEntry *firstCrlEntry = NULL;
+ PKIX_PL_CRLEntry *secondCrlEntry = NULL;
+ PKIX_UInt32 secondType;
+ PKIX_Boolean cmpResult = PKIX_FALSE;
+
+ PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Equals");
+ PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
+
+ /* test that firstObject is a CRLEntry */
+ PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CRLENTRY_TYPE, plContext),
+ PKIX_FIRSTOBJECTNOTCRLENTRY);
+
+ firstCrlEntry = (PKIX_PL_CRLEntry *)firstObject;
+ secondCrlEntry = (PKIX_PL_CRLEntry *)secondObject;
+
+ PKIX_NULLCHECK_TWO
+ (firstCrlEntry->nssCrlEntry, secondCrlEntry->nssCrlEntry);
+
+ /*
+ * Since we know firstObject is a CRLEntry, if both references are
+ * identical, they must be equal
+ */
+ if (firstCrlEntry == secondCrlEntry){
+ *pResult = PKIX_TRUE;
+ goto cleanup;
+ }
+
+ /*
+ * If secondCrlEntry isn't a CRL Entry, we don't throw an error.
+ * We simply return a Boolean result of FALSE
+ */
+ *pResult = PKIX_FALSE;
+ PKIX_CHECK(PKIX_PL_Object_GetType
+ ((PKIX_PL_Object *)secondCrlEntry, &secondType, plContext),
+ PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
+ if (secondType != PKIX_CRLENTRY_TYPE) goto cleanup;
+
+ /* Compare userSerialNumber */
+ PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
+ if (SECITEM_CompareItem(
+ &(((PKIX_PL_CRLEntry *)firstCrlEntry)->nssCrlEntry->serialNumber),
+ &(((PKIX_PL_CRLEntry *)secondCrlEntry)->nssCrlEntry->serialNumber))
+ != SECEqual) {
+ *pResult = PKIX_FALSE;
+ goto cleanup;
+ }
+
+ /* Compare revocationDate */
+ PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
+ if (SECITEM_CompareItem
+ (&(((PKIX_PL_CRLEntry *)firstCrlEntry)->nssCrlEntry->
+ revocationDate),
+ &(((PKIX_PL_CRLEntry *)secondCrlEntry)->nssCrlEntry->
+ revocationDate))
+ != SECEqual) {
+ *pResult = PKIX_FALSE;
+ goto cleanup;
+ }
+
+ /* Compare Critical Extension List */
+ PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Equals
+ (firstCrlEntry->nssCrlEntry->extensions,
+ secondCrlEntry->nssCrlEntry->extensions,
+ &cmpResult,
+ plContext),
+ PKIX_CRLENTRYEXTENSIONSEQUALSFAILED);
+
+ if (cmpResult != PKIX_TRUE){
+ *pResult = PKIX_FALSE;
+ goto cleanup;
+ }
+
+ cmpResult = (firstCrlEntry->userReasonCode ==
+ secondCrlEntry->userReasonCode);
+
+ *pResult = cmpResult;
+
+cleanup:
+
+ PKIX_RETURN(CRLENTRY);
+}
+
+/*
+ * FUNCTION: pkix_pl_CRLEntry_RegisterSelf
+ * DESCRIPTION:
+ * Registers PKIX_CRLEntry_TYPE and its related functions with systemClasses[]
+ * THREAD SAFETY:
+ * Not Thread Safe - for performance and complexity reasons
+ *
+ * Since this function is only called by PKIX_PL_Initialize, which should
+ * only be called once, it is acceptable that this function is not
+ * thread-safe.
+ */
+PKIX_Error *
+pkix_pl_CRLEntry_RegisterSelf(void *plContext)
+{
+
+ extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
+ pkix_ClassTable_Entry entry;
+
+ PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_RegisterSelf");
+
+ entry.description = "CRLEntry";
+ entry.objCounter = 0;
+ entry.typeObjectSize = sizeof(PKIX_PL_CRLEntry);
+ entry.destructor = pkix_pl_CRLEntry_Destroy;
+ entry.equalsFunction = pkix_pl_CRLEntry_Equals;
+ entry.hashcodeFunction = pkix_pl_CRLEntry_Hashcode;
+ entry.toStringFunction = pkix_pl_CRLEntry_ToString;
+ entry.comparator = NULL;
+ entry.duplicateFunction = pkix_duplicateImmutable;
+
+ systemClasses[PKIX_CRLENTRY_TYPE] = entry;
+
+ PKIX_RETURN(CRLENTRY);
+}
+
+/*
+ * FUNCTION: pkix_pl_CRLEntry_CreateEntry
+ * DESCRIPTION:
+ *
+ * Creates a new CRLEntry using the CertCrlEntry pointed to by "nssCrlEntry"
+ * and stores it at "pCrlEntry". Once created, a CRLEntry is immutable.
+ *
+ * revokedCertificates SEQUENCE OF SEQUENCE {
+ * userCertificate CertificateSerialNumber,
+ * revocationDate Time,
+ * crlEntryExtensions Extensions OPTIONAL
+ * -- if present, MUST be v2
+ *
+ * PARAMETERS:
+ * "nssCrlEntry"
+ * Address of CERTCrlEntry representing an NSS CRL entry.
+ * Must be non-NULL.
+ * "pCrlEntry"
+ * Address where object pointer will be stored. Must be non-NULL.
+ * "plContext"
+ * Platform-specific context pointer.
+ * THREAD SAFETY:
+ * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ * Returns NULL if the function succeeds.
+ * Returns a CRLEntry Error if the function fails in a non-fatal way.
+ * Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_pl_CRLEntry_CreateEntry(
+ CERTCrlEntry *nssCrlEntry, /* entry data to be created from */
+ PKIX_PL_CRLEntry **pCrlEntry,
+ void *plContext)
+{
+ PKIX_PL_CRLEntry *crlEntry = NULL;
+
+ PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_CreateEntry");
+ PKIX_NULLCHECK_TWO(nssCrlEntry, pCrlEntry);
+
+ PKIX_CHECK(PKIX_PL_Object_Alloc
+ (PKIX_CRLENTRY_TYPE,
+ sizeof (PKIX_PL_CRLEntry),
+ (PKIX_PL_Object **)&crlEntry,
+ plContext),
+ PKIX_COULDNOTCREATECRLENTRYOBJECT);
+
+ crlEntry->nssCrlEntry = nssCrlEntry;
+ crlEntry->serialNumber = NULL;
+ crlEntry->critExtOids = NULL;
+ crlEntry->userReasonCode = 0;
+ crlEntry->userReasonCodeAbsent = PKIX_FALSE;
+
+ *pCrlEntry = crlEntry;
+
+cleanup:
+
+ PKIX_RETURN(CRLENTRY);
+}
+
+/*
+ * FUNCTION: pkix_pl_CRLEntry_Create
+ * DESCRIPTION:
+ *
+ * Creates a List of CRLEntries using the array of CERTCrlEntries pointed to
+ * by "nssCrlEntries" and stores it at "pCrlEntryList". If "nssCrlEntries" is
+ * NULL, this function stores an empty List at "pCrlEntryList".
+ * }
+ * PARAMETERS:
+ * "nssCrlEntries"
+ * Address of array of CERTCrlEntries representing NSS CRL entries.
+ * Can be NULL if CRL has no NSS CRL entries.
+ * "pCrlEntryList"
+ * Address where object pointer will be stored. Must be non-NULL.
+ * "plContext"
+ * Platform-specific context pointer.
+ * THREAD SAFETY:
+ * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ * Returns NULL if the function succeeds.
+ * Returns a CRLEntry Error if the function fails in a non-fatal way.
+ * Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+pkix_pl_CRLEntry_Create(
+ CERTCrlEntry **nssCrlEntries, /* head of entry list */
+ PKIX_List **pCrlEntryList,
+ void *plContext)
+{
+ PKIX_List *entryList = NULL;
+ PKIX_PL_CRLEntry *crlEntry = NULL;
+ CERTCrlEntry **entries = NULL;
+ SECItem serialNumberItem;
+ PKIX_PL_BigInt *serialNumber;
+ char *bytes = NULL;
+ PKIX_UInt32 length;
+
+ PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Create");
+ PKIX_NULLCHECK_ONE(pCrlEntryList);
+
+ entries = nssCrlEntries;
+
+ PKIX_CHECK(PKIX_List_Create(&entryList, plContext),
+ PKIX_LISTCREATEFAILED);
+
+ if (entries) {
+ while (*entries){
+ PKIX_CHECK(pkix_pl_CRLEntry_CreateEntry
+ (*entries, &crlEntry, plContext),
+ PKIX_COULDNOTCREATECRLENTRYOBJECT);
+
+ /* Get Serial Number */
+ serialNumberItem = (*entries)->serialNumber;
+ length = serialNumberItem.len;
+ bytes = (char *)serialNumberItem.data;
+
+ PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
+ (bytes, length, &serialNumber, plContext),
+ PKIX_BIGINTCREATEWITHBYTESFAILED);
+
+ crlEntry->serialNumber = serialNumber;
+ crlEntry->nssCrlEntry = *entries;
+
+ PKIX_CHECK(PKIX_List_AppendItem
+ (entryList, (PKIX_PL_Object *)crlEntry, plContext),
+ PKIX_LISTAPPENDITEMFAILED);
+
+ PKIX_DECREF(crlEntry);
+
+ entries++;
+ }
+ }
+
+ *pCrlEntryList = entryList;
+
+cleanup:
+ PKIX_DECREF(crlEntry);
+
+ if (PKIX_ERROR_RECEIVED){
+ PKIX_DECREF(entryList);
+ }
+
+ PKIX_RETURN(CRLENTRY);
+}
+
+/* --Public-CRLENTRY-Functions------------------------------------- */
+
+/*
+ * FUNCTION: PKIX_PL_CRLEntry_GetCRLEntryReasonCode
+ * (see comments in pkix_pl_pki.h)
+ */
+PKIX_Error *
+PKIX_PL_CRLEntry_GetCRLEntryReasonCode (
+ PKIX_PL_CRLEntry *crlEntry,
+ PKIX_Int32 *pReason,
+ void *plContext)
+{
+ SECStatus status;
+ CERTCRLEntryReasonCode nssReasonCode;
+
+ PKIX_ENTER(CRLENTRY, "PKIX_PL_CRLEntry_GetCRLEntryReasonCode");
+ PKIX_NULLCHECK_TWO(crlEntry, pReason);
+
+ if (!crlEntry->userReasonCodeAbsent && crlEntry->userReasonCode == 0) {
+
+ PKIX_OBJECT_LOCK(crlEntry);
+
+ if (!crlEntry->userReasonCodeAbsent &&
+ crlEntry->userReasonCode == 0) {
+
+ /* reason code has not been cached in */
+ PKIX_CRLENTRY_DEBUG("\t\tCERT_FindCRLEntryReasonExten.\n");
+ status = CERT_FindCRLEntryReasonExten
+ (crlEntry->nssCrlEntry, &nssReasonCode);
+
+ if (status == SECSuccess) {
+ crlEntry->userReasonCode = (PKIX_Int32) nssReasonCode;
+ } else {
+ crlEntry->userReasonCodeAbsent = PKIX_TRUE;
+ }
+ }
+
+ PKIX_OBJECT_UNLOCK(crlEntry);
+
+ }
+
+ *pReason = crlEntry->userReasonCode;
+
+cleanup:
+
+ PKIX_RETURN(CRLENTRY);
+}
+
+/*
+ * FUNCTION: PKIX_PL_CRLEntry_GetCriticalExtensionOIDs
+ * (see comments in pkix_pl_pki.h)
+ */
+PKIX_Error *
+PKIX_PL_CRLEntry_GetCriticalExtensionOIDs (
+ PKIX_PL_CRLEntry *crlEntry,
+ PKIX_List **pList, /* list of PKIX_PL_OID */
+ void *plContext)
+{
+ PKIX_List *oidsList = NULL;
+ CERTCertExtension **extensions;
+
+ PKIX_ENTER(CRLENTRY, "PKIX_PL_CRLEntry_GetCriticalExtensionOIDs");
+ PKIX_NULLCHECK_THREE(crlEntry, crlEntry->nssCrlEntry, pList);
+
+ /* if we don't have a cached copy from before, we create one */
+ if (crlEntry->critExtOids == NULL) {
+
+ PKIX_OBJECT_LOCK(crlEntry);
+
+ if (crlEntry->critExtOids == NULL) {
+
+ extensions = crlEntry->nssCrlEntry->extensions;
+
+ PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
+ (extensions, &oidsList, plContext),
+ PKIX_GETCRITICALEXTENSIONOIDSFAILED);
+
+ crlEntry->critExtOids = oidsList;
+ }
+
+ PKIX_OBJECT_UNLOCK(crlEntry);
+
+ }
+
+ /* We should return a copy of the List since this list changes */
+ PKIX_DUPLICATE(crlEntry->critExtOids, pList, plContext,
+ PKIX_OBJECTDUPLICATELISTFAILED);
+
+cleanup:
+
+ PKIX_RETURN(CRLENTRY);
+}