Index: mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c |
=================================================================== |
--- mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c (revision 191424) |
+++ mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c (working copy) |
@@ -1,1068 +0,0 @@ |
-/* 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_crl.c |
- * |
- * CRL Function Definitions |
- * |
- */ |
- |
-#include "pkix_pl_crl.h" |
-#include "certxutl.h" |
- |
-extern PKIX_PL_HashTable *cachedCrlSigTable; |
- |
-/* --Private-CRL-Functions------------------------------------- */ |
- |
-/* |
- * FUNCTION: pkix_pl_CRL_GetVersion |
- * DESCRIPTION: |
- * |
- * Retrieves the version of the CRL pointed to by "crl" and stores it at |
- * "pVersion". The version number will either be 0 or 1 (corresponding to |
- * v1 or v2, respectively). |
- * |
- * Version ::= INTEGER { v1(0), v2(1), v3(2) } |
- * |
- * PARAMETERS: |
- * "crl" |
- * Address of CRL whose version is to be stored. Must be non-NULL. |
- * "pVersion" |
- * Address where a version 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 CRL 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_CRL_GetVersion( |
- PKIX_PL_CRL *crl, |
- PKIX_UInt32 *pVersion, |
- void *plContext) |
-{ |
- PKIX_UInt32 myVersion; |
- |
- PKIX_ENTER(CRL, "pkix_pl_CRL_GetVersion"); |
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pVersion); |
- |
- PKIX_NULLCHECK_ONE(crl->nssSignedCrl->crl.version.data); |
- |
- myVersion = *(crl->nssSignedCrl->crl.version.data); |
- |
- if (myVersion > 1) { |
- PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1ORV2); |
- } |
- |
- *pVersion = myVersion; |
- |
-cleanup: |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_CRL_GetCRLNumber (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_CRL_GetCRLNumber( |
- PKIX_PL_CRL *crl, |
- PKIX_PL_BigInt **pCrlNumber, |
- void *plContext) |
-{ |
- PKIX_PL_BigInt *crlNumber = NULL; |
- SECItem nssCrlNumber; |
- PLArenaPool *arena = NULL; |
- SECStatus status; |
- PKIX_UInt32 length = 0; |
- char *bytes = NULL; |
- |
- PKIX_ENTER(CRL, "PKIX_PL_CRL_GetCRLNumber"); |
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCrlNumber); |
- |
- /* Can call this function only with der been adopted. */ |
- PORT_Assert(crl->adoptedDerCrl); |
- |
- if (!crl->crlNumberAbsent && crl->crlNumber == NULL) { |
- |
- PKIX_OBJECT_LOCK(crl); |
- |
- if (!crl->crlNumberAbsent && crl->crlNumber == NULL) { |
- |
- nssCrlNumber.type = 0; |
- nssCrlNumber.len = 0; |
- nssCrlNumber.data = NULL; |
- |
- PKIX_CRL_DEBUG("\t\tCalling PORT_NewArena).\n"); |
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
- if (arena == NULL) { |
- PKIX_ERROR(PKIX_OUTOFMEMORY); |
- } |
- |
- PKIX_CRL_DEBUG("\t\tCalling CERT_FindCRLNumberExten\n"); |
- status = CERT_FindCRLNumberExten |
- (arena, &crl->nssSignedCrl->crl, &nssCrlNumber); |
- |
- if (status == SECSuccess) { |
- /* Get data in bytes then convert to bigint */ |
- length = nssCrlNumber.len; |
- bytes = (char *)nssCrlNumber.data; |
- |
- PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes |
- (bytes, length, &crlNumber, plContext), |
- PKIX_BIGINTCREATEWITHBYTESFAILED); |
- |
- /* arena release does the job |
- PKIX_CRL_DEBUG("\t\tCalling SECITEM_FreeItem\n"); |
- SECITEM_FreeItem(&nssCrlNumber, PKIX_FALSE); |
- */ |
- crl->crlNumber = crlNumber; |
- |
- } else { |
- |
- crl->crlNumberAbsent = PKIX_TRUE; |
- } |
- } |
- |
- PKIX_OBJECT_UNLOCK(crl); |
- |
- } |
- |
- PKIX_INCREF(crl->crlNumber); |
- |
- *pCrlNumber = crl->crlNumber; |
- |
-cleanup: |
- |
- if (arena){ |
- PKIX_CRL_DEBUG("\t\tCalling PORT_FreeArena).\n"); |
- PORT_FreeArena(arena, PR_FALSE); |
- } |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_CRL_GetSignatureAlgId |
- * |
- * DESCRIPTION: |
- * Retrieves a pointer to the OID that represents the signature algorithm of |
- * the CRL pointed to by "crl" and stores it at "pSignatureAlgId". |
- * |
- * AlgorithmIdentifier ::= SEQUENCE { |
- * algorithm OBJECT IDENTIFIER, |
- * parameters ANY DEFINED BY algorithm OPTIONAL } |
- * |
- * PARAMETERS: |
- * "crl" |
- * Address of CRL whose signature algorithm OID is to be stored. |
- * Must be non-NULL. |
- * "pSignatureAlgId" |
- * 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 CRL 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_CRL_GetSignatureAlgId( |
- PKIX_PL_CRL *crl, |
- PKIX_PL_OID **pSignatureAlgId, |
- void *plContext) |
-{ |
- PKIX_PL_OID *signatureAlgId = NULL; |
- |
- PKIX_ENTER(CRL, "pkix_pl_CRL_GetSignatureAlgId"); |
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pSignatureAlgId); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (crl->signatureAlgId == NULL){ |
- PKIX_OBJECT_LOCK(crl); |
- if (crl->signatureAlgId == NULL){ |
- CERTCrl *nssCrl = &(crl->nssSignedCrl->crl); |
- SECAlgorithmID *algorithm = &nssCrl->signatureAlg; |
- SECItem *algBytes = &algorithm->algorithm; |
- |
- if (!algBytes->data || !algBytes->len) { |
- PKIX_ERROR(PKIX_OIDBYTESLENGTH0); |
- } |
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem |
- (algBytes, &signatureAlgId, plContext), |
- PKIX_OIDCREATEFAILED); |
- |
- /* save a cached copy in case it is asked for again */ |
- crl->signatureAlgId = signatureAlgId; |
- signatureAlgId = NULL; |
- } |
- PKIX_OBJECT_UNLOCK(crl); |
- } |
- PKIX_INCREF(crl->signatureAlgId); |
- *pSignatureAlgId = crl->signatureAlgId; |
-cleanup: |
- PKIX_DECREF(signatureAlgId); |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_CRL_GetCRLEntries |
- * DESCRIPTION: |
- * |
- * Retrieves a pointer to the List of CRLEntries found in the CRL pointed to |
- * by "crl" and stores it at "pCRLEntries". If there are no CRLEntries, |
- * this functions stores NULL at "pCRLEntries". |
- * |
- * PARAMETERS: |
- * "crl" |
- * Address of CRL whose CRL Entries are to be retrieved. Must be non-NULL. |
- * "pCRLEntries" |
- * 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 CRL 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_CRL_GetCRLEntries( |
- PKIX_PL_CRL *crl, |
- PKIX_List **pCrlEntries, |
- void *plContext) |
-{ |
- PKIX_List *entryList = NULL; |
- CERTCrl *nssCrl = NULL; |
- |
- PKIX_ENTER(CRL, "pkix_pl_CRL_GetCRLEntries"); |
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCrlEntries); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (crl->crlEntryList == NULL) { |
- |
- PKIX_OBJECT_LOCK(crl); |
- |
- if (crl->crlEntryList == NULL){ |
- |
- nssCrl = &(crl->nssSignedCrl->crl); |
- |
- PKIX_CHECK(pkix_pl_CRLEntry_Create |
- (nssCrl->entries, &entryList, plContext), |
- PKIX_CRLENTRYCREATEFAILED); |
- |
- PKIX_CHECK(PKIX_List_SetImmutable |
- (entryList, plContext), |
- PKIX_LISTSETIMMUTABLEFAILED); |
- |
- crl->crlEntryList = entryList; |
- } |
- |
- PKIX_OBJECT_UNLOCK(crl); |
- |
- } |
- |
- PKIX_INCREF(crl->crlEntryList); |
- |
- *pCrlEntries = crl->crlEntryList; |
- |
-cleanup: |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_CRL_Destroy |
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_CRL_Destroy( |
- PKIX_PL_Object *object, |
- void *plContext) |
-{ |
- PKIX_PL_CRL *crl = NULL; |
- |
- PKIX_ENTER(CRL, "pkix_pl_CRL_Destroy"); |
- PKIX_NULLCHECK_ONE(object); |
- |
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext), |
- PKIX_OBJECTNOTCRL); |
- |
- crl = (PKIX_PL_CRL*)object; |
- |
- PKIX_CRL_DEBUG("\t\tCalling CERT_DestroyCrl\n"); |
- if (crl->nssSignedCrl) { |
- CERT_DestroyCrl(crl->nssSignedCrl); |
- } |
- if (crl->adoptedDerCrl) { |
- SECITEM_FreeItem(crl->adoptedDerCrl, PR_TRUE); |
- } |
- crl->nssSignedCrl = NULL; |
- crl->adoptedDerCrl = NULL; |
- crl->crlNumberAbsent = PKIX_FALSE; |
- |
- PKIX_DECREF(crl->issuer); |
- PKIX_DECREF(crl->signatureAlgId); |
- PKIX_DECREF(crl->crlNumber); |
- PKIX_DECREF(crl->crlEntryList); |
- PKIX_DECREF(crl->critExtOids); |
- if (crl->derGenName) { |
- SECITEM_FreeItem(crl->derGenName, PR_TRUE); |
- } |
- |
-cleanup: |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_CRL_ToString_Helper |
- * DESCRIPTION: |
- * |
- * Helper function that creates a string representation of the CRL pointed |
- * to by "crl" and stores it at "pString". |
- * |
- * PARAMETERS |
- * "crl" |
- * Address of CRL 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 CRL 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_CRL_ToString_Helper( |
- PKIX_PL_CRL *crl, |
- PKIX_PL_String **pString, |
- void *plContext) |
-{ |
- char *asciiFormat = NULL; |
- PKIX_UInt32 crlVersion; |
- PKIX_PL_X500Name *crlIssuer = NULL; |
- PKIX_PL_OID *nssSignatureAlgId = NULL; |
- PKIX_PL_BigInt *crlNumber = NULL; |
- PKIX_List *crlEntryList = NULL; |
- PKIX_List *critExtOIDs = NULL; |
- PKIX_PL_String *formatString = NULL; |
- PKIX_PL_String *crlIssuerString = NULL; |
- PKIX_PL_String *lastUpdateString = NULL; |
- PKIX_PL_String *nextUpdateString = NULL; |
- PKIX_PL_String *nssSignatureAlgIdString = NULL; |
- PKIX_PL_String *crlNumberString = NULL; |
- PKIX_PL_String *crlEntryListString = NULL; |
- PKIX_PL_String *critExtOIDsString = NULL; |
- PKIX_PL_String *crlString = NULL; |
- |
- PKIX_ENTER(CRL, "pkix_pl_CRL_ToString_Helper"); |
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pString); |
- |
- asciiFormat = |
- "[\n" |
- "\tVersion: v%d\n" |
- "\tIssuer: %s\n" |
- "\tUpdate: [Last: %s\n" |
- "\t Next: %s]\n" |
- "\tSignatureAlgId: %s\n" |
- "\tCRL Number : %s\n" |
- "\n" |
- "\tEntry List: %s\n" |
- "\n" |
- "\tCritExtOIDs: %s\n" |
- "]\n"; |
- |
- PKIX_CHECK(PKIX_PL_String_Create |
- (PKIX_ESCASCII, |
- asciiFormat, |
- 0, |
- &formatString, |
- plContext), |
- PKIX_STRINGCREATEFAILED); |
- |
- /* Version */ |
- PKIX_CHECK(pkix_pl_CRL_GetVersion(crl, &crlVersion, plContext), |
- PKIX_CRLGETVERSIONFAILED); |
- |
- /* Issuer */ |
- PKIX_CHECK(PKIX_PL_CRL_GetIssuer(crl, &crlIssuer, plContext), |
- PKIX_CRLGETISSUERFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Object_ToString |
- ((PKIX_PL_Object *)crlIssuer, &crlIssuerString, plContext), |
- PKIX_X500NAMETOSTRINGFAILED); |
- |
- /* This update - No Date object created, use nss data directly */ |
- PKIX_CHECK(pkix_pl_Date_ToString_Helper |
- (&(crl->nssSignedCrl->crl.lastUpdate), |
- &lastUpdateString, |
- plContext), |
- PKIX_DATETOSTRINGHELPERFAILED); |
- |
- /* Next update - No Date object created, use nss data directly */ |
- PKIX_CHECK(pkix_pl_Date_ToString_Helper |
- (&(crl->nssSignedCrl->crl.nextUpdate), |
- &nextUpdateString, |
- plContext), |
- PKIX_DATETOSTRINGHELPERFAILED); |
- |
- /* Signature Algorithm Id */ |
- PKIX_CHECK(pkix_pl_CRL_GetSignatureAlgId |
- (crl, &nssSignatureAlgId, plContext), |
- PKIX_CRLGETSIGNATUREALGIDFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Object_ToString |
- ((PKIX_PL_Object *)nssSignatureAlgId, |
- &nssSignatureAlgIdString, |
- plContext), |
- PKIX_OIDTOSTRINGFAILED); |
- |
- /* CRL Number */ |
- PKIX_CHECK(PKIX_PL_CRL_GetCRLNumber |
- (crl, &crlNumber, plContext), |
- PKIX_CRLGETCRLNUMBERFAILED); |
- |
- PKIX_TOSTRING(crlNumber, &crlNumberString, plContext, |
- PKIX_BIGINTTOSTRINGFAILED); |
- |
- /* CRL Entries */ |
- PKIX_CHECK(pkix_pl_CRL_GetCRLEntries(crl, &crlEntryList, plContext), |
- PKIX_CRLGETCRLENTRIESFAILED); |
- |
- PKIX_TOSTRING(crlEntryList, &crlEntryListString, plContext, |
- PKIX_LISTTOSTRINGFAILED); |
- |
- /* CriticalExtensionOIDs */ |
- PKIX_CHECK(PKIX_PL_CRL_GetCriticalExtensionOIDs |
- (crl, &critExtOIDs, plContext), |
- PKIX_CRLGETCRITICALEXTENSIONOIDSFAILED); |
- |
- PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext, |
- PKIX_LISTTOSTRINGFAILED); |
- |
- PKIX_CHECK(PKIX_PL_Sprintf |
- (&crlString, |
- plContext, |
- formatString, |
- crlVersion + 1, |
- crlIssuerString, |
- lastUpdateString, |
- nextUpdateString, |
- nssSignatureAlgIdString, |
- crlNumberString, |
- crlEntryListString, |
- critExtOIDsString), |
- PKIX_SPRINTFFAILED); |
- |
- *pString = crlString; |
- |
-cleanup: |
- |
- PKIX_DECREF(crlIssuer); |
- PKIX_DECREF(nssSignatureAlgId); |
- PKIX_DECREF(crlNumber); |
- PKIX_DECREF(crlEntryList); |
- PKIX_DECREF(critExtOIDs); |
- PKIX_DECREF(crlIssuerString); |
- PKIX_DECREF(lastUpdateString); |
- PKIX_DECREF(nextUpdateString); |
- PKIX_DECREF(nssSignatureAlgIdString); |
- PKIX_DECREF(crlNumberString); |
- PKIX_DECREF(crlEntryListString); |
- PKIX_DECREF(critExtOIDsString); |
- PKIX_DECREF(formatString); |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_CRL_ToString |
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_CRL_ToString( |
- PKIX_PL_Object *object, |
- PKIX_PL_String **pString, |
- void *plContext) |
-{ |
- PKIX_PL_String *crlString = NULL; |
- PKIX_PL_CRL *crl = NULL; |
- |
- PKIX_ENTER(CRL, "pkix_pl_CRL_ToString"); |
- PKIX_NULLCHECK_TWO(object, pString); |
- |
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext), |
- PKIX_OBJECTNOTCRL); |
- |
- crl = (PKIX_PL_CRL *) object; |
- |
- PKIX_CHECK(pkix_pl_CRL_ToString_Helper(crl, &crlString, plContext), |
- PKIX_CRLTOSTRINGHELPERFAILED); |
- |
- *pString = crlString; |
- |
-cleanup: |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_CRL_Hashcode |
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_CRL_Hashcode( |
- PKIX_PL_Object *object, |
- PKIX_UInt32 *pHashcode, |
- void *plContext) |
-{ |
- PKIX_PL_CRL *crl = NULL; |
- PKIX_UInt32 certHash; |
- SECItem *crlDer = NULL; |
- |
- PKIX_ENTER(CRL, "pkix_pl_CRL_Hashcode"); |
- PKIX_NULLCHECK_TWO(object, pHashcode); |
- |
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext), |
- PKIX_OBJECTNOTCRL); |
- |
- crl = (PKIX_PL_CRL *)object; |
- if (crl->adoptedDerCrl) { |
- crlDer = crl->adoptedDerCrl; |
- } else if (crl->nssSignedCrl && crl->nssSignedCrl->derCrl) { |
- crlDer = crl->nssSignedCrl->derCrl; |
- } |
- if (!crlDer || !crlDer->data) { |
- PKIX_ERROR(PKIX_CANNOTAQUIRECRLDER); |
- } |
- |
- PKIX_CHECK(pkix_hash(crlDer->data, crlDer->len, |
- &certHash, plContext), |
- PKIX_ERRORINHASH); |
- |
- *pHashcode = certHash; |
- |
-cleanup: |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_CRL_Equals |
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) |
- */ |
-static PKIX_Error * |
-pkix_pl_CRL_Equals( |
- PKIX_PL_Object *firstObject, |
- PKIX_PL_Object *secondObject, |
- PKIX_Boolean *pResult, |
- void *plContext) |
-{ |
- PKIX_PL_CRL *firstCrl = NULL; |
- PKIX_PL_CRL *secondCrl = NULL; |
- SECItem *crlDerOne = NULL, *crlDerTwo = NULL; |
- PKIX_UInt32 secondType; |
- |
- PKIX_ENTER(CRL, "pkix_pl_CRL_Equals"); |
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); |
- |
- /* test that firstObject is a CRL */ |
- PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CRL_TYPE, plContext), |
- PKIX_FIRSTOBJECTNOTCRL); |
- |
- firstCrl = (PKIX_PL_CRL *)firstObject; |
- secondCrl = (PKIX_PL_CRL *)secondObject; |
- |
- /* |
- * Since we know firstObject is a CRL, if both references are |
- * identical, they must be equal |
- */ |
- if (firstCrl == secondCrl){ |
- *pResult = PKIX_TRUE; |
- goto cleanup; |
- } |
- |
- /* |
- * If secondCrl isn't a CRL, 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 *)secondCrl, &secondType, plContext), |
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); |
- if (secondType != PKIX_CRL_TYPE) goto cleanup; |
- |
- if (firstCrl->adoptedDerCrl) { |
- crlDerOne = firstCrl->adoptedDerCrl; |
- } else if (firstCrl->nssSignedCrl && firstCrl->nssSignedCrl->derCrl) { |
- crlDerOne = firstCrl->nssSignedCrl->derCrl; |
- } |
- |
- if (secondCrl->adoptedDerCrl) { |
- crlDerTwo = secondCrl->adoptedDerCrl; |
- } else if (secondCrl->nssSignedCrl && secondCrl->nssSignedCrl->derCrl) { |
- crlDerTwo = secondCrl->nssSignedCrl->derCrl; |
- } |
- |
- if (SECITEM_CompareItem(crlDerOne, crlDerTwo) == SECEqual) { |
- *pResult = PKIX_TRUE; |
- } |
- |
-cleanup: |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_CRL_RegisterSelf |
- * |
- * DESCRIPTION: |
- * Registers PKIX_CRL_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_CRL_RegisterSelf(void *plContext) |
-{ |
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; |
- pkix_ClassTable_Entry *entry = &systemClasses[PKIX_CRL_TYPE]; |
- |
- PKIX_ENTER(CRL, "pkix_pl_CRL_RegisterSelf"); |
- |
- entry->description = "CRL"; |
- entry->typeObjectSize = sizeof(PKIX_PL_CRL); |
- entry->destructor = pkix_pl_CRL_Destroy; |
- entry->equalsFunction = pkix_pl_CRL_Equals; |
- entry->hashcodeFunction = pkix_pl_CRL_Hashcode; |
- entry->toStringFunction = pkix_pl_CRL_ToString; |
- entry->duplicateFunction = pkix_duplicateImmutable; |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_CRL_VerifyUpdateTime (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_CRL_VerifyUpdateTime( |
- PKIX_PL_CRL *crl, |
- PKIX_PL_Date *date, |
- PKIX_Boolean *pResult, |
- void *plContext) |
-{ |
- PRTime timeToCheck; |
- PRTime nextUpdate; |
- PRTime lastUpdate; |
- SECStatus status; |
- CERTCrl *nssCrl = NULL; |
- SECItem *nextUpdateDer = NULL; |
- PKIX_Boolean haveNextUpdate = PR_FALSE; |
- |
- PKIX_ENTER(CRL, "PKIX_PL_CRL_VerifyUpdateTime"); |
- PKIX_NULLCHECK_FOUR(crl, crl->nssSignedCrl, date, pResult); |
- |
- /* Can call this function only with der been adopted. */ |
- PORT_Assert(crl->adoptedDerCrl); |
- |
- nssCrl = &(crl->nssSignedCrl->crl); |
- timeToCheck = date->nssTime; |
- |
- /* nextUpdate can be NULL. Checking before using it */ |
- nextUpdateDer = &nssCrl->nextUpdate; |
- if (nextUpdateDer->data && nextUpdateDer->len) { |
- haveNextUpdate = PR_TRUE; |
- status = DER_DecodeTimeChoice(&nextUpdate, nextUpdateDer); |
- if (status != SECSuccess) { |
- PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORNEXTUPDATEFAILED); |
- } |
- } |
- |
- status = DER_DecodeTimeChoice(&lastUpdate, &(nssCrl->lastUpdate)); |
- if (status != SECSuccess) { |
- PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORLASTUPDATEFAILED); |
- } |
- |
- if (!haveNextUpdate || nextUpdate < timeToCheck) { |
- *pResult = PKIX_FALSE; |
- goto cleanup; |
- } |
- |
- if (lastUpdate <= timeToCheck) { |
- *pResult = PKIX_TRUE; |
- } else { |
- *pResult = PKIX_FALSE; |
- } |
- |
-cleanup: |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: pkix_pl_CRL_CreateWithSignedCRL |
- * DESCRIPTION: |
- * |
- * Creates a new CRL using the CERTSignedCrl pointed to by "nssSignedCrl" |
- * and stores it at "pCRL". If the decoding of the CERTSignedCrl fails, |
- * a PKIX_Error is returned. |
- * |
- * PARAMETERS: |
- * "nssSignedCrl" |
- * Address of CERTSignedCrl. Must be non-NULL. |
- * "adoptedDerCrl" |
- * SECItem ponter that if not NULL is indicating that memory used |
- * for der should be adopted by crl that is about to be created. |
- * "pCRL" |
- * 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 CRL 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_CRL_CreateWithSignedCRL( |
- CERTSignedCrl *nssSignedCrl, |
- SECItem *adoptedDerCrl, |
- SECItem *derGenName, |
- PKIX_PL_CRL **pCrl, |
- void *plContext) |
-{ |
- PKIX_PL_CRL *crl = NULL; |
- |
- PKIX_ENTER(CRL, "pkix_pl_CRL_CreateWithSignedCRL"); |
- PKIX_NULLCHECK_ONE(pCrl); |
- |
- /* create a PKIX_PL_CRL object */ |
- PKIX_CHECK(PKIX_PL_Object_Alloc |
- (PKIX_CRL_TYPE, |
- sizeof (PKIX_PL_CRL), |
- (PKIX_PL_Object **)&crl, |
- plContext), |
- PKIX_COULDNOTCREATECRLOBJECT); |
- |
- /* populate the nssSignedCrl field */ |
- crl->nssSignedCrl = nssSignedCrl; |
- crl->adoptedDerCrl = adoptedDerCrl; |
- crl->issuer = NULL; |
- crl->signatureAlgId = NULL; |
- crl->crlNumber = NULL; |
- crl->crlNumberAbsent = PKIX_FALSE; |
- crl->crlEntryList = NULL; |
- crl->critExtOids = NULL; |
- if (derGenName) { |
- crl->derGenName = |
- SECITEM_DupItem(derGenName); |
- if (!crl->derGenName) { |
- PKIX_ERROR(PKIX_ALLOCERROR); |
- } |
- } |
- |
- *pCrl = crl; |
- |
-cleanup: |
- |
- if (PKIX_ERROR_RECEIVED){ |
- PKIX_DECREF(crl); |
- } |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* --Public-CRL-Functions------------------------------------- */ |
- |
-/* |
- * FUNCTION: PKIX_PL_CRL_Create (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_CRL_Create( |
- PKIX_PL_ByteArray *byteArray, |
- PKIX_PL_CRL **pCrl, |
- void *plContext) |
-{ |
- CERTSignedCrl *nssSignedCrl = NULL; |
- SECItem derItem, *derCrl = NULL; |
- PKIX_PL_CRL *crl = NULL; |
- |
- PKIX_ENTER(CRL, "PKIX_PL_CRL_Create"); |
- PKIX_NULLCHECK_TWO(byteArray, pCrl); |
- |
- if (byteArray->length == 0){ |
- PKIX_ERROR(PKIX_ZEROLENGTHBYTEARRAYFORCRLENCODING); |
- } |
- derItem.type = siBuffer; |
- derItem.data = byteArray->array; |
- derItem.len = byteArray->length; |
- derCrl = SECITEM_DupItem(&derItem); |
- if (!derCrl) { |
- PKIX_ERROR(PKIX_ALLOCERROR); |
- } |
- nssSignedCrl = |
- CERT_DecodeDERCrlWithFlags(NULL, derCrl, SEC_CRL_TYPE, |
- CRL_DECODE_DONT_COPY_DER | |
- CRL_DECODE_SKIP_ENTRIES); |
- if (!nssSignedCrl) { |
- PKIX_ERROR(PKIX_CERTDECODEDERCRLFAILED); |
- } |
- PKIX_CHECK( |
- pkix_pl_CRL_CreateWithSignedCRL(nssSignedCrl, derCrl, NULL, |
- &crl, plContext), |
- PKIX_CRLCREATEWITHSIGNEDCRLFAILED); |
- nssSignedCrl = NULL; |
- derCrl = NULL; |
- *pCrl = crl; |
- |
-cleanup: |
- if (derCrl) { |
- SECITEM_FreeItem(derCrl, PR_TRUE); |
- } |
- if (nssSignedCrl) { |
- SEC_DestroyCrl(nssSignedCrl); |
- } |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_CRL_GetIssuer (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_CRL_GetIssuer( |
- PKIX_PL_CRL *crl, |
- PKIX_PL_X500Name **pCRLIssuer, |
- void *plContext) |
-{ |
- PKIX_PL_String *crlString = NULL; |
- PKIX_PL_X500Name *issuer = NULL; |
- SECItem *derIssuerName = NULL; |
- CERTName *issuerName = NULL; |
- |
- PKIX_ENTER(CRL, "PKIX_PL_CRL_GetIssuer"); |
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCRLIssuer); |
- |
- /* Can call this function only with der been adopted. */ |
- PORT_Assert(crl->adoptedDerCrl); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (crl->issuer == NULL){ |
- |
- PKIX_OBJECT_LOCK(crl); |
- |
- if (crl->issuer == NULL) { |
- |
- issuerName = &crl->nssSignedCrl->crl.name; |
- derIssuerName = &crl->nssSignedCrl->crl.derName; |
- |
- PKIX_CHECK( |
- PKIX_PL_X500Name_CreateFromCERTName(derIssuerName, |
- issuerName, |
- &issuer, |
- plContext), |
- PKIX_X500NAMECREATEFROMCERTNAMEFAILED); |
- |
- /* save a cached copy in case it is asked for again */ |
- crl->issuer = issuer; |
- } |
- |
- PKIX_OBJECT_UNLOCK(crl); |
- |
- } |
- |
- PKIX_INCREF(crl->issuer); |
- |
- *pCRLIssuer = crl->issuer; |
- |
-cleanup: |
- |
- PKIX_DECREF(crlString); |
- |
- PKIX_RETURN(CRL); |
-} |
- |
- |
-/* |
- * FUNCTION: PKIX_PL_CRL_GetCriticalExtensionOIDs |
- * (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_CRL_GetCriticalExtensionOIDs( |
- PKIX_PL_CRL *crl, |
- PKIX_List **pExtensions, /* list of PKIX_PL_OID */ |
- void *plContext) |
-{ |
- PKIX_List *oidsList = NULL; |
- CERTCertExtension **extensions = NULL; |
- CERTCrl *nssSignedCrl = NULL; |
- |
- PKIX_ENTER(CRL, "PKIX_PL_CRL_GetCriticalExtensionOIDs"); |
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pExtensions); |
- |
- /* Can call this function only with der been adopted. */ |
- PORT_Assert(crl->adoptedDerCrl); |
- |
- /* if we don't have a cached copy from before, we create one */ |
- if (crl->critExtOids == NULL) { |
- |
- PKIX_OBJECT_LOCK(crl); |
- |
- nssSignedCrl = &(crl->nssSignedCrl->crl); |
- extensions = nssSignedCrl->extensions; |
- |
- if (crl->critExtOids == NULL) { |
- |
- PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs |
- (extensions, &oidsList, plContext), |
- PKIX_GETCRITICALEXTENSIONOIDSFAILED); |
- |
- crl->critExtOids = oidsList; |
- } |
- |
- PKIX_OBJECT_UNLOCK(crl); |
- |
- } |
- |
- /* We should return a copy of the List since this list changes */ |
- PKIX_DUPLICATE(crl->critExtOids, pExtensions, plContext, |
- PKIX_OBJECTDUPLICATELISTFAILED); |
- |
-cleanup: |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-/* |
- * FUNCTION: PKIX_PL_CRL_VerifySignature (see comments in pkix_pl_pki.h) |
- */ |
-PKIX_Error * |
-PKIX_PL_CRL_VerifySignature( |
- PKIX_PL_CRL *crl, |
- PKIX_PL_PublicKey *pubKey, |
- void *plContext) |
-{ |
- PKIX_PL_CRL *cachedCrl = NULL; |
- PKIX_Error *verifySig = NULL; |
- PKIX_Error *cachedSig = NULL; |
- PKIX_Boolean crlEqual = PKIX_FALSE; |
- PKIX_Boolean crlInHash= PKIX_FALSE; |
- CERTSignedCrl *nssSignedCrl = NULL; |
- SECKEYPublicKey *nssPubKey = NULL; |
- CERTSignedData *tbsCrl = NULL; |
- void* wincx = NULL; |
- SECStatus status; |
- |
- PKIX_ENTER(CRL, "PKIX_PL_CRL_VerifySignature"); |
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pubKey); |
- |
- /* Can call this function only with der been adopted. */ |
- PORT_Assert(crl->adoptedDerCrl); |
- |
- verifySig = PKIX_PL_HashTable_Lookup |
- (cachedCrlSigTable, |
- (PKIX_PL_Object *) pubKey, |
- (PKIX_PL_Object **) &cachedCrl, |
- plContext); |
- |
- if (cachedCrl != NULL && verifySig == NULL) { |
- /* Cached Signature Table lookup succeed */ |
- PKIX_EQUALS(crl, cachedCrl, &crlEqual, plContext, |
- PKIX_OBJECTEQUALSFAILED); |
- if (crlEqual == PKIX_TRUE) { |
- goto cleanup; |
- } |
- /* Different PubKey may hash to same value, skip add */ |
- crlInHash = PKIX_TRUE; |
- } |
- |
- nssSignedCrl = crl->nssSignedCrl; |
- tbsCrl = &nssSignedCrl->signatureWrap; |
- |
- PKIX_CRL_DEBUG("\t\tCalling SECKEY_ExtractPublicKey\n"); |
- nssPubKey = SECKEY_ExtractPublicKey(pubKey->nssSPKI); |
- if (!nssPubKey){ |
- PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED); |
- } |
- |
- PKIX_CHECK(pkix_pl_NssContext_GetWincx |
- ((PKIX_PL_NssContext *)plContext, &wincx), |
- PKIX_NSSCONTEXTGETWINCXFAILED); |
- |
- PKIX_CRL_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey\n"); |
- status = CERT_VerifySignedDataWithPublicKey(tbsCrl, nssPubKey, wincx); |
- |
- if (status != SECSuccess) { |
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE); |
- PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHEPUBLICKEY); |
- } |
- |
- if (crlInHash == PKIX_FALSE) { |
- cachedSig = PKIX_PL_HashTable_Add |
- (cachedCrlSigTable, |
- (PKIX_PL_Object *) pubKey, |
- (PKIX_PL_Object *) crl, |
- plContext); |
- |
- if (cachedSig != NULL) { |
- PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed\n"); |
- } |
- } |
- |
-cleanup: |
- |
- if (nssPubKey){ |
- PKIX_CRL_DEBUG("\t\tCalling SECKEY_DestroyPublicKey\n"); |
- SECKEY_DestroyPublicKey(nssPubKey); |
- nssPubKey = NULL; |
- } |
- |
- PKIX_DECREF(cachedCrl); |
- PKIX_DECREF(verifySig); |
- PKIX_DECREF(cachedSig); |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-PKIX_Error* |
-PKIX_PL_CRL_ReleaseDerCrl(PKIX_PL_CRL *crl, |
- SECItem **derCrl, |
- void *plContext) |
-{ |
- PKIX_ENTER(CRL, "PKIX_PL_CRL_ReleaseDerCrl"); |
- *derCrl = crl->adoptedDerCrl; |
- crl->adoptedDerCrl = NULL; |
- |
- PKIX_RETURN(CRL); |
-} |
- |
-PKIX_Error* |
-PKIX_PL_CRL_AdoptDerCrl(PKIX_PL_CRL *crl, |
- SECItem *derCrl, |
- void *plContext) |
-{ |
- PKIX_ENTER(CRL, "PKIX_PL_CRL_AquireDerCrl"); |
- if (crl->adoptedDerCrl) { |
- PKIX_ERROR(PKIX_CANNOTAQUIRECRLDER); |
- } |
- crl->adoptedDerCrl = derCrl; |
-cleanup: |
- PKIX_RETURN(CRL); |
-} |