390502 - libpkix fails cert validation when no valid CRL (NIST validation policy is always enforced). r=nelson
authoralexei.volkov.bugs%sun.com
Wed, 05 Sep 2007 23:22:29 +0000
changeset 8035 19622fc52fc4c64eac6f333d8abaa1cea2c14ddb
parent 8034 3075d4504837a1478b889103da5bfdd577f93bb1
child 8036 f3682f2e22305a7f0b2cc5898af6abeed491d986
push idunknown
push userunknown
push dateunknown
reviewersnelson
bugs390502
390502 - libpkix fails cert validation when no valid CRL (NIST validation policy is always enforced). r=nelson
security/nss/lib/certhigh/certvfypkix.c
security/nss/lib/libpkix/include/pkix_crlsel.h
security/nss/lib/libpkix/include/pkix_errorstrings.h
security/nss/lib/libpkix/include/pkix_params.h
security/nss/lib/libpkix/include/pkix_pl_pki.h
security/nss/lib/libpkix/pkix/checker/pkix_defaultrevchecker.c
security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.c
security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.h
security/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.c
security/nss/lib/libpkix/pkix/params/pkix_procparams.c
security/nss/lib/libpkix/pkix/params/pkix_procparams.h
security/nss/lib/libpkix/pkix/top/pkix_build.c
security/nss/lib/libpkix/pkix/top/pkix_defaultcrlchecker.c
security/nss/lib/libpkix/pkix/top/pkix_defaultcrlchecker.h
security/nss/lib/libpkix/pkix/top/pkix_validate.c
security/nss/lib/libpkix/pkix/util/pkix_tools.c
security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c
--- a/security/nss/lib/certhigh/certvfypkix.c
+++ b/security/nss/lib/certhigh/certvfypkix.c
@@ -555,24 +555,21 @@ cert_CreatePkixProcessingParams(
     PKIX_CHECK(
         PKIX_PL_Date_CreateFromPRTime(time, &date, plContext),
         PKIX_DATECREATEFROMPRTIMEFAILED);
 
     PKIX_CHECK(
         PKIX_ProcessingParams_SetDate(procParams, date, plContext),
         PKIX_PROCESSINGPARAMSSETDATEFAILED);
     
-#ifdef PKIX_NOTDEF
-    /* Code will be enabled with integration of a patch for bug 390502 */
     PKIX_CHECK(
         PKIX_ProcessingParams_SetNISTRevocationPolicyEnabled(procParams,
                                                              PKIX_FALSE,
                                                              plContext),
         PKIX_PROCESSINGPARAMSSETNISTREVOCATIONENABLEDFAILED);
-#endif /* PKIX_NOTDEF */
 
     PKIX_CHECK(
         PKIX_ProcessingParams_SetAnyPolicyInhibited(procParams, PR_FALSE,
                                                     plContext),
         PKIX_PROCESSINGPARAMSSETANYPOLICYINHIBITED);
 
     PKIX_CHECK(
         PKIX_ProcessingParams_SetExplicitPolicyRequired(procParams, PR_FALSE,
--- a/security/nss/lib/libpkix/include/pkix_crlsel.h
+++ b/security/nss/lib/libpkix/include/pkix_crlsel.h
@@ -554,16 +554,79 @@ PKIX_ComCRLSelParams_GetDateAndTime(
  *  Returns a Fatal Error if the function fails in an unrecoverable way.
  */
 PKIX_Error *
 PKIX_ComCRLSelParams_SetDateAndTime(
         PKIX_ComCRLSelParams *params,
         PKIX_PL_Date *date,
         void *plContext);
 
+/* 
+ * FUNCTION: PKIX_ComCRLSelParams_GetNISTPolicyEnabled
+ * DESCRIPTION:
+ *
+ *  Retrieves a pointer to the Boolean representing the NIST CRL policy
+ *  activation flag that is set in the ComCRLSelParams pointed to by "params"
+ *  and stores it at "enabled". If enabled, a CRL must have nextUpdate field.
+ *
+ *  Default value for this flag is TRUE.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCRLSelParams whose NIST CRL policy criterion  is to
+ *      be stored. Must be non-NULL.
+ *  "pEnabled"
+ *      Address where object pointer will be stored. Must be non-NULL.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CRLSelector 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_ComCRLSelParams_GetNISTPolicyEnabled(
+        PKIX_ComCRLSelParams *params,
+        PKIX_Boolean *pEnabled,
+        void *plContext);
+
+/*
+ * FUNCTION: PKIX_ComCRLSelParams_SetNISTPolicyEnabled
+ * DESCRIPTION:
+ *
+ *  Sets the NIST crl policy criterion of the ComCRLSelParams pointed to by
+ *  "params" using a "enabled" flag. In order to match against this
+ *  criterion, a CRL's nextUpdate must be available and criterion's
+ *  dataAndTime must be within thisUpdate and nextUpdate time period.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ComCRLSelParamsParams whose NIST CRL policy criterion
+ *      is to be set. Must be non-NULL.
+ *  "enabled"
+ *      Address of Bollean used to set the criterion
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Not Thread Safe - assumes exclusive access to "params"
+ *  (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CRLSelector 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_ComCRLSelParams_SetNISTPolicyEnabled(
+        PKIX_ComCRLSelParams *params,
+        PKIX_Boolean enabled,
+        void *plContext);
+
 /*
  * FUNCTION: PKIX_ComCRLSelParams_GetMaxCRLNumber
  * DESCRIPTION:
  *
  *  Retrieves a pointer to the BigInt (if any) representing the maxCRLNumber
  *  criterion that is set in the ComCRLSelParams pointed to by "params" and
  *  stores it at "pNumber". In order to match against this criterion, a CRL
  *  must have a CRL number extension whose value is less than or equal to the
--- a/security/nss/lib/libpkix/include/pkix_errorstrings.h
+++ b/security/nss/lib/libpkix/include/pkix_errorstrings.h
@@ -896,17 +896,17 @@ PKIX_ERRORENTRY(PROCESSINGPARAMSGETCERTC
 PKIX_ERRORENTRY(PROCESSINGPARAMSGETCERTSTORESFAILED,PKIX_ProcessingParams_GetCertStores failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSGETDATEFAILED,PKIX_ProcessingParams_GetDate failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSGETHINTCERTSFAILED,PKIX_ProcessingParams_GetHintCerts failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSGETINITIALPOLICIESFAILED,PKIX_ProcessingParams_GetInitialPolicies failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSGETPOLICYQUALIFIERSREJECTEDFAILED,PKIX_ProcessingParams_GetPolicyQualifiersRejected failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSGETRESOURCELIMITSFAILED,PKIX_ProcessingParams_GetResourceLimits failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSGETREVOCATIONCHECKERSFAILED,PKIX_ProcessingParams_GetRevocationCheckers failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSGETREVOCATIONENABLEDFAILED,PKIX_ProcessingParams_GetRevocationEnabled failed),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETNISTREVOCATIONPOLICYENABLEDFAILED,pkix_ProcessingParams_GetNISTRevocationPolicyEnabled failed),
+PKIX_ERRORENTRY(PROCESSINGPARAMSGETNISTREVPOLICYENABLEDFAILED,pkix_ProcessingParams_GetNISTRevocationPolicyEnabled failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED,PKIX_ProcessingParams_GetTargetCertConstraints failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSGETTRUSTANCHORSFAILED,PKIX_ProcessingParams_GetTrustAnchors failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSISANYPOLICYINHIBITEDFAILED,PKIX_ProcessingParams_IsAnyPolicyInhibited failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSISEXPLICITPOLICYREQUIREDFAILED,PKIX_ProcessingParams_IsExplicitPolicyRequired failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSISPOLICYMAPPINGINHIBITEDFAILED,PKIX_ProcessingParams_IsPolicyMappingInhibited failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSSETANYPOLICYINHIBITED,PKIX_ProcessingParams_SetAnyPolicyInhibited failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSSETCERTSTORESFAILED,PKIX_ProcessingParams_SetCertStores failed),
 PKIX_ERRORENTRY(PROCESSINGPARAMSSETDATEFAILED,PKIX_ProcessingParams_SetDate failed),
--- a/security/nss/lib/libpkix/include/pkix_params.h
+++ b/security/nss/lib/libpkix/include/pkix_params.h
@@ -1067,16 +1067,78 @@ PKIX_ProcessingParams_IsCRLRevocationChe
  *  Returns a Fatal Error if the function fails in an unrecoverable way.
  */
 PKIX_Error *
 PKIX_ProcessingParams_SetRevocationEnabled(
         PKIX_ProcessingParams *params,
         PKIX_Boolean enabled,
         void *plContext);
 
+/*
+ * FUNCTION: PKIX_ProcessingParams_IsNISTRevocationPolicyEnabled
+ * DESCRIPTION:
+ *
+ *  Checks whether the ProcessingParams pointed to by "params" indicate that
+ *  CRL revocation checking is enabled and revocation is done according to NIST
+ *  CRL policy which states that a valid CRL with nextUpdate field must be
+ *  available for certificate revocation checking.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ProcessingParams used to determine whether or not NIST CRL
+ *      revocation policy is enabled. Must be non-NULL.
+ *  "pEnabled"
+ *      Address where Boolean will be stored. Must be non-NULL.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *      (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a Params 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_ProcessingParams_IsNISTRevocationPolicyEnabled(
+        PKIX_ProcessingParams *params,
+        PKIX_Boolean *pEnabled,
+        void *plContext);
+
+/*
+ * FUNCTION: PKIX_ProcessingParams_SetNISTRevocationPolicyEnabled
+ * DESCRIPTION:
+ *
+ *  Specifies in the ProcessingParams pointed to by "params" whether NIST CRL
+ *  revocation checking is enabled using the Boolean value of "enabled".
+ *  (See PKIX_ProcessingParams_IsNISTRevocationPolicyEnabled function
+ *  description)
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ProcessingParams to be set. Must be non-NULL.
+ *  "enabled"
+ *      Boolean value indicating whether nist CRL revocation checking is to
+ *      be enabled.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Not Thread Safe - assumes exclusive access to "params"
+ *  (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a Params 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_ProcessingParams_SetNISTRevocationPolicyEnabled(
+        PKIX_ProcessingParams *params,
+        PKIX_Boolean enabled,
+        void *plContext);
+
 
 /* PKIX_ValidateParams
  *
  * PKIX_ValidateParams consists of a ProcessingParams object as well as the
  * List of Certs (certChain) that the caller is trying to validate.
  */
 
 /*
--- a/security/nss/lib/libpkix/include/pkix_pl_pki.h
+++ b/security/nss/lib/libpkix/include/pkix_pl_pki.h
@@ -2022,17 +2022,17 @@ PKIX_PL_CRL_GetCRLNumber(
         void *plContext);
 
 /*
  * FUNCTION: PKIX_PL_CRL_VerifyUpdateTime
  * DESCRIPTION:
  *
  *  Checks whether the CRL pointed to by "crl" would be valid at the time
  *  represented by the Date pointed to by "date" and stores the Boolean result
- *  at "pResult".
+ *  at "pResult". This check is done only when NIST policy is enforced.
  *
  *  Time ::= CHOICE {
  *      utcTime         UTCTime,
  *      generalTime     GeneralizedTime }
  *
  * PARAMETERS:
  *  "crl"
  *      Address of CRL whose validity is to be checked. Must be non-NULL.
--- a/security/nss/lib/libpkix/pkix/checker/pkix_defaultrevchecker.c
+++ b/security/nss/lib/libpkix/pkix/checker/pkix_defaultrevchecker.c
@@ -255,21 +255,30 @@ pkix_DefaultRevChecker_Check(
         *pNBIOContext = 0;
         *pReasonCode = 0;
 
         /*
          * If we haven't yet created a defaultCrlChecker to do the actual work,
          * create one now.
          */
         if (defaultRevChecker->certChainChecker == NULL) {
+                PKIX_Boolean nistCRLPolicyEnabled = PR_TRUE;
+                if (procParams) {
+                    PKIX_CHECK(
+                        pkix_ProcessingParams_GetNISTRevocationPolicyEnabled
+                        (procParams, &nistCRLPolicyEnabled, plContext),
+                        PKIX_PROCESSINGPARAMSGETNISTREVPOLICYENABLEDFAILED);
+                }
+
                 PKIX_CHECK(pkix_DefaultCRLChecker_Initialize
                         (defaultRevChecker->certStores,
                         defaultRevChecker->testDate,
                         defaultRevChecker->trustedPubKey,
                         defaultRevChecker->certsRemaining,
+                        nistCRLPolicyEnabled,
                         &crlChecker,
                         plContext),
                         PKIX_DEFAULTCRLCHECKERINITIALIZEFAILED);
 
                 PKIX_CHECK(PKIX_CertChainChecker_GetCheckCallback
                         (crlChecker, &check, plContext),
                         PKIX_CERTCHAINCHECKERGETCHECKCALLBACKFAILED);
 
--- a/security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.c
+++ b/security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.c
@@ -482,16 +482,17 @@ PKIX_ComCRLSelParams_Create(
                     (PKIX_PL_Object **)&params,
                     plContext),
                     PKIX_COULDNOTCREATECOMMONCRLSELECTORPARAMSOBJECT);
 
         /* initialize fields */
         params->issuerNames = NULL;
         params->cert = NULL;
         params->date = NULL;
+        params->nistPolicyEnabled = PKIX_TRUE;
         params->maxCRLNumber = NULL;
         params->minCRLNumber = NULL;
 
         *pParams = params;
 
 cleanup:
 
         PKIX_RETURN(COMCRLSELPARAMS);
@@ -676,16 +677,57 @@ PKIX_ComCRLSelParams_SetDateAndTime(
                     ((PKIX_PL_Object *)params, plContext),
                     PKIX_OBJECTINVALIDATECACHEFAILED);
 
 cleanup:
 
         PKIX_RETURN(COMCRLSELPARAMS);
 }
 
+/*
+ * FUNCTION: PKIX_ComCRLSelParams_GetDateAndTime (see comments in pkix_crlsel.h)
+ */
+PKIX_Error *
+PKIX_ComCRLSelParams_GetNISTPolicyEnabled(
+        PKIX_ComCRLSelParams *params,
+        PKIX_Boolean *pEnabled,
+        void *plContext)
+{
+        PKIX_ENTER(COMCRLSELPARAMS,
+                    "PKIX_ComCRLSelParams_GetNISTPolicyEnabled");
+        PKIX_NULLCHECK_TWO(params, pEnabled);
+
+        *pEnabled = params->nistPolicyEnabled;
+
+        PKIX_RETURN(COMCRLSELPARAMS);
+}
+
+/*
+ * FUNCTION: PKIX_ComCRLSelParams_SetDateAndTime (see comments in pkix_crlsel.h)
+ */
+PKIX_Error *
+PKIX_ComCRLSelParams_SetNISTPolicyEnabled(
+        PKIX_ComCRLSelParams *params,
+        PKIX_Boolean enabled,
+        void *plContext)
+{
+        PKIX_ENTER(COMCRLSELPARAMS,
+                    "PKIX_ComCRLSelParams_SetNISTPolicyEnabled");
+        PKIX_NULLCHECK_ONE(params); /* allows date to be NULL from spec */
+
+        params->nistPolicyEnabled = enabled;
+
+        PKIX_CHECK(PKIX_PL_Object_InvalidateCache
+                    ((PKIX_PL_Object *)params, plContext),
+                    PKIX_OBJECTINVALIDATECACHEFAILED);
+
+cleanup:
+
+        PKIX_RETURN(COMCRLSELPARAMS);
+}
 
 /*
  * FUNCTION: PKIX_ComCRLSelParams_GetMaxCRLNumber
  * (see comments in pkix_crlsel.h)
  */
 PKIX_Error *
 PKIX_ComCRLSelParams_GetMaxCRLNumber(
         PKIX_ComCRLSelParams *params,
--- a/security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.h
+++ b/security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.h
@@ -49,16 +49,17 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 struct PKIX_ComCRLSelParamsStruct {
         PKIX_List *issuerNames; /* list of PKIX_PL_X500Name */
         PKIX_PL_Cert *cert; /* certificate being checked */
         PKIX_PL_Date *date;
+        PKIX_Boolean nistPolicyEnabled;
         PKIX_PL_BigInt *maxCRLNumber;
         PKIX_PL_BigInt *minCRLNumber;
 };
 
 /* see source file for function documentation */
 
 PKIX_Error *pkix_ComCRLSelParams_RegisterSelf(void *plContext);
 
--- a/security/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.c
+++ b/security/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.c
@@ -398,30 +398,31 @@ cleanup:
  *  Returns NULL if the function succeeds.
  *  Returns a CRLSelector 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_CRLSelector_DefaultMatch(
         PKIX_CRLSelector *selector,
         PKIX_PL_CRL *crl,
-	PKIX_Boolean *pMatch,
+        PKIX_Boolean *pMatch,
         void *plContext)
 {
         PKIX_ComCRLSelParams *params = NULL;
         PKIX_PL_X500Name *crlIssuerName = NULL;
         PKIX_PL_X500Name *issuerName = NULL;
         PKIX_List *selIssuerNames = NULL;
         PKIX_PL_Date *selDate = NULL;
         PKIX_Boolean result = PKIX_TRUE;
         PKIX_UInt32 numIssuers = 0;
         PKIX_UInt32 i;
         PKIX_PL_BigInt *minCRLNumber = NULL;
         PKIX_PL_BigInt *maxCRLNumber = NULL;
         PKIX_PL_BigInt *crlNumber = NULL;
+        PKIX_Boolean nistPolicyEnabled = PKIX_FALSE;
 
         PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_DefaultMatch");
         PKIX_NULLCHECK_TWO(selector, crl);
 
         *pMatch = PKIX_TRUE;
         params = selector->params;
 
         /* No matching parameter provided, just a match */
@@ -479,26 +480,32 @@ pkix_CRLSelector_DefaultMatch(
 
         PKIX_CHECK(PKIX_ComCRLSelParams_GetDateAndTime
                     (params, &selDate, plContext),
                     PKIX_COMCRLSELPARAMSGETDATEANDTIMEFAILED);
 
         /* Check for Date */
         if (selDate != NULL){
 
-                result = PKIX_FALSE;
+                PKIX_CHECK(PKIX_ComCRLSelParams_GetNISTPolicyEnabled
+                            (params, &nistPolicyEnabled, plContext),
+                           PKIX_COMCRLSELPARAMSGETNISTPOLICYENABLEDFAILED);
 
-                PKIX_CHECK(PKIX_PL_CRL_VerifyUpdateTime
-                            (crl, selDate, &result, plContext),
-                            PKIX_CRLVERIFYUPDATETIMEFAILED);
-
-                if (result == PKIX_FALSE) {
-                        PKIX_CRLSELECTOR_DEBUG("DateAndTime match Failed\n");
-                        *pMatch = PKIX_FALSE;
-                        goto cleanup;
+                /* check crl dates only for if NIST policies enforced */
+                if (nistPolicyEnabled) {
+                        result = PKIX_FALSE;
+                    
+                        PKIX_CHECK(PKIX_PL_CRL_VerifyUpdateTime
+                                   (crl, selDate, &result, plContext),
+                                   PKIX_CRLVERIFYUPDATETIMEFAILED);
+                    
+                        if (result == PKIX_FALSE) {
+                                *pMatch = PKIX_FALSE;
+                                goto cleanup;
+                        }
                 }
 
         }
 
         /* Check for CRL number in range */
         PKIX_CHECK(PKIX_PL_CRL_GetCRLNumber(crl, &crlNumber, plContext),
                     PKIX_CRLGETCRLNUMBERFAILED);
 
--- a/security/nss/lib/libpkix/pkix/params/pkix_procparams.c
+++ b/security/nss/lib/libpkix/pkix/params/pkix_procparams.c
@@ -118,16 +118,20 @@ pkix_ProcessingParams_Equals(
             (secondProcParams->qualifiersRejected)) {
                 goto cleanup;
         }
 
         if (firstProcParams->isCrlRevocationCheckingEnabled !=
             secondProcParams->isCrlRevocationCheckingEnabled) {
                 goto cleanup;
         }
+        if (firstProcParams->isCrlRevocationCheckingEnabledWithNISTPolicy !=
+            secondProcParams->isCrlRevocationCheckingEnabledWithNISTPolicy) {
+                goto cleanup;
+        }
 
         /* trustAnchors can never be NULL */
 
         PKIX_EQUALS
                 (firstProcParams->trustAnchors,
                 secondProcParams->trustAnchors,
                 &cmpResult,
                 plContext,
@@ -260,17 +264,18 @@ pkix_ProcessingParams_Hashcode(
                 plContext,
                 PKIX_OBJECTHASHCODEFAILED);
 
         hash = (31 * ((31 * anchorsHash) + hintCertsHash + dateHash)) +
                 constraintsHash + initialHash + rejectedHash;
 
         hash += ((((certStoresHash + resourceLimitsHash) << 7) +
                 certChainCheckersHash + revCheckersHash +
-                procParams->isCrlRevocationCheckingEnabled) << 7);
+                procParams->isCrlRevocationCheckingEnabled +
+                procParams->isCrlRevocationCheckingEnabledWithNISTPolicy) << 7);
 
         *pHashcode = hash;
 
 cleanup:
 
         PKIX_RETURN(PROCESSINGPARAMS);
 }
 
@@ -370,17 +375,18 @@ pkix_ProcessingParams_ToString(
                 formatString,
                 anchorsString,
                 dateString,
                 constraintsString,
                 InitialPoliciesString,
                 qualsRejectedString,
                 certStoresString,
                 resourceLimitsString,
-                procParams->isCrlRevocationCheckingEnabled),
+                procParams->isCrlRevocationCheckingEnabled,
+                procParams->isCrlRevocationCheckingEnabledWithNISTPolicy),
                 PKIX_SPRINTFFAILED);
 
         *pString = procParamsString;
 
 cleanup:
 
         PKIX_DECREF(formatString);
         PKIX_DECREF(anchorsString);
@@ -478,16 +484,19 @@ pkix_ProcessingParams_Duplicate(
                 (params->resourceLimits,
                 &(paramsDuplicate->resourceLimits),
                 plContext,
                 PKIX_OBJECTDUPLICATEFAILED);
 
         paramsDuplicate->isCrlRevocationCheckingEnabled =
                 params->isCrlRevocationCheckingEnabled;
 
+        paramsDuplicate->isCrlRevocationCheckingEnabledWithNISTPolicy =
+                params->isCrlRevocationCheckingEnabledWithNISTPolicy;
+
         *pNewObject = (PKIX_PL_Object *)paramsDuplicate;
 
 cleanup:
 
         if (PKIX_ERROR_RECEIVED){
                 PKIX_DECREF(paramsDuplicate);
         }
 
@@ -565,22 +574,20 @@ PKIX_ProcessingParams_Create(
         params->initialAnyPolicyInhibit = PKIX_FALSE;
         params->initialExplicitPolicy = PKIX_FALSE;
         params->qualifiersRejected = PKIX_FALSE;
         params->certChainCheckers = NULL;
         params->revCheckers = NULL;
         params->certStores = NULL;
         params->resourceLimits = NULL;
 
-        /*
-         * XXX CRL checking should be enabled as default, but before
-         * we encorporate CRL in all our tests, take it as disable for now
-         */
         params->isCrlRevocationCheckingEnabled = PKIX_TRUE;
 
+        params->isCrlRevocationCheckingEnabledWithNISTPolicy = PKIX_TRUE;
+
         *pParams = params;
 
 cleanup:
 
         if (PKIX_ERROR_RECEIVED){
                 PKIX_DECREF(params);
         }
 
@@ -1184,26 +1191,114 @@ cleanup:
 PKIX_Error *
 pkix_ProcessingParams_GetRevocationEnabled(
         PKIX_ProcessingParams *params,
         PKIX_Boolean *pEnabled,
         void *plContext)
 {
 
         PKIX_ENTER(PROCESSINGPARAMS,
-                    "PKIX_ProcessingParams_GetRevocationEnabled");
+                    "pkix_ProcessingParams_GetRevocationEnabled");
 
         PKIX_NULLCHECK_TWO(params, pEnabled);
 
         *pEnabled = params->isCrlRevocationCheckingEnabled;
 
         PKIX_RETURN(PROCESSINGPARAMS);
 }
 
 /*
+ * FUNCTION: PKIX_ProcessingParams_IsNISTRevocationPolicyEnabled
+ * (see comments in pkix_params.h)
+ */
+PKIX_Error *
+PKIX_ProcessingParams_IsNISTRevocationPolicyEnabled(
+        PKIX_ProcessingParams *params,
+        PKIX_Boolean *pEnabled,
+        void *plContext)
+{
+
+        PKIX_ENTER(PROCESSINGPARAMS,
+                    "PKIX_ProcessingParams_IsNISTRevocationPolicyEnabled");
+        PKIX_NULLCHECK_TWO(params, pEnabled);
+
+        *pEnabled = params->isCrlRevocationCheckingEnabledWithNISTPolicy;
+
+        PKIX_RETURN(PROCESSINGPARAMS);
+}
+
+/*
+ * FUNCTION: PKIX_ProcessingParams_SetNISTRevocationPolicyEnabled
+ * (see comments in pkix_params.h)
+ */
+PKIX_Error *
+PKIX_ProcessingParams_SetNISTRevocationPolicyEnabled(
+        PKIX_ProcessingParams *params,
+        PKIX_Boolean enabled,
+        void *plContext)
+{
+
+        PKIX_ENTER(PROCESSINGPARAMS,
+                    "PKIX_ProcessingParams_SetNISTRevocationPolicyEnabled");
+        PKIX_NULLCHECK_ONE(params);
+
+        params->isCrlRevocationCheckingEnabledWithNISTPolicy = enabled;
+
+        PKIX_CHECK(PKIX_PL_Object_InvalidateCache
+                    ((PKIX_PL_Object *)params, plContext),
+                    PKIX_OBJECTINVALIDATECACHEFAILED);
+
+cleanup:
+
+        PKIX_RETURN(PROCESSINGPARAMS);
+}
+
+/*
+ * FUNCTION: pkix_ProcessingParams_GetNISTRevocationPolicyEnabled
+ *
+ * DESCRIPTION:
+ *  Retrieves the boolean value from the ProcessingParams pointed to by
+ *  "params", and stores the result at "pEnable". The value indicates
+ *  whether Revocation Checking should be performed according to nist
+ *  revocation policy.
+ *
+ * PARAMETERS:
+ *  "params"
+ *      Address of ProcessingParams whose revocationEnabledWithNistPolicy
+ *      flag is to be retrieved. Must be non-NULL.
+ *  "pEnable"
+ *      Address where Boolean value 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 Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+pkix_ProcessingParams_GetNISTRevocationPolicyEnabled(
+        PKIX_ProcessingParams *params,
+        PKIX_Boolean *pEnabled,
+        void *plContext)
+{
+
+        PKIX_ENTER(PROCESSINGPARAMS,
+                    "pkix_ProcessingParams_GetNISTRevocationPolicyEnabled");
+
+        PKIX_NULLCHECK_TWO(params, pEnabled);
+
+        *pEnabled = params->isCrlRevocationCheckingEnabledWithNISTPolicy;
+
+        PKIX_RETURN(PROCESSINGPARAMS);
+}
+
+/*
  * FUNCTION: PKIX_ProcessingParams_SetResourceLimits
  * (see comments in pkix_params.h)
  */
 PKIX_Error *
 PKIX_ProcessingParams_SetResourceLimits(
         PKIX_ProcessingParams *params,
         PKIX_ResourceLimits *resourceLimits,
         void *plContext)
--- a/security/nss/lib/libpkix/pkix/params/pkix_procparams.h
+++ b/security/nss/lib/libpkix/pkix/params/pkix_procparams.h
@@ -48,38 +48,45 @@
 
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 struct PKIX_ProcessingParamsStruct {
         PKIX_List *trustAnchors;        /* Never NULL */
-	PKIX_List *hintCerts;	/* user-supplied partial chain, may be NULL */
+        PKIX_List *hintCerts;	/* user-supplied partial chain, may be NULL */
         PKIX_CertSelector *constraints;
         PKIX_PL_Date *date;
         PKIX_List *initialPolicies;     /* list of PKIX_PL_OID */
         PKIX_Boolean initialPolicyMappingInhibit;
         PKIX_Boolean initialAnyPolicyInhibit;
         PKIX_Boolean initialExplicitPolicy;
         PKIX_Boolean qualifiersRejected;
         PKIX_List *certChainCheckers;
         PKIX_List *revCheckers;
         PKIX_List *certStores;
         PKIX_Boolean isCrlRevocationCheckingEnabled;
+        PKIX_Boolean isCrlRevocationCheckingEnabledWithNISTPolicy;
         PKIX_ResourceLimits *resourceLimits;
 };
 
 /* see source file for function documentation */
 
 PKIX_Error *pkix_ProcessingParams_RegisterSelf(void *plContext);
 
 PKIX_Error *
 pkix_ProcessingParams_GetRevocationEnabled(
         PKIX_ProcessingParams *params,
         PKIX_Boolean *pEnabled,
         void *plContext);
 
+PKIX_Error *
+pkix_ProcessingParams_GetNISTRevocationPolicyEnabled(
+        PKIX_ProcessingParams *params,
+        PKIX_Boolean *pEnabled,
+        void *plContext);
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* _PKIX_PROCESSINGPARAMS_H */
--- a/security/nss/lib/libpkix/pkix/top/pkix_build.c
+++ b/security/nss/lib/libpkix/pkix/top/pkix_build.c
@@ -3596,16 +3596,17 @@ pkix_Build_InitiateBuildChain(
         void *plContext)
 {
         PKIX_UInt32 numAnchors = 0;
         PKIX_UInt32 numCertStores = 0;
         PKIX_UInt32 numHintCerts = 0;
         PKIX_UInt32 i = 0;
         PKIX_Boolean dsaParamsNeeded = PKIX_FALSE;
         PKIX_Boolean isCrlEnabled = PKIX_FALSE;
+        PKIX_Boolean nistCRLPolicyEnabled = PKIX_TRUE;
         PKIX_Boolean cacheHit = PKIX_FALSE;
         PKIX_Boolean trusted = PKIX_FALSE;
         PKIX_Boolean isDuplicate = PKIX_FALSE;
         PKIX_PL_Cert *trustedCert = NULL;
         PKIX_CertSelector *targetConstraints = NULL;
         PKIX_ComCertSelParams *targetParams = NULL;
         PKIX_List *anchors = NULL;
         PKIX_List *targetSubjNames = NULL;
@@ -3781,16 +3782,22 @@ pkix_Build_InitiateBuildChain(
                             PKIX_CERTCHECKVALIDITYFAILED];
                     goto cleanup;
             }
     
             PKIX_CHECK(pkix_ProcessingParams_GetRevocationEnabled
                     (procParams, &isCrlEnabled, plContext),
                     PKIX_PROCESSINGPARAMSGETREVOCATIONENABLEDFAILED);
     
+            PKIX_CHECK(
+                pkix_ProcessingParams_GetNISTRevocationPolicyEnabled
+                (procParams, &nistCRLPolicyEnabled, plContext),
+                PKIX_PROCESSINGPARAMSGETNISTREVPOLICYENABLEDFAILED);
+
+
             PKIX_CHECK(PKIX_ProcessingParams_GetCertStores
                     (procParams, &certStores, plContext),
                     PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
     
             PKIX_CHECK(PKIX_List_GetLength
                     (certStores, &numCertStores, plContext),
                     PKIX_LISTGETLENGTHFAILED);
     
@@ -3831,16 +3838,17 @@ pkix_Build_InitiateBuildChain(
     
             if (isCrlEnabled) {
                     if (numCertStores > 0) {
                             PKIX_CHECK(pkix_DefaultCRLChecker_Initialize
                                     (certStores,
                                     testDate,
                                     NULL,
                                     0,
+                                    nistCRLPolicyEnabled,
                                     &crlChecker,
                                     plContext),
                                     PKIX_DEFAULTCRLCHECKERINITIALIZEFAILED);
                     } else {
                         PKIX_ERROR(PKIX_CANTENABLEREVOCATIONWITHOUTCERTSTORE);
                     }
             }
     
--- a/security/nss/lib/libpkix/pkix/top/pkix_defaultcrlchecker.c
+++ b/security/nss/lib/libpkix/pkix/top/pkix_defaultcrlchecker.c
@@ -149,16 +149,18 @@ pkix_DefaultCRLCheckerState_RegisterSelf
  *      Address of CertStore List to be stored in state. Must be non-NULL.
  *  "testDate"
  *      Address of PKIX_PL_Date to be checked. May be NULL.
  *  "trustedPubKey"
  *      Trusted Anchor Public Key for verifying first Cert in the chain.
  *      Must be non-NULL.
  *  "certsRemaining"
  *      Number of certificates remaining in the chain.
+ *  "nistCRLPolicyEnabled"
+ *      If enabled, enforce nist crl policy.
  *  "pCheckerState"
  *      Address of DefaultCRLCheckerState that is returned. Must be non-NULL.
  *  "plContext"
  *      Platform-specific context pointer.
  *
  * THREAD SAFETY:
  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  *
@@ -169,16 +171,17 @@ pkix_DefaultCRLCheckerState_RegisterSelf
  *  Returns a Fatal Error
  */
 static PKIX_Error *
 pkix_DefaultCRLCheckerState_Create(
     PKIX_List *certStores,
     PKIX_PL_Date *testDate,
     PKIX_PL_PublicKey *trustedPubKey,
     PKIX_UInt32 certsRemaining,
+    PKIX_Boolean nistCRLPolicyEnabled,
     pkix_DefaultCRLCheckerState **pCheckerState,
     void *plContext)
 {
         pkix_DefaultCRLCheckerState *state = NULL;
 
         PKIX_ENTER(DEFAULTCRLCHECKERSTATE,
                     "pkix_DefaultCRLCheckerState_Create");
         PKIX_NULLCHECK_TWO(certStores, pCheckerState);
@@ -197,16 +200,17 @@ pkix_DefaultCRLCheckerState_Create(
 
         PKIX_INCREF(testDate);
         state->testDate = testDate;
 
         PKIX_INCREF(trustedPubKey);
         state->prevPublicKey = trustedPubKey;
 
         state->certHasValidCrl = PKIX_FALSE;
+        state->nistCRLPolicyEnabled = nistCRLPolicyEnabled;
         state->prevCertCrlSign = PKIX_TRUE;
         state->prevPublicKeyList = NULL;
         state->reasonCodeMask = 0;
         state->certsRemaining = certsRemaining;
 
         PKIX_CHECK(PKIX_PL_OID_Create
                     (PKIX_CRLREASONCODE_OID,
                     &state->crlReasonCodeOID,
@@ -560,16 +564,20 @@ pkix_DefaultCRLChecker_Check_SetSelector
         PKIX_CHECK(PKIX_ComCRLSelParams_AddIssuerName
                 (comCrlSelParams, certIssuer, plContext),
                 PKIX_COMCRLSELPARAMSADDISSUERNAMEFAILED);
 
         PKIX_CHECK(PKIX_ComCRLSelParams_SetDateAndTime
                 (comCrlSelParams, nowDate, plContext),
                 PKIX_COMCRLSELPARAMSSETDATEANDTIMEFAILED);
 
+        PKIX_CHECK(PKIX_ComCRLSelParams_SetNISTPolicyEnabled
+                (comCrlSelParams, state->nistCRLPolicyEnabled, plContext),
+                PKIX_COMCERTSELPARAMSSETNISTPOLICYENABLEDFAILED);
+
         PKIX_CHECK(PKIX_CRLSelector_Create
                 (NULL,
                 NULL, /* never used? (PKIX_PL_Object *)checker, */
                 &crlSelector,
                 plContext),
                 PKIX_CRLSELECTORCREATEFAILED);
 
         PKIX_CHECK(PKIX_CRLSelector_SetCommonCRLSelectorParams
@@ -859,17 +867,17 @@ pkix_DefaultCRLChecker_Check_Helper(
         PKIX_Boolean useOnlyLocal,
         void **pNBIOContext,
         void *plContext)
 {
 
         void *nbioContext = NULL;
         PKIX_Boolean certStoreCanBeUsed = PKIX_FALSE;
         PKIX_CertStore *certStore = NULL;
-	PKIX_Error *storeError = NULL;
+        PKIX_Error *storeError = NULL;
 
         PKIX_ENTER(CERTCHAINCHECKER, "pkix_DefaultCRLChecker_Check_Helper");
         PKIX_NULLCHECK_THREE(checker, cert, state);
 
         nbioContext = *pNBIOContext;
         *pNBIOContext = NULL; /* prepare for Error exit */
 
         while ((state->crlStoreIndex) < (state->numCrlStores)) {
@@ -921,18 +929,19 @@ pkix_DefaultCRLChecker_Check_Helper(
                                 goto cleanup;
                         }
                 }
 
                 PKIX_DECREF(certStore);
                 state->crlStoreIndex++;
         } /* while ((state->crlStoreIndex) < (state->numCrlStores)) */
 
-        if (state->certHasValidCrl == PKIX_FALSE) {
-                PKIX_ERROR(PKIX_CERTIFICATEDOESNTHAVEVALIDCRL);
+        if (state->nistCRLPolicyEnabled != PKIX_FALSE &&
+            state->certHasValidCrl == PKIX_FALSE) {
+            PKIX_ERROR(PKIX_CERTIFICATEDOESNTHAVEVALIDCRL);
         }
 
 cleanup:
 
         PKIX_DECREF(certStore);
 
         PKIX_RETURN(CERTCHAINCHECKER);
 }
@@ -1122,16 +1131,18 @@ cleanup:
  *  "certStores"
  *      Address of CertStore List to be stored in state. Must be non-NULL.
  *  "testDate"
  *      Address of PKIX_PL_Date to be checked. May be NULL.
  *  "trustedPubKey"
  *      Address of Public Key of Trust Anchor. Must be non-NULL.
  *  "certsRemaining"
  *      Number of certificates remaining in the chain.
+ *  "nistPolicyEnabled"
+ *      Enable NIST crl policy.
  *  "pChecker"
  *      Address where object pointer will be stored. Must be non-NULL.
  *      Must be non-NULL.
  *  "plContext"
  *      Platform-specific context pointer.
  *
  * THREAD SAFETY:
  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
@@ -1142,29 +1153,31 @@ cleanup:
  *  Returns a Fatal Error
  */
 PKIX_Error *
 pkix_DefaultCRLChecker_Initialize(
         PKIX_List *certStores,
         PKIX_PL_Date *testDate,
         PKIX_PL_PublicKey *trustedPubKey,
         PKIX_UInt32 certsRemaining,
+        PKIX_Boolean nistPolicyEnabled,
         PKIX_CertChainChecker **pChecker,
         void *plContext)
 {
         pkix_DefaultCRLCheckerState *state = NULL;
 
         PKIX_ENTER(CERTCHAINCHECKER, "pkix_DefaultCRLChecker_Initialize");
         PKIX_NULLCHECK_TWO(certStores, pChecker);
 
         PKIX_CHECK(pkix_DefaultCRLCheckerState_Create
                     (certStores,
                     testDate,
                     trustedPubKey,
                     certsRemaining,
+                    nistPolicyEnabled, 
                     &state,
                     plContext),
                     PKIX_DEFAULTCRLCHECKERSTATECREATEFAILED);
 
         PKIX_CHECK(PKIX_CertChainChecker_Create
                     (pkix_DefaultCRLChecker_Check,
                     PKIX_FALSE,
                     PKIX_FALSE,
--- a/security/nss/lib/libpkix/pkix/top/pkix_defaultcrlchecker.h
+++ b/security/nss/lib/libpkix/pkix/top/pkix_defaultcrlchecker.h
@@ -51,16 +51,17 @@ extern "C" {
 #endif
 
 typedef struct pkix_DefaultCRLCheckerState pkix_DefaultCRLCheckerState;
 
 struct pkix_DefaultCRLCheckerState {
         PKIX_List *certStores; /* list of CertStore */
         PKIX_PL_Date *testDate;
         PKIX_Boolean certHasValidCrl;
+        PKIX_Boolean nistCRLPolicyEnabled;
         PKIX_Boolean prevCertCrlSign;
         PKIX_PL_PublicKey *prevPublicKey; /* Subject PubKey of last cert */
         PKIX_List *prevPublicKeyList; /* of PKIX_PL_PublicKey */
         PKIX_UInt32 reasonCodeMask;
         PKIX_UInt32 certsRemaining;
         PKIX_PL_OID *crlReasonCodeOID;
 
         PKIX_PL_X500Name *certIssuer;
@@ -71,16 +72,17 @@ struct pkix_DefaultCRLCheckerState {
 };
 
 PKIX_Error *
 pkix_DefaultCRLChecker_Initialize(
         PKIX_List *certStores,
         PKIX_PL_Date *testDate,
         PKIX_PL_PublicKey *trustedPubKey,
         PKIX_UInt32 certsRemaining,
+        PKIX_Boolean nistCRLPolicyEnabled,
         PKIX_CertChainChecker **pChecker,
         void *plContext);
 
 PKIX_Error *
 pkix_DefaultCRLChecker_Check_Helper(
         PKIX_CertChainChecker *checker,
         PKIX_PL_Cert *cert,
         PKIX_PL_PublicKey *prevPublicKey,
--- a/security/nss/lib/libpkix/pkix/top/pkix_validate.c
+++ b/security/nss/lib/libpkix/pkix/top/pkix_validate.c
@@ -597,22 +597,29 @@ pkix_InitializeCheckers(
 
         if (isCrlEnabled) {
 
                 PKIX_CHECK(PKIX_List_GetLength
                     (certStores, &numCertStores, plContext),
                     PKIX_LISTGETLENGTHFAILED);
 
                 if (numCertStores > 0) {
+                        PKIX_Boolean nistCRLPolicyEnabled = PR_TRUE;
+
+                        PKIX_CHECK(
+                        pkix_ProcessingParams_GetNISTRevocationPolicyEnabled
+                        (procParams, &nistCRLPolicyEnabled, plContext),
+                        PKIX_PROCESSINGPARAMSGETNISTREVPOLICYENABLEDFAILED);
 
                         PKIX_CHECK(pkix_DefaultCRLChecker_Initialize
                             (certStores,
                             testDate,
                             trustedPubKey,
                             numCerts,
+                            nistCRLPolicyEnabled,
                             &defaultCrlChecker,
                             plContext),
                             PKIX_DEFAULTCRLCHECKERINITIALIZEFAILED);
 
                         PKIX_CHECK(PKIX_List_AppendItem
                             (checkers,
                             (PKIX_PL_Object *)defaultCrlChecker,
                             plContext),
--- a/security/nss/lib/libpkix/pkix/util/pkix_tools.c
+++ b/security/nss/lib/libpkix/pkix/util/pkix_tools.c
@@ -1160,20 +1160,29 @@ pkix_CacheCert_Add(
 {
         PKIX_List *cachedKeys = NULL;
         PKIX_List *cachedValues = NULL;
         PKIX_PL_Date *cacheValidUntilDate = NULL;
         PKIX_PL_X500Name *subject = NULL;
         PKIX_Error *cachedCertError = NULL;
         PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
         PKIX_UInt32 cachePeriod = CACHE_ITEM_PERIOD_SECONDS;
+        PKIX_UInt32 numCerts = 0;
 
         PKIX_ENTER(BUILD, "pkix_CacheCert_Add");
         PKIX_NULLCHECK_THREE(store, certSelParams, certs);
 
+        PKIX_CHECK(PKIX_List_GetLength(certs, &numCerts,
+                                       plContext),
+                   PKIX_LISTGETLENGTHFAILED);
+        if (numCerts == 0) {
+            /* Don't want to add an empty list. */
+            goto cleanup;
+        }
+
         PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
                 PKIX_LISTCREATEFAILED);
 
         PKIX_CHECK(PKIX_List_AppendItem
                 (cachedKeys, (PKIX_PL_Object *)store, plContext),
                 PKIX_LISTAPPENDITEMFAILED);
 
         PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c
@@ -707,41 +707,51 @@ PKIX_PL_CRL_VerifyUpdateTime(
         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);
 
         nssCrl = &(crl->nssSignedCrl->crl);
 
         PKIX_CRL_DEBUG("\t\tCalling DER_DecodeTimeChoice on date\n");
         status = DER_DecodeTimeChoice(&timeToCheck, &(date->nssTime));
         if (status != SECSuccess) {
                 PKIX_ERROR(PKIX_DERDECODETIMECHOICEFAILED);
         }
 
-        PKIX_CRL_DEBUG("\t\tCalling DER_DecodeTimeChoice on nextUpdate\n");
-        status = DER_DecodeTimeChoice(&nextUpdate, &(nssCrl->nextUpdate));
-        if (status != SECSuccess) {
-                PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORNEXTUPDATEFAILED);
+        /* 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);
+                }
         }
 
-        PKIX_CRL_DEBUG("\t\tCalling DER_DecodeTimeChoice on lastUpdate\n");
         status = DER_DecodeTimeChoice(&lastUpdate, &(nssCrl->lastUpdate));
         if (status != SECSuccess) {
                 PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORLASTUPDATEFAILED);
         }
 
-        if (lastUpdate <= timeToCheck && nextUpdate > timeToCheck) {
+        if (!haveNextUpdate || nextUpdate < timeToCheck) {
+                *pResult = PKIX_FALSE;
+                goto cleanup;
+        }
+
+        if (lastUpdate <= timeToCheck) {
                 *pResult = PKIX_TRUE;
         } else {
                 *pResult = PKIX_FALSE;
         }
 
 cleanup:
 
         PKIX_RETURN(CRL);