/* 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/. */

/*
 * Moved from secpkcs7.c
 */

#include "cert.h"
#include "certi.h"
#include "secder.h"
#include "secasn1.h"
#include "secoid.h"
#include "certdb.h"
#include "certxutl.h"
#include "prtime.h"
#include "secerr.h"
#include "pk11func.h"
#include "dev.h"
#include "dev3hack.h"
#include "nssbase.h"
#if defined(DPC_RWLOCK) || defined(GLOBAL_RWLOCK)
#include "nssrwlk.h"
#endif
#include "pk11priv.h"

const SEC_ASN1Template SEC_CERTExtensionTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertExtension) },
    { SEC_ASN1_OBJECT_ID, offsetof(CERTCertExtension, id) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
      offsetof(CERTCertExtension, critical) },
    { SEC_ASN1_OCTET_STRING, offsetof(CERTCertExtension, value) },
    { 0 }
};

static const SEC_ASN1Template SEC_CERTExtensionsTemplate[] = {
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_CERTExtensionTemplate }
};

/*
 * XXX Also, these templates need to be tested; Lisa did the obvious
 * translation but they still should be verified.
 */

const SEC_ASN1Template CERT_IssuerAndSNTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTIssuerAndSN) },
    { SEC_ASN1_SAVE, offsetof(CERTIssuerAndSN, derIssuer) },
    { SEC_ASN1_INLINE, offsetof(CERTIssuerAndSN, issuer), CERT_NameTemplate },
    { SEC_ASN1_INTEGER, offsetof(CERTIssuerAndSN, serialNumber) },
    { 0 }
};

SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
SEC_ASN1_MKSUB(CERT_TimeChoiceTemplate)

static const SEC_ASN1Template cert_CrlKeyTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCrlKey) },
    { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(CERTCrlKey, dummy) },
    { SEC_ASN1_SKIP },
    { SEC_ASN1_ANY, offsetof(CERTCrlKey, derName) },
    { SEC_ASN1_SKIP_REST },
    { 0 }
};

static const SEC_ASN1Template cert_CrlEntryTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCrlEntry) },
    { SEC_ASN1_INTEGER, offsetof(CERTCrlEntry, serialNumber) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CERTCrlEntry, revocationDate),
      SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF,
      offsetof(CERTCrlEntry, extensions), SEC_CERTExtensionTemplate },
    { 0 }
};

const SEC_ASN1Template CERT_CrlTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCrl) },
    { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(CERTCrl, version) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CERTCrl, signatureAlg),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_SAVE, offsetof(CERTCrl, derName) },
    { SEC_ASN1_INLINE, offsetof(CERTCrl, name), CERT_NameTemplate },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CERTCrl, lastUpdate),
      SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
    { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN,
      offsetof(CERTCrl, nextUpdate), SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, offsetof(CERTCrl, entries),
      cert_CrlEntryTemplate },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
          SEC_ASN1_EXPLICIT | 0,
      offsetof(CERTCrl, extensions), SEC_CERTExtensionsTemplate },
    { 0 }
};

const SEC_ASN1Template CERT_CrlTemplateNoEntries[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCrl) },
    { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(CERTCrl, version) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CERTCrl, signatureAlg),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_SAVE, offsetof(CERTCrl, derName) },
    { SEC_ASN1_INLINE, offsetof(CERTCrl, name), CERT_NameTemplate },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CERTCrl, lastUpdate),
      SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
    { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN,
      offsetof(CERTCrl, nextUpdate), SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF |
      SEC_ASN1_SKIP }, /* skip entries */
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
          SEC_ASN1_EXPLICIT | 0,
      offsetof(CERTCrl, extensions), SEC_CERTExtensionsTemplate },
    { 0 }
};

const SEC_ASN1Template CERT_CrlTemplateEntriesOnly[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCrl) },
    { SEC_ASN1_SKIP | SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL },
    { SEC_ASN1_SKIP },
    { SEC_ASN1_SKIP },
    { SEC_ASN1_SKIP | SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(CERTCrl, lastUpdate), SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
    { SEC_ASN1_SKIP | SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN,
      offsetof(CERTCrl, nextUpdate), SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, offsetof(CERTCrl, entries),
      cert_CrlEntryTemplate }, /* decode entries */
    { SEC_ASN1_SKIP_REST },
    { 0 }
};

const SEC_ASN1Template CERT_SignedCrlTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTSignedCrl) },
    { SEC_ASN1_SAVE, offsetof(CERTSignedCrl, signatureWrap.data) },
    { SEC_ASN1_INLINE, offsetof(CERTSignedCrl, crl), CERT_CrlTemplate },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(CERTSignedCrl, signatureWrap.signatureAlgorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_BIT_STRING, offsetof(CERTSignedCrl, signatureWrap.signature) },
    { 0 }
};

static const SEC_ASN1Template cert_SignedCrlTemplateNoEntries[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTSignedCrl) },
    { SEC_ASN1_SAVE, offsetof(CERTSignedCrl, signatureWrap.data) },
    { SEC_ASN1_INLINE, offsetof(CERTSignedCrl, crl),
      CERT_CrlTemplateNoEntries },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(CERTSignedCrl, signatureWrap.signatureAlgorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_BIT_STRING, offsetof(CERTSignedCrl, signatureWrap.signature) },
    { 0 }
};

const SEC_ASN1Template CERT_SetOfSignedCrlTemplate[] = {
    { SEC_ASN1_SET_OF, 0, CERT_SignedCrlTemplate },
};

/* get CRL version */
int
cert_get_crl_version(CERTCrl* crl)
{
    /* CRL version is defaulted to v1 */
    int version = SEC_CRL_VERSION_1;
    if (crl && crl->version.data != 0) {
        version = (int)DER_GetUInteger(&crl->version);
    }
    return version;
}

/* check the entries in the CRL */
SECStatus
cert_check_crl_entries(CERTCrl* crl)
{
    CERTCrlEntry** entries;
    CERTCrlEntry* entry;
    PRBool hasCriticalExten = PR_FALSE;
    SECStatus rv = SECSuccess;

    if (!crl) {
        return SECFailure;
    }

    if (crl->entries == NULL) {
        /* CRLs with no entries are valid */
        return (SECSuccess);
    }

    /* Look in the crl entry extensions.  If there is a critical extension,
       then the crl version must be v2; otherwise, it should be v1.
     */
    entries = crl->entries;
    while (*entries) {
        entry = *entries;
        if (entry->extensions) {
            /* If there is a critical extension in the entries, then the
               CRL must be of version 2.  If we already saw a critical
               extension,
               there is no need to check the version again.
            */
            if (hasCriticalExten == PR_FALSE) {
                hasCriticalExten = cert_HasCriticalExtension(entry->extensions);
                if (hasCriticalExten) {
                    if (cert_get_crl_version(crl) != SEC_CRL_VERSION_2) {
                        /* only CRL v2 critical extensions are supported */
                        PORT_SetError(SEC_ERROR_CRL_V1_CRITICAL_EXTENSION);
                        rv = SECFailure;
                        break;
                    }
                }
            }

            /* For each entry, make sure that it does not contain an unknown
               critical extension.  If it does, we must reject the CRL since
               we don't know how to process the extension.
            */
            if (cert_HasUnknownCriticalExten(entry->extensions) == PR_TRUE) {
                PORT_SetError(SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION);
                rv = SECFailure;
                break;
            }
        }
        ++entries;
    }
    return (rv);
}

/* Check the version of the CRL.  If there is a critical extension in the crl
   or crl entry, then the version must be v2. Otherwise, it should be v1. If
   the crl contains critical extension(s), then we must recognized the
   extension's OID.
   */
SECStatus
cert_check_crl_version(CERTCrl* crl)
{
    PRBool hasCriticalExten = PR_FALSE;
    int version = cert_get_crl_version(crl);

    if (version > SEC_CRL_VERSION_2) {
        PORT_SetError(SEC_ERROR_CRL_INVALID_VERSION);
        return (SECFailure);
    }

    /* Check the crl extensions for a critial extension.  If one is found,
       and the version is not v2, then we are done.
     */
    if (crl->extensions) {
        hasCriticalExten = cert_HasCriticalExtension(crl->extensions);
        if (hasCriticalExten) {
            if (version != SEC_CRL_VERSION_2) {
                /* only CRL v2 critical extensions are supported */
                PORT_SetError(SEC_ERROR_CRL_V1_CRITICAL_EXTENSION);
                return (SECFailure);
            }
            /* make sure that there is no unknown critical extension */
            if (cert_HasUnknownCriticalExten(crl->extensions) == PR_TRUE) {
                PORT_SetError(SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION);
                return (SECFailure);
            }
        }
    }

    return (SECSuccess);
}

/*
 * Generate a database key, based on the issuer name from a
 * DER crl.
 */
SECStatus
CERT_KeyFromDERCrl(PLArenaPool* arena, SECItem* derCrl, SECItem* key)
{
    SECStatus rv;
    CERTSignedData sd;
    CERTCrlKey crlkey;
    PLArenaPool* myArena;

    if (!arena) {
        /* arena needed for QuickDER */
        myArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    } else {
        myArena = arena;
    }
    PORT_Memset(&sd, 0, sizeof(sd));
    rv = SEC_QuickDERDecodeItem(myArena, &sd, CERT_SignedDataTemplate, derCrl);
    if (SECSuccess == rv) {
        PORT_Memset(&crlkey, 0, sizeof(crlkey));
        rv = SEC_QuickDERDecodeItem(myArena, &crlkey, cert_CrlKeyTemplate,
                                    &sd.data);
    }

    /* make a copy so the data doesn't point to memory inside derCrl, which
       may be temporary */
    if (SECSuccess == rv) {
        rv = SECITEM_CopyItem(arena, key, &crlkey.derName);
    }

    if (myArena != arena) {
        PORT_FreeArena(myArena, PR_FALSE);
    }

    return rv;
}

#define GetOpaqueCRLFields(x) ((OpaqueCRLFields*)x->opaque)

SECStatus
CERT_CompleteCRLDecodeEntries(CERTSignedCrl* crl)
{
    SECStatus rv = SECSuccess;
    SECItem* crldata = NULL;
    OpaqueCRLFields* extended = NULL;

    if ((!crl) || (!(extended = (OpaqueCRLFields*)crl->opaque)) ||
        (PR_TRUE == extended->decodingError)) {
        rv = SECFailure;
    } else {
        if (PR_FALSE == extended->partial) {
            /* the CRL has already been fully decoded */
            return SECSuccess;
        }
        if (PR_TRUE == extended->badEntries) {
            /* the entries decoding already failed */
            return SECFailure;
        }
        crldata = &crl->signatureWrap.data;
        if (!crldata) {
            rv = SECFailure;
        }
    }

    if (SECSuccess == rv) {
        rv = SEC_QuickDERDecodeItem(crl->arena, &crl->crl,
                                    CERT_CrlTemplateEntriesOnly, crldata);
        if (SECSuccess == rv) {
            extended->partial = PR_FALSE; /* successful decode, avoid
                decoding again */
        } else {
            extended->decodingError = PR_TRUE;
            extended->badEntries = PR_TRUE;
            /* cache the decoding failure. If it fails the first time,
               it will fail again, which will grow the arena and leak
               memory, so we want to avoid it */
        }
        rv = cert_check_crl_entries(&crl->crl);
        if (rv != SECSuccess) {
            extended->badExtensions = PR_TRUE;
        }
    }
    return rv;
}

/*
 * take a DER CRL and decode it into a CRL structure
 * allow reusing the input DER without making a copy
 */
CERTSignedCrl*
CERT_DecodeDERCrlWithFlags(PLArenaPool* narena, SECItem* derSignedCrl, int type,
                           PRInt32 options)
{
    PLArenaPool* arena;
    CERTSignedCrl* crl;
    SECStatus rv;
    OpaqueCRLFields* extended = NULL;
    const SEC_ASN1Template* crlTemplate = CERT_SignedCrlTemplate;
    PRInt32 testOptions = options;

    PORT_Assert(derSignedCrl);
    if (!derSignedCrl) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    /* Adopting DER requires not copying it.  Code that sets ADOPT flag
     * but doesn't set DONT_COPY probably doesn't know What it is doing.
     * That condition is a programming error in the caller.
     */
    testOptions &= (CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_DONT_COPY_DER);
    PORT_Assert(testOptions != CRL_DECODE_ADOPT_HEAP_DER);
    if (testOptions == CRL_DECODE_ADOPT_HEAP_DER) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    /* make a new arena if needed */
    if (narena == NULL) {
        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        if (!arena) {
            return NULL;
        }
    } else {
        arena = narena;
    }

    /* allocate the CRL structure */
    crl = (CERTSignedCrl*)PORT_ArenaZAlloc(arena, sizeof(CERTSignedCrl));
    if (!crl) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    crl->arena = arena;

    /* allocate opaque fields */
    crl->opaque = (void*)PORT_ArenaZAlloc(arena, sizeof(OpaqueCRLFields));
    if (!crl->opaque) {
        goto loser;
    }
    extended = (OpaqueCRLFields*)crl->opaque;
    if (options & CRL_DECODE_ADOPT_HEAP_DER) {
        extended->heapDER = PR_TRUE;
    }
    if (options & CRL_DECODE_DONT_COPY_DER) {
        crl->derCrl = derSignedCrl; /* DER is not copied . The application
                                       must keep derSignedCrl until it
                                       destroys the CRL */
    } else {
        crl->derCrl = (SECItem*)PORT_ArenaZAlloc(arena, sizeof(SECItem));
        if (crl->derCrl == NULL) {
            goto loser;
        }
        rv = SECITEM_CopyItem(arena, crl->derCrl, derSignedCrl);
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    /* Save the arena in the inner crl for CRL extensions support */
    crl->crl.arena = arena;
    if (options & CRL_DECODE_SKIP_ENTRIES) {
        crlTemplate = cert_SignedCrlTemplateNoEntries;
        extended->partial = PR_TRUE;
    }

    /* decode the CRL info */
    switch (type) {
        case SEC_CRL_TYPE:
            rv = SEC_QuickDERDecodeItem(arena, crl, crlTemplate, crl->derCrl);
            if (rv != SECSuccess) {
                extended->badDER = PR_TRUE;
                break;
            }
            /* check for critical extensions */
            rv = cert_check_crl_version(&crl->crl);
            if (rv != SECSuccess) {
                extended->badExtensions = PR_TRUE;
                break;
            }

            if (PR_TRUE == extended->partial) {
                /* partial decoding, don't verify entries */
                break;
            }

            rv = cert_check_crl_entries(&crl->crl);
            if (rv != SECSuccess) {
                extended->badExtensions = PR_TRUE;
            }

            break;

        default:
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            rv = SECFailure;
            break;
    }

    if (rv != SECSuccess) {
        goto loser;
    }

    crl->referenceCount = 1;

    return (crl);

loser:
    if (options & CRL_DECODE_KEEP_BAD_CRL) {
        if (extended) {
            extended->decodingError = PR_TRUE;
        }
        if (crl) {
            crl->referenceCount = 1;
            return (crl);
        }
    }

    if ((narena == NULL) && arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (0);
}

/*
 * take a DER CRL and decode it into a CRL structure
 */
CERTSignedCrl*
CERT_DecodeDERCrl(PLArenaPool* narena, SECItem* derSignedCrl, int type)
{
    return CERT_DecodeDERCrlWithFlags(narena, derSignedCrl, type,
                                      CRL_DECODE_DEFAULT_OPTIONS);
}

/*
 * Lookup a CRL in the databases. We mirror the same fast caching data base
 *  caching stuff used by certificates....?
 * return values :
 *
 * SECSuccess means we got a valid decodable DER CRL, or no CRL at all.
 * Caller may distinguish those cases by the value returned in "decoded".
 * When DER CRL is not found, error code will be SEC_ERROR_CRL_NOT_FOUND.
 *
 * SECFailure means we got a fatal error - most likely, we found a CRL,
 * and it failed decoding, or there was an out of memory error. Do NOT ignore
 * it and specifically do NOT treat it the same as having no CRL, as this
 * can compromise security !!! Ideally, you should treat this case as if you
 * received a "catch-all" CRL where all certs you were looking up are
 * considered to be revoked
 */
static SECStatus
SEC_FindCrlByKeyOnSlot(PK11SlotInfo* slot, SECItem* crlKey, int type,
                       CERTSignedCrl** decoded, PRInt32 decodeoptions)
{
    SECStatus rv = SECSuccess;
    CERTSignedCrl* crl = NULL;
    SECItem* derCrl = NULL;
    CK_OBJECT_HANDLE crlHandle = 0;
    char* url = NULL;

    PORT_Assert(decoded);
    if (!decoded) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    derCrl = PK11_FindCrlByName(&slot, &crlHandle, crlKey, type, &url);
    if (derCrl == NULL) {
        /* if we had a problem other than the CRL just didn't exist, return
         * a failure to the upper level */
        int nsserror = PORT_GetError();
        if (nsserror != SEC_ERROR_CRL_NOT_FOUND) {
            rv = SECFailure;
        }
        goto loser;
    }
    PORT_Assert(crlHandle != CK_INVALID_HANDLE);
    /* PK11_FindCrlByName obtained a slot reference. */

    /* derCRL is a fresh HEAP copy made for us by PK11_FindCrlByName.
       Force adoption of the DER CRL from the heap - this will cause it
       to be automatically freed when SEC_DestroyCrl is invoked */
    decodeoptions |= (CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_DONT_COPY_DER);

    crl = CERT_DecodeDERCrlWithFlags(NULL, derCrl, type, decodeoptions);
    if (crl) {
        crl->slot = slot;
        slot = NULL;   /* adopt it */
        derCrl = NULL; /* adopted by the crl struct */
        crl->pkcs11ID = crlHandle;
        if (url) {
            crl->url = PORT_ArenaStrdup(crl->arena, url);
        }
    } else {
        rv = SECFailure;
    }

    if (url) {
        PORT_Free(url);
    }

    if (slot) {
        PK11_FreeSlot(slot);
    }

loser:
    if (derCrl) {
        SECITEM_FreeItem(derCrl, PR_TRUE);
    }

    *decoded = crl;

    return rv;
}

CERTSignedCrl*
crl_storeCRL(PK11SlotInfo* slot, char* url, CERTSignedCrl* newCrl,
             SECItem* derCrl, int type)
{
    CERTSignedCrl *oldCrl = NULL, *crl = NULL;
    PRBool deleteOldCrl = PR_FALSE;
    CK_OBJECT_HANDLE crlHandle = CK_INVALID_HANDLE;

    PORT_Assert(newCrl);
    PORT_Assert(derCrl);
    PORT_Assert(type == SEC_CRL_TYPE);

    if (type != SEC_CRL_TYPE) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    /* we can't use the cache here because we must look in the same
       token */
    (void)SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type, &oldCrl,
                                 CRL_DECODE_SKIP_ENTRIES);
    /* if there is an old crl on the token, make sure the one we are
       installing is newer. If not, exit out, otherwise delete the
       old crl.
     */
    if (oldCrl != NULL) {
        /* if it's already there, quietly continue */
        if (SECITEM_CompareItem(newCrl->derCrl, oldCrl->derCrl) == SECEqual) {
            crl = newCrl;
            crl->slot = PK11_ReferenceSlot(slot);
            crl->pkcs11ID = oldCrl->pkcs11ID;
            if (oldCrl->url && !url)
                url = oldCrl->url;
            if (url)
                crl->url = PORT_ArenaStrdup(crl->arena, url);
            goto done;
        }
        if (!SEC_CrlIsNewer(&newCrl->crl, &oldCrl->crl)) {
            PORT_SetError(SEC_ERROR_OLD_CRL);
            goto done;
        }

        /* if we have a url in the database, use that one */
        if (oldCrl->url && !url) {
            url = oldCrl->url;
        }

        /* really destroy this crl */
        /* first drum it out of the permanment Data base */
        deleteOldCrl = PR_TRUE;
    }

    /* invalidate CRL cache for this issuer */
    CERT_CRLCacheRefreshIssuer(NULL, &newCrl->crl.derName);
    /* Write the new entry into the data base */
    crlHandle = PK11_PutCrl(slot, derCrl, &newCrl->crl.derName, url, type);
    if (crlHandle != CK_INVALID_HANDLE) {
        crl = newCrl;
        crl->slot = PK11_ReferenceSlot(slot);
        crl->pkcs11ID = crlHandle;
        if (url) {
            crl->url = PORT_ArenaStrdup(crl->arena, url);
        }
    }

done:
    if (oldCrl) {
        if (deleteOldCrl && crlHandle != CK_INVALID_HANDLE) {
            SEC_DeletePermCRL(oldCrl);
        }
        SEC_DestroyCrl(oldCrl);
    }

    return crl;
}

/*
 *
 * create a new CRL from DER material.
 *
 * The signature on this CRL must be checked before you
 * load it. ???
 */
CERTSignedCrl*
SEC_NewCrl(CERTCertDBHandle* handle, char* url, SECItem* derCrl, int type)
{
    CERTSignedCrl* retCrl = NULL;
    PK11SlotInfo* slot = PK11_GetInternalKeySlot();
    retCrl =
        PK11_ImportCRL(slot, derCrl, url, type, NULL, CRL_IMPORT_BYPASS_CHECKS,
                       NULL, CRL_DECODE_DEFAULT_OPTIONS);
    PK11_FreeSlot(slot);

    return retCrl;
}

CERTSignedCrl*
SEC_FindCrlByDERCert(CERTCertDBHandle* handle, SECItem* derCrl, int type)
{
    PLArenaPool* arena;
    SECItem crlKey;
    SECStatus rv;
    CERTSignedCrl* crl = NULL;

    /* create a scratch arena */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        return (NULL);
    }

    /* extract the database key from the cert */
    rv = CERT_KeyFromDERCrl(arena, derCrl, &crlKey);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* find the crl */
    crl = SEC_FindCrlByName(handle, &crlKey, type);

loser:
    PORT_FreeArena(arena, PR_FALSE);
    return (crl);
}

CERTSignedCrl*
SEC_DupCrl(CERTSignedCrl* acrl)
{
    if (acrl) {
        PR_ATOMIC_INCREMENT(&acrl->referenceCount);
        return acrl;
    }
    return NULL;
}

SECStatus
SEC_DestroyCrl(CERTSignedCrl* crl)
{
    if (crl) {
        if (PR_ATOMIC_DECREMENT(&crl->referenceCount) < 1) {
            if (crl->slot) {
                PK11_FreeSlot(crl->slot);
            }
            if (GetOpaqueCRLFields(crl) &&
                PR_TRUE == GetOpaqueCRLFields(crl)->heapDER) {
                SECITEM_FreeItem(crl->derCrl, PR_TRUE);
            }
            if (crl->arena) {
                PORT_FreeArena(crl->arena, PR_FALSE);
            }
        }
        return SECSuccess;
    } else {
        return SECFailure;
    }
}

SECStatus
SEC_LookupCrls(CERTCertDBHandle* handle, CERTCrlHeadNode** nodes, int type)
{
    CERTCrlHeadNode* head;
    PLArenaPool* arena = NULL;
    SECStatus rv;

    *nodes = NULL;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        return SECFailure;
    }

    /* build a head structure */
    head = (CERTCrlHeadNode*)PORT_ArenaAlloc(arena, sizeof(CERTCrlHeadNode));
    head->arena = arena;
    head->first = NULL;
    head->last = NULL;
    head->dbhandle = handle;

    /* Look up the proper crl types */
    *nodes = head;

    rv = PK11_LookupCrls(head, type, NULL);

    if (rv != SECSuccess) {
        if (arena) {
            PORT_FreeArena(arena, PR_FALSE);
            *nodes = NULL;
        }
    }

    return rv;
}

/* These functions simply return the address of the above-declared templates.
** This is necessary for Windows DLLs.  Sigh.
*/
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_IssuerAndSNTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CrlTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SignedCrlTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SetOfSignedCrlTemplate)

/* CRL cache code starts here */

/* constructor */
static SECStatus CachedCrl_Create(CachedCrl** returned, CERTSignedCrl* crl,
                                  CRLOrigin origin);
/* destructor */
static SECStatus CachedCrl_Destroy(CachedCrl* crl);

/* create hash table of CRL entries */
static SECStatus CachedCrl_Populate(CachedCrl* crlobject);

/* empty the cache content */
static SECStatus CachedCrl_Depopulate(CachedCrl* crl);

/* are these CRLs the same, as far as the cache is concerned ?
   Or are they the same token object, but with different DER ? */

static SECStatus CachedCrl_Compare(CachedCrl* a, CachedCrl* b, PRBool* isDupe,
                                   PRBool* isUpdated);

/* create a DPCache object */
static SECStatus DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer,
                                const SECItem* subject, SECItem* dp);

/* destructor for CRL DPCache object */
static SECStatus DPCache_Destroy(CRLDPCache* cache);

/* add a new CRL object to the dynamic array of CRLs of the DPCache, and
   returns the cached CRL object . Needs write access to DPCache. */
static SECStatus DPCache_AddCRL(CRLDPCache* cache, CachedCrl* crl,
                                PRBool* added);

/* fetch the CRL for this DP from the PKCS#11 tokens */
static SECStatus DPCache_FetchFromTokens(CRLDPCache* cache, PRTime vfdate,
                                         void* wincx);

/* update the content of the CRL cache, including fetching of CRLs, and
   reprocessing with specified issuer and date */
static SECStatus DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate* issuer,
                                     PRBool readlocked, PRTime vfdate,
                                     void* wincx);

/* returns true if there are CRLs from PKCS#11 slots */
static PRBool DPCache_HasTokenCRLs(CRLDPCache* cache);

/* remove CRL at offset specified */
static SECStatus DPCache_RemoveCRL(CRLDPCache* cache, PRUint32 offset);

/* Pick best CRL to use . needs write access */
static SECStatus DPCache_SelectCRL(CRLDPCache* cache);

/* create an issuer cache object (per CA subject ) */
static SECStatus IssuerCache_Create(CRLIssuerCache** returned,
                                    CERTCertificate* issuer,
                                    const SECItem* subject, const SECItem* dp);

/* destructor for CRL IssuerCache object */
SECStatus IssuerCache_Destroy(CRLIssuerCache* cache);

/* add a DPCache to the issuer cache */
static SECStatus IssuerCache_AddDP(CRLIssuerCache* cache,
                                   CERTCertificate* issuer,
                                   const SECItem* subject, const SECItem* dp,
                                   CRLDPCache** newdpc);

/* get a particular DPCache object from an IssuerCache */
static CRLDPCache* IssuerCache_GetDPCache(CRLIssuerCache* cache,
                                          const SECItem* dp);

/*
** Pre-allocator hash allocator ops.
*/

/* allocate memory for hash table */
static void* PR_CALLBACK
PreAllocTable(void* pool, PRSize size)
{
    PreAllocator* alloc = (PreAllocator*)pool;
    PORT_Assert(alloc);
    if (!alloc) {
        /* no allocator, or buffer full */
        return NULL;
    }
    if (size > (alloc->len - alloc->used)) {
        /* initial buffer full, let's use the arena */
        alloc->extra += size;
        return PORT_ArenaAlloc(alloc->arena, size);
    }
    /* use the initial buffer */
    alloc->used += size;
    return (char*)alloc->data + alloc->used - size;
}

/* free hash table memory.
   Individual PreAllocator elements cannot be freed, so this is a no-op. */
static void PR_CALLBACK
PreFreeTable(void* pool, void* item)
{
}

/* allocate memory for hash table */
static PLHashEntry* PR_CALLBACK
PreAllocEntry(void* pool, const void* key)
{
    return PreAllocTable(pool, sizeof(PLHashEntry));
}

/* free hash table entry.
   Individual PreAllocator elements cannot be freed, so this is a no-op. */
static void PR_CALLBACK
PreFreeEntry(void* pool, PLHashEntry* he, PRUintn flag)
{
}

/* methods required for PL hash table functions */
static PLHashAllocOps preAllocOps = { PreAllocTable, PreFreeTable,
                                      PreAllocEntry, PreFreeEntry };

/* destructor for PreAllocator object */
void
PreAllocator_Destroy(PreAllocator* allocator)
{
    if (!allocator) {
        return;
    }
    if (allocator->arena) {
        PORT_FreeArena(allocator->arena, PR_TRUE);
    }
}

/* constructor for PreAllocator object */
PreAllocator*
PreAllocator_Create(PRSize size)
{
    PLArenaPool* arena = NULL;
    PreAllocator* prebuffer = NULL;
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        return NULL;
    }
    prebuffer = (PreAllocator*)PORT_ArenaZAlloc(arena, sizeof(PreAllocator));
    if (!prebuffer) {
        PORT_FreeArena(arena, PR_TRUE);
        return NULL;
    }
    prebuffer->arena = arena;

    if (size) {
        prebuffer->len = size;
        prebuffer->data = PORT_ArenaAlloc(arena, size);
        if (!prebuffer->data) {
            PORT_FreeArena(arena, PR_TRUE);
            return NULL;
        }
    }
    return prebuffer;
}

/* global Named CRL cache object */
static NamedCRLCache namedCRLCache = { NULL, NULL };

/* global CRL cache object */
static CRLCache crlcache = { NULL, NULL };

/* initial state is off */
static PRBool crlcache_initialized = PR_FALSE;

PRTime CRLCache_Empty_TokenFetch_Interval = 60 * 1000000; /* how often
    to query the tokens for CRL objects, in order to discover new objects, if
    the cache does not contain any token CRLs . In microseconds */

PRTime CRLCache_TokenRefetch_Interval = 600 * 1000000; /* how often
   to query the tokens for CRL objects, in order to discover new objects, if
   the cache already contains token CRLs In microseconds */

PRTime CRLCache_ExistenceCheck_Interval = 60 * 1000000; /* how often to check
    if a token CRL object still exists. In microseconds */

/* this function is called at NSS initialization time */
SECStatus
InitCRLCache(void)
{
    if (PR_FALSE == crlcache_initialized) {
        PORT_Assert(NULL == crlcache.lock);
        PORT_Assert(NULL == crlcache.issuers);
        PORT_Assert(NULL == namedCRLCache.lock);
        PORT_Assert(NULL == namedCRLCache.entries);
        if (crlcache.lock || crlcache.issuers || namedCRLCache.lock ||
            namedCRLCache.entries) {
            /* CRL cache already partially initialized */
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            return SECFailure;
        }
#ifdef GLOBAL_RWLOCK
        crlcache.lock = NSSRWLock_New(NSS_RWLOCK_RANK_NONE, NULL);
#else
        crlcache.lock = PR_NewLock();
#endif
        namedCRLCache.lock = PR_NewLock();
        crlcache.issuers = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
                                           PL_CompareValues, NULL, NULL);
        namedCRLCache.entries = PL_NewHashTable(
            0, SECITEM_Hash, SECITEM_HashCompare, PL_CompareValues, NULL, NULL);
        if (!crlcache.lock || !namedCRLCache.lock || !crlcache.issuers ||
            !namedCRLCache.entries) {
            if (crlcache.lock) {
#ifdef GLOBAL_RWLOCK
                NSSRWLock_Destroy(crlcache.lock);
#else
                PR_DestroyLock(crlcache.lock);
#endif
                crlcache.lock = NULL;
            }
            if (namedCRLCache.lock) {
                PR_DestroyLock(namedCRLCache.lock);
                namedCRLCache.lock = NULL;
            }
            if (crlcache.issuers) {
                PL_HashTableDestroy(crlcache.issuers);
                crlcache.issuers = NULL;
            }
            if (namedCRLCache.entries) {
                PL_HashTableDestroy(namedCRLCache.entries);
                namedCRLCache.entries = NULL;
            }

            return SECFailure;
        }
        crlcache_initialized = PR_TRUE;
        return SECSuccess;
    } else {
        PORT_Assert(crlcache.lock);
        PORT_Assert(crlcache.issuers);
        if ((NULL == crlcache.lock) || (NULL == crlcache.issuers)) {
            /* CRL cache not fully initialized */
            return SECFailure;
        } else {
            /* CRL cache already initialized */
            return SECSuccess;
        }
    }
}

/* destructor for CRL DPCache object */
static SECStatus
DPCache_Destroy(CRLDPCache* cache)
{
    PRUint32 i = 0;
    PORT_Assert(cache);
    if (!cache) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    if (cache->lock) {
#ifdef DPC_RWLOCK
        NSSRWLock_Destroy(cache->lock);
#else
        PR_DestroyLock(cache->lock);
#endif
    } else {
        PORT_Assert(0);
        return SECFailure;
    }
    /* destroy all our CRL objects */
    for (i = 0; i < cache->ncrls; i++) {
        if (!cache->crls || !cache->crls[i] ||
            SECSuccess != CachedCrl_Destroy(cache->crls[i])) {
            return SECFailure;
        }
    }
    /* free the array of CRLs */
    if (cache->crls) {
        PORT_Free(cache->crls);
    }
    /* destroy the cert */
    if (cache->issuerDERCert) {
        SECITEM_FreeItem(cache->issuerDERCert, PR_TRUE);
    }
    /* free the subject */
    if (cache->subject) {
        SECITEM_FreeItem(cache->subject, PR_TRUE);
    }
    /* free the distribution points */
    if (cache->distributionPoint) {
        SECITEM_FreeItem(cache->distributionPoint, PR_TRUE);
    }
    PORT_Free(cache);
    return SECSuccess;
}

/* destructor for CRL IssuerCache object */
SECStatus
IssuerCache_Destroy(CRLIssuerCache* cache)
{
    PORT_Assert(cache);
    if (!cache) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
#ifdef XCRL
    if (cache->lock) {
        NSSRWLock_Destroy(cache->lock);
    } else {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    if (cache->issuer) {
        CERT_DestroyCertificate(cache->issuer);
    }
#endif
    /* free the subject */
    if (cache->subject) {
        SECITEM_FreeItem(cache->subject, PR_TRUE);
    }
    if (SECSuccess != DPCache_Destroy(cache->dpp)) {
        PORT_Assert(0);
        return SECFailure;
    }
    PORT_Free(cache);
    return SECSuccess;
}

/* create a named CRL entry object */
static SECStatus
NamedCRLCacheEntry_Create(NamedCRLCacheEntry** returned)
{
    NamedCRLCacheEntry* entry = NULL;
    if (!returned) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    *returned = NULL;
    entry = (NamedCRLCacheEntry*)PORT_ZAlloc(sizeof(NamedCRLCacheEntry));
    if (!entry) {
        return SECFailure;
    }
    *returned = entry;
    return SECSuccess;
}

/* destroy a named CRL entry object */
static SECStatus
NamedCRLCacheEntry_Destroy(NamedCRLCacheEntry* entry)
{
    if (!entry) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    if (entry->crl) {
        /* named CRL cache owns DER memory */
        SECITEM_ZfreeItem(entry->crl, PR_TRUE);
    }
    if (entry->canonicalizedName) {
        SECITEM_FreeItem(entry->canonicalizedName, PR_TRUE);
    }
    PORT_Free(entry);
    return SECSuccess;
}

/* callback function used in hash table destructor */
static PRIntn PR_CALLBACK
FreeIssuer(PLHashEntry* he, PRIntn i, void* arg)
{
    CRLIssuerCache* issuer = NULL;
    SECStatus* rv = (SECStatus*)arg;

    PORT_Assert(he);
    if (!he) {
        return HT_ENUMERATE_NEXT;
    }
    issuer = (CRLIssuerCache*)he->value;
    PORT_Assert(issuer);
    if (issuer) {
        if (SECSuccess != IssuerCache_Destroy(issuer)) {
            PORT_Assert(rv);
            if (rv) {
                *rv = SECFailure;
            }
            return HT_ENUMERATE_NEXT;
        }
    }
    return HT_ENUMERATE_NEXT;
}

/* callback function used in hash table destructor */
static PRIntn PR_CALLBACK
FreeNamedEntries(PLHashEntry* he, PRIntn i, void* arg)
{
    NamedCRLCacheEntry* entry = NULL;
    SECStatus* rv = (SECStatus*)arg;

    PORT_Assert(he);
    if (!he) {
        return HT_ENUMERATE_NEXT;
    }
    entry = (NamedCRLCacheEntry*)he->value;
    PORT_Assert(entry);
    if (entry) {
        if (SECSuccess != NamedCRLCacheEntry_Destroy(entry)) {
            PORT_Assert(rv);
            if (rv) {
                *rv = SECFailure;
            }
            return HT_ENUMERATE_NEXT;
        }
    }
    return HT_ENUMERATE_NEXT;
}

/* needs to be called at NSS shutdown time
   This will destroy the global CRL cache, including
   - the hash table of issuer cache objects
   - the issuer cache objects
   - DPCache objects in issuer cache objects */
SECStatus
ShutdownCRLCache(void)
{
    SECStatus rv = SECSuccess;
    if (PR_FALSE == crlcache_initialized && !crlcache.lock &&
        !crlcache.issuers) {
        /* CRL cache has already been shut down */
        return SECSuccess;
    }
    if (PR_TRUE == crlcache_initialized &&
        (!crlcache.lock || !crlcache.issuers || !namedCRLCache.lock ||
         !namedCRLCache.entries)) {
        /* CRL cache has partially been shut down */
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    /* empty the CRL cache */
    /* free the issuers */
    PL_HashTableEnumerateEntries(crlcache.issuers, &FreeIssuer, &rv);
    /* free the hash table of issuers */
    PL_HashTableDestroy(crlcache.issuers);
    crlcache.issuers = NULL;
/* free the global lock */
#ifdef GLOBAL_RWLOCK
    NSSRWLock_Destroy(crlcache.lock);
#else
    PR_DestroyLock(crlcache.lock);
#endif
    crlcache.lock = NULL;

    /* empty the named CRL cache. This must be done after freeing the CRL
     * cache, since some CRLs in this cache are in the memory for the other  */
    /* free the entries */
    PL_HashTableEnumerateEntries(namedCRLCache.entries, &FreeNamedEntries, &rv);
    /* free the hash table of issuers */
    PL_HashTableDestroy(namedCRLCache.entries);
    namedCRLCache.entries = NULL;
    /* free the global lock */
    PR_DestroyLock(namedCRLCache.lock);
    namedCRLCache.lock = NULL;

    crlcache_initialized = PR_FALSE;
    return rv;
}

/* add a new CRL object to the dynamic array of CRLs of the DPCache, and
   returns the cached CRL object . Needs write access to DPCache. */
static SECStatus
DPCache_AddCRL(CRLDPCache* cache, CachedCrl* newcrl, PRBool* added)
{
    CachedCrl** newcrls = NULL;
    PRUint32 i = 0;
    PORT_Assert(cache);
    PORT_Assert(newcrl);
    PORT_Assert(added);
    if (!cache || !newcrl || !added) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    *added = PR_FALSE;
    /* before adding a new CRL, check if it is a duplicate */
    for (i = 0; i < cache->ncrls; i++) {
        CachedCrl* existing = NULL;
        SECStatus rv = SECSuccess;
        PRBool dupe = PR_FALSE, updated = PR_FALSE;
        if (!cache->crls) {
            PORT_Assert(0);
            return SECFailure;
        }
        existing = cache->crls[i];
        if (!existing) {
            PORT_Assert(0);
            return SECFailure;
        }
        rv = CachedCrl_Compare(existing, newcrl, &dupe, &updated);
        if (SECSuccess != rv) {
            PORT_Assert(0);
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            return SECFailure;
        }
        if (PR_TRUE == dupe) {
            /* dupe */
            PORT_SetError(SEC_ERROR_CRL_ALREADY_EXISTS);
            return SECSuccess;
        }
        if (PR_TRUE == updated) {
            /* this token CRL is in the same slot and has the same object ID,
               but different content. We need to remove the old object */
            if (SECSuccess != DPCache_RemoveCRL(cache, i)) {
                PORT_Assert(0);
                PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
                return PR_FALSE;
            }
        }
    }

    newcrls = (CachedCrl**)PORT_Realloc(cache->crls, (cache->ncrls + 1) * sizeof(CachedCrl*));
    if (!newcrls) {
        return SECFailure;
    }
    cache->crls = newcrls;
    cache->ncrls++;
    cache->crls[cache->ncrls - 1] = newcrl;
    *added = PR_TRUE;
    return SECSuccess;
}

/* remove CRL at offset specified */
static SECStatus
DPCache_RemoveCRL(CRLDPCache* cache, PRUint32 offset)
{
    CachedCrl* acrl = NULL;
    PORT_Assert(cache);
    if (!cache || (!cache->crls) || (!(offset < cache->ncrls))) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    acrl = cache->crls[offset];
    PORT_Assert(acrl);
    if (!acrl) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    cache->crls[offset] = cache->crls[cache->ncrls - 1];
    cache->crls[cache->ncrls - 1] = NULL;
    cache->ncrls--;
    if (cache->selected == acrl) {
        cache->selected = NULL;
    }
    if (SECSuccess != CachedCrl_Destroy(acrl)) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    return SECSuccess;
}

/* check whether a CRL object stored in a PKCS#11 token still exists in
   that token . This has to be efficient (the entire CRL value cannot be
   transferred accross the token boundaries), so this is accomplished by
   simply fetching the subject attribute and making sure it hasn't changed .
   Note that technically, the CRL object could have been replaced with a new
   PKCS#11 object of the same ID and subject (which actually happens in
   softoken), but this function has no way of knowing that the object
   value changed, since CKA_VALUE isn't checked. */
static PRBool
TokenCRLStillExists(CERTSignedCrl* crl)
{
    NSSItem newsubject;
    SECItem subject;
    CK_ULONG crl_class;
    PRStatus status;
    PK11SlotInfo* slot = NULL;
    nssCryptokiObject instance;
    NSSArena* arena;
    PRBool xstatus = PR_TRUE;
    SECItem* oldSubject = NULL;

    PORT_Assert(crl);
    if (!crl) {
        return PR_FALSE;
    }
    slot = crl->slot;
    PORT_Assert(crl->slot);
    if (!slot) {
        return PR_FALSE;
    }
    oldSubject = &crl->crl.derName;
    PORT_Assert(oldSubject);
    if (!oldSubject) {
        return PR_FALSE;
    }

    /* query subject and type attributes in order to determine if the
       object has been deleted */

    /* first, make an nssCryptokiObject */
    instance.handle = crl->pkcs11ID;
    PORT_Assert(instance.handle);
    if (!instance.handle) {
        return PR_FALSE;
    }
    instance.token = PK11Slot_GetNSSToken(slot);
    PORT_Assert(instance.token);
    if (!instance.token) {
        return PR_FALSE;
    }
    instance.isTokenObject = PR_TRUE;
    instance.label = NULL;

    arena = NSSArena_Create();
    PORT_Assert(arena);
    if (!arena) {
        return PR_FALSE;
    }

    status =
        nssCryptokiCRL_GetAttributes(&instance, NULL,          /* XXX sessionOpt */
                                     arena, NULL, &newsubject, /* subject */
                                     &crl_class,               /* class */
                                     NULL, NULL);
    if (PR_SUCCESS == status) {
        subject.data = newsubject.data;
        subject.len = newsubject.size;
        if (SECITEM_CompareItem(oldSubject, &subject) != SECEqual) {
            xstatus = PR_FALSE;
        }
        if (CKO_NETSCAPE_CRL != crl_class) {
            xstatus = PR_FALSE;
        }
    } else {
        xstatus = PR_FALSE;
    }
    NSSArena_Destroy(arena);
    return xstatus;
}

/* verify the signature of a CRL against its issuer at a given date */
static SECStatus
CERT_VerifyCRL(CERTSignedCrl* crlobject, CERTCertificate* issuer, PRTime vfdate,
               void* wincx)
{
    return CERT_VerifySignedData(&crlobject->signatureWrap, issuer, vfdate,
                                 wincx);
}

/* verify a CRL and update cache state */
static SECStatus
CachedCrl_Verify(CRLDPCache* cache, CachedCrl* crlobject, PRTime vfdate,
                 void* wincx)
{
    /*  Check if it is an invalid CRL
        if we got a bad CRL, we want to cache it in order to avoid
        subsequent fetches of this same identical bad CRL. We set
        the cache to the invalid state to ensure that all certs on this
        DP are considered to have unknown status from now on. The cache
        object will remain in this state until the bad CRL object
        is removed from the token it was fetched from. If the cause
        of the failure is that we didn't have the issuer cert to
        verify the signature, this state can be cleared when
        the issuer certificate becomes available if that causes the
        signature to verify */

    if (!cache || !crlobject) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    if (PR_TRUE == GetOpaqueCRLFields(crlobject->crl)->decodingError) {
        crlobject->sigChecked = PR_TRUE; /* we can never verify a CRL
            with bogus DER. Mark it checked so we won't try again */
        PORT_SetError(SEC_ERROR_BAD_DER);
        return SECSuccess;
    } else {
        SECStatus signstatus = SECFailure;
        if (cache->issuerDERCert) {
            CERTCertificate* issuer = CERT_NewTempCertificate(
                cache->dbHandle, cache->issuerDERCert, NULL, PR_FALSE, PR_TRUE);

            if (issuer) {
                signstatus =
                    CERT_VerifyCRL(crlobject->crl, issuer, vfdate, wincx);
                CERT_DestroyCertificate(issuer);
            }
        }
        if (SECSuccess != signstatus) {
            if (!cache->issuerDERCert) {
                /* we tried to verify without an issuer cert . This is
                   because this CRL came through a call to SEC_FindCrlByName.
                   So, we don't cache this verification failure. We'll try
                   to verify the CRL again when a certificate from that issuer
                   becomes available */
            } else {
                crlobject->sigChecked = PR_TRUE;
            }
            PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE);
            return SECSuccess;
        } else {
            crlobject->sigChecked = PR_TRUE;
            crlobject->sigValid = PR_TRUE;
        }
    }

    return SECSuccess;
}

/* fetch the CRLs for this DP from the PKCS#11 tokens */
static SECStatus
DPCache_FetchFromTokens(CRLDPCache* cache, PRTime vfdate, void* wincx)
{
    SECStatus rv = SECSuccess;
    CERTCrlHeadNode head;
    if (!cache) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    /* first, initialize list */
    memset(&head, 0, sizeof(head));
    head.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    rv = pk11_RetrieveCrls(&head, cache->subject, wincx);

    /* if this function fails, something very wrong happened, such as an out
       of memory error during CRL decoding. We don't want to proceed and must
       mark the cache object invalid */
    if (SECFailure == rv) {
        /* fetch failed, add error bit */
        cache->invalid |= CRL_CACHE_LAST_FETCH_FAILED;
    } else {
        /* fetch was successful, clear this error bit */
        cache->invalid &= (~CRL_CACHE_LAST_FETCH_FAILED);
    }

    /* add any CRLs found to our array */
    if (SECSuccess == rv) {
        CERTCrlNode* crlNode = NULL;

        for (crlNode = head.first; crlNode; crlNode = crlNode->next) {
            CachedCrl* returned = NULL;
            CERTSignedCrl* crlobject = crlNode->crl;
            if (!crlobject) {
                PORT_Assert(0);
                continue;
            }
            rv = CachedCrl_Create(&returned, crlobject, CRL_OriginToken);
            if (SECSuccess == rv) {
                PRBool added = PR_FALSE;
                rv = DPCache_AddCRL(cache, returned, &added);
                if (PR_TRUE != added) {
                    rv = CachedCrl_Destroy(returned);
                    returned = NULL;
                } else if (vfdate) {
                    rv = CachedCrl_Verify(cache, returned, vfdate, wincx);
                }
            } else {
                /* not enough memory to add the CRL to the cache. mark it
                   invalid so we will try again . */
                cache->invalid |= CRL_CACHE_LAST_FETCH_FAILED;
            }
            if (SECFailure == rv) {
                break;
            }
        }
    }

    if (head.arena) {
        CERTCrlNode* crlNode = NULL;
        /* clean up the CRL list in case we got a partial one
           during a failed fetch */
        for (crlNode = head.first; crlNode; crlNode = crlNode->next) {
            if (crlNode->crl) {
                SEC_DestroyCrl(crlNode->crl); /* free the CRL. Either it got
                   added to the cache and the refcount got bumped, or not, and
                   thus we need to free its RAM */
            }
        }
        PORT_FreeArena(head.arena, PR_FALSE); /* destroy CRL list */
    }

    return rv;
}

static SECStatus
CachedCrl_GetEntry(CachedCrl* crl, const SECItem* sn, CERTCrlEntry** returned)
{
    CERTCrlEntry* acrlEntry;

    PORT_Assert(crl);
    PORT_Assert(crl->entries);
    PORT_Assert(sn);
    PORT_Assert(returned);
    if (!crl || !sn || !returned || !crl->entries) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    acrlEntry = PL_HashTableLookup(crl->entries, (void*)sn);
    if (acrlEntry) {
        *returned = acrlEntry;
    } else {
        *returned = NULL;
    }
    return SECSuccess;
}

/* check if a particular SN is in the CRL cache and return its entry */
dpcacheStatus
DPCache_Lookup(CRLDPCache* cache, const SECItem* sn, CERTCrlEntry** returned)
{
    SECStatus rv;
    if (!cache || !sn || !returned) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        /* no cache or SN to look up, or no way to return entry */
        return dpcacheCallerError;
    }
    *returned = NULL;
    if (0 != cache->invalid) {
        /* the cache contains a bad CRL, or there was a CRL fetching error. */
        PORT_SetError(SEC_ERROR_CRL_INVALID);
        return dpcacheInvalidCacheError;
    }
    if (!cache->selected) {
        /* no CRL means no entry to return. This is OK, except for
         * NIST policy */
        return dpcacheEmpty;
    }
    rv = CachedCrl_GetEntry(cache->selected, sn, returned);
    if (SECSuccess != rv) {
        return dpcacheLookupError;
    } else {
        if (*returned) {
            return dpcacheFoundEntry;
        } else {
            return dpcacheNoEntry;
        }
    }
}

#if defined(DPC_RWLOCK)

#define DPCache_LockWrite()                    \
    {                                          \
        if (readlocked) {                      \
            NSSRWLock_UnlockRead(cache->lock); \
        }                                      \
        NSSRWLock_LockWrite(cache->lock);      \
    }

#define DPCache_UnlockWrite()                \
    {                                        \
        if (readlocked) {                    \
            NSSRWLock_LockRead(cache->lock); \
        }                                    \
        NSSRWLock_UnlockWrite(cache->lock);  \
    }

#else

/* with a global lock, we are always locked for read before we need write
   access, so do nothing */

#define DPCache_LockWrite() \
    {                       \
    }

#define DPCache_UnlockWrite() \
    {                         \
    }

#endif

/* update the content of the CRL cache, including fetching of CRLs, and
   reprocessing with specified issuer and date . We are always holding
   either the read or write lock on DPCache upon entry. */
static SECStatus
DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate* issuer,
                    PRBool readlocked, PRTime vfdate, void* wincx)
{
    /* Update the CRLDPCache now. We don't cache token CRL lookup misses
       yet, as we have no way of getting notified of new PKCS#11 object
       creation that happens in a token  */
    SECStatus rv = SECSuccess;
    PRUint32 i = 0;
    PRBool forcedrefresh = PR_FALSE;
    PRBool dirty = PR_FALSE; /* whether something was changed in the
                                cache state during this update cycle */
    PRBool hastokenCRLs = PR_FALSE;
    PRTime now = 0;
    PRTime lastfetch = 0;
    PRBool mustunlock = PR_FALSE;

    if (!cache) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    /* first, make sure we have obtained all the CRLs we need.
       We do an expensive token fetch in the following cases :
       1) cache is empty because no fetch was ever performed yet
       2) cache is explicitly set to refresh state
       3) cache is in invalid state because last fetch failed
       4) cache contains no token CRLs, and it's been more than one minute
          since the last fetch
       5) cache contains token CRLs, and it's been more than 10 minutes since
          the last fetch
    */
    forcedrefresh = cache->refresh;
    lastfetch = cache->lastfetch;
    if (PR_TRUE != forcedrefresh &&
        (!(cache->invalid & CRL_CACHE_LAST_FETCH_FAILED))) {
        now = PR_Now();
        hastokenCRLs = DPCache_HasTokenCRLs(cache);
    }
    if ((0 == lastfetch) ||

        (PR_TRUE == forcedrefresh) ||

        (cache->invalid & CRL_CACHE_LAST_FETCH_FAILED) ||

        ((PR_FALSE == hastokenCRLs) &&
         ((now - cache->lastfetch > CRLCache_Empty_TokenFetch_Interval) ||
          (now < cache->lastfetch))) ||

        ((PR_TRUE == hastokenCRLs) &&
         ((now - cache->lastfetch > CRLCache_TokenRefetch_Interval) ||
          (now < cache->lastfetch)))) {
        /* the cache needs to be refreshed, and/or we had zero CRL for this
           DP. Try to get one from PKCS#11 tokens */
        DPCache_LockWrite();
        /* check if another thread updated before us, and skip update if so */
        if (lastfetch == cache->lastfetch) {
            /* we are the first */
            rv = DPCache_FetchFromTokens(cache, vfdate, wincx);
            if (PR_TRUE == cache->refresh) {
                cache->refresh = PR_FALSE; /* clear refresh state */
            }
            dirty = PR_TRUE;
            cache->lastfetch = PR_Now();
        }
        DPCache_UnlockWrite();
    }

    /* now, make sure we have no extraneous CRLs (deleted token objects)
       we'll do this inexpensive existence check either
       1) if there was a token object fetch
       2) every minute */
    if ((PR_TRUE != dirty) && (!now)) {
        now = PR_Now();
    }
    if ((PR_TRUE == dirty) ||
        ((now - cache->lastcheck > CRLCache_ExistenceCheck_Interval) ||
         (now < cache->lastcheck))) {
        PRTime lastcheck = cache->lastcheck;
        mustunlock = PR_FALSE;
        /* check if all CRLs still exist */
        for (i = 0; (i < cache->ncrls); i++) {
            CachedCrl* savcrl = cache->crls[i];
            if ((!savcrl) || (savcrl && CRL_OriginToken != savcrl->origin)) {
                /* we only want to check token CRLs */
                continue;
            }
            if ((PR_TRUE != TokenCRLStillExists(savcrl->crl))) {

                /* this CRL is gone */
                if (PR_TRUE != mustunlock) {
                    DPCache_LockWrite();
                    mustunlock = PR_TRUE;
                }
                /* first, we need to check if another thread did an update
                   before we did */
                if (lastcheck == cache->lastcheck) {
                    /* the CRL is gone. And we are the one to do the update */
                    DPCache_RemoveCRL(cache, i);
                    dirty = PR_TRUE;
                }
                /* stay locked here intentionally so we do all the other
                   updates in this thread for the remaining CRLs */
            }
        }
        if (PR_TRUE == mustunlock) {
            cache->lastcheck = PR_Now();
            DPCache_UnlockWrite();
            mustunlock = PR_FALSE;
        }
    }

    /* add issuer certificate if it was previously unavailable */
    if (issuer && (NULL == cache->issuerDERCert) &&
        (SECSuccess == CERT_CheckCertUsage(issuer, KU_CRL_SIGN))) {
        /* if we didn't have a valid issuer cert yet, but we do now. add it */
        DPCache_LockWrite();
        if (!cache->issuerDERCert) {
            dirty = PR_TRUE;
            cache->dbHandle = issuer->dbhandle;
            cache->issuerDERCert = SECITEM_DupItem(&issuer->derCert);
        }
        DPCache_UnlockWrite();
    }

    /* verify CRLs that couldn't be checked when inserted into the cache
       because the issuer cert or a verification date was unavailable.
       These are CRLs that were inserted into the cache through
       SEC_FindCrlByName, or through manual insertion, rather than through a
       certificate verification (CERT_CheckCRL) */

    if (cache->issuerDERCert && vfdate) {
        mustunlock = PR_FALSE;
        /* re-process all unverified CRLs */
        for (i = 0; i < cache->ncrls; i++) {
            CachedCrl* savcrl = cache->crls[i];
            if (!savcrl) {
                continue;
            }
            if (PR_TRUE != savcrl->sigChecked) {
                if (!mustunlock) {
                    DPCache_LockWrite();
                    mustunlock = PR_TRUE;
                }
                /* first, we need to check if another thread updated
                   it before we did, and abort if it has been modified since
                   we acquired the lock. Make sure first that the CRL is still
                   in the array at the same position */
                if ((i < cache->ncrls) && (savcrl == cache->crls[i]) &&
                    (PR_TRUE != savcrl->sigChecked)) {
                    /* the CRL is still there, unverified. Do it */
                    CachedCrl_Verify(cache, savcrl, vfdate, wincx);
                    dirty = PR_TRUE;
                }
                /* stay locked here intentionally so we do all the other
                   updates in this thread for the remaining CRLs */
            }
            if (mustunlock && !dirty) {
                DPCache_UnlockWrite();
                mustunlock = PR_FALSE;
            }
        }
    }

    if (dirty || cache->mustchoose) {
        /* changes to the content of the CRL cache necessitate examining all
           CRLs for selection of the most appropriate one to cache */
        if (!mustunlock) {
            DPCache_LockWrite();
            mustunlock = PR_TRUE;
        }
        DPCache_SelectCRL(cache);
        cache->mustchoose = PR_FALSE;
    }
    if (mustunlock)
        DPCache_UnlockWrite();

    return rv;
}

/* callback for qsort to sort by thisUpdate */
static int
SortCRLsByThisUpdate(const void* arg1, const void* arg2)
{
    PRTime timea, timeb;
    SECStatus rv = SECSuccess;
    CachedCrl *a, *b;

    a = *(CachedCrl**)arg1;
    b = *(CachedCrl**)arg2;

    if (!a || !b) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        rv = SECFailure;
    }

    if (SECSuccess == rv) {
        rv = DER_DecodeTimeChoice(&timea, &a->crl->crl.lastUpdate);
    }
    if (SECSuccess == rv) {
        rv = DER_DecodeTimeChoice(&timeb, &b->crl->crl.lastUpdate);
    }
    if (SECSuccess == rv) {
        if (timea > timeb) {
            return 1; /* a is better than b */
        }
        if (timea < timeb) {
            return -1; /* a is not as good as b */
        }
    }

    /* if they are equal, or if all else fails, use pointer differences */
    PORT_Assert(a != b); /* they should never be equal */
    return a > b ? 1 : -1;
}

/* callback for qsort to sort a set of disparate CRLs, some of which are
   invalid DER or failed signature check.

   Validated CRLs are differentiated by thisUpdate .
   Validated CRLs are preferred over non-validated CRLs .
   Proper DER CRLs are preferred over non-DER data .
*/
static int
SortImperfectCRLs(const void* arg1, const void* arg2)
{
    CachedCrl *a, *b;

    a = *(CachedCrl**)arg1;
    b = *(CachedCrl**)arg2;

    if (!a || !b) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        PORT_Assert(0);
    } else {
        PRBool aDecoded = PR_FALSE, bDecoded = PR_FALSE;
        if ((PR_TRUE == a->sigValid) && (PR_TRUE == b->sigValid)) {
            /* both CRLs have been validated, choose the latest one */
            return SortCRLsByThisUpdate(arg1, arg2);
        }
        if (PR_TRUE == a->sigValid) {
            return 1; /* a is greater than b */
        }
        if (PR_TRUE == b->sigValid) {
            return -1; /* a is not as good as b */
        }
        aDecoded = GetOpaqueCRLFields(a->crl)->decodingError;
        bDecoded = GetOpaqueCRLFields(b->crl)->decodingError;
        /* neither CRL had its signature check pass */
        if ((PR_FALSE == aDecoded) && (PR_FALSE == bDecoded)) {
            /* both CRLs are proper DER, choose the latest one */
            return SortCRLsByThisUpdate(arg1, arg2);
        }
        if (PR_FALSE == aDecoded) {
            return 1; /* a is better than b */
        }
        if (PR_FALSE == bDecoded) {
            return -1; /* a is not as good as b */
        }
        /* both are invalid DER. sigh. */
    }
    /* if they are equal, or if all else fails, use pointer differences */
    PORT_Assert(a != b); /* they should never be equal */
    return a > b ? 1 : -1;
}

/* Pick best CRL to use . needs write access */
static SECStatus
DPCache_SelectCRL(CRLDPCache* cache)
{
    PRUint32 i;
    PRBool valid = PR_TRUE;
    CachedCrl* selected = NULL;

    PORT_Assert(cache);
    if (!cache) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    /* if any invalid CRL is present, then the CRL cache is
       considered invalid, for security reasons */
    for (i = 0; i < cache->ncrls; i++) {
        if (!cache->crls[i] || !cache->crls[i]->sigChecked ||
            !cache->crls[i]->sigValid) {
            valid = PR_FALSE;
            break;
        }
    }
    if (PR_TRUE == valid) {
        /* all CRLs are valid, clear this error */
        cache->invalid &= (~CRL_CACHE_INVALID_CRLS);
    } else {
        /* some CRLs are invalid, set this error */
        cache->invalid |= CRL_CACHE_INVALID_CRLS;
    }

    if (cache->invalid) {
        /* cache is in an invalid state, so reset it */
        if (cache->selected) {
            cache->selected = NULL;
        }
        /* also sort the CRLs imperfectly */
        qsort(cache->crls, cache->ncrls, sizeof(CachedCrl*), SortImperfectCRLs);
        return SECSuccess;
    }

    if (cache->ncrls) {
        /* all CRLs are good, sort them by thisUpdate */
        qsort(cache->crls, cache->ncrls, sizeof(CachedCrl*), SortCRLsByThisUpdate);

        /* pick the newest CRL */
        selected = cache->crls[cache->ncrls - 1];

        /* and populate the cache */
        if (SECSuccess != CachedCrl_Populate(selected)) {
            return SECFailure;
        }
    }

    cache->selected = selected;

    return SECSuccess;
}

/* initialize a DPCache object */
static SECStatus
DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer,
               const SECItem* subject, SECItem* dp)
{
    CRLDPCache* cache = NULL;
    PORT_Assert(returned);
    /* issuer and dp are allowed to be NULL */
    if (!returned || !subject) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    *returned = NULL;
    cache = PORT_ZAlloc(sizeof(CRLDPCache));
    if (!cache) {
        return SECFailure;
    }
#ifdef DPC_RWLOCK
    cache->lock = NSSRWLock_New(NSS_RWLOCK_RANK_NONE, NULL);
#else
    cache->lock = PR_NewLock();
#endif
    if (!cache->lock) {
        PORT_Free(cache);
        return SECFailure;
    }
    if (issuer) {
        cache->dbHandle = issuer->dbhandle;
        cache->issuerDERCert = SECITEM_DupItem(&issuer->derCert);
    }
    cache->distributionPoint = SECITEM_DupItem(dp);
    cache->subject = SECITEM_DupItem(subject);
    cache->lastfetch = 0;
    cache->lastcheck = 0;
    *returned = cache;
    return SECSuccess;
}

/* create an issuer cache object (per CA subject ) */
static SECStatus
IssuerCache_Create(CRLIssuerCache** returned, CERTCertificate* issuer,
                   const SECItem* subject, const SECItem* dp)
{
    SECStatus rv = SECSuccess;
    CRLIssuerCache* cache = NULL;
    PORT_Assert(returned);
    PORT_Assert(subject);
    /* issuer and dp are allowed to be NULL */
    if (!returned || !subject) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    *returned = NULL;
    cache = (CRLIssuerCache*)PORT_ZAlloc(sizeof(CRLIssuerCache));
    if (!cache) {
        return SECFailure;
    }
    cache->subject = SECITEM_DupItem(subject);
#ifdef XCRL
    cache->lock = NSSRWLock_New(NSS_RWLOCK_RANK_NONE, NULL);
    if (!cache->lock) {
        rv = SECFailure;
    }
    if (SECSuccess == rv && issuer) {
        cache->issuer = CERT_DupCertificate(issuer);
        if (!cache->issuer) {
            rv = SECFailure;
        }
    }
#endif
    if (SECSuccess != rv) {
        PORT_Assert(SECSuccess == IssuerCache_Destroy(cache));
        return SECFailure;
    }
    *returned = cache;
    return SECSuccess;
}

/* add a DPCache to the issuer cache */
static SECStatus
IssuerCache_AddDP(CRLIssuerCache* cache, CERTCertificate* issuer,
                  const SECItem* subject, const SECItem* dp,
                  CRLDPCache** newdpc)
{
    /* now create the required DP cache object */
    if (!cache || !subject || !newdpc) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    if (!dp) {
        /* default distribution point */
        SECStatus rv = DPCache_Create(&cache->dpp, issuer, subject, NULL);
        if (SECSuccess == rv) {
            *newdpc = cache->dpp;
            return SECSuccess;
        }
    } else {
        /* we should never hit this until we support multiple DPs */
        PORT_Assert(dp);
        /* XCRL allocate a new distribution point cache object, initialize it,
           and add it to the hash table of DPs */
    }
    return SECFailure;
}

/* add an IssuerCache to the global hash table of issuers */
static SECStatus
CRLCache_AddIssuer(CRLIssuerCache* issuer)
{
    PORT_Assert(issuer);
    PORT_Assert(crlcache.issuers);
    if (!issuer || !crlcache.issuers) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    if (NULL == PL_HashTableAdd(crlcache.issuers, (void*)issuer->subject,
                                (void*)issuer)) {
        return SECFailure;
    }
    return SECSuccess;
}

/* retrieve the issuer cache object for a given issuer subject */
static SECStatus
CRLCache_GetIssuerCache(CRLCache* cache, const SECItem* subject,
                        CRLIssuerCache** returned)
{
    /* we need to look up the issuer in the hash table */
    SECStatus rv = SECSuccess;
    PORT_Assert(cache);
    PORT_Assert(subject);
    PORT_Assert(returned);
    PORT_Assert(crlcache.issuers);
    if (!cache || !subject || !returned || !crlcache.issuers) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        rv = SECFailure;
    }

    if (SECSuccess == rv) {
        *returned = (CRLIssuerCache*)PL_HashTableLookup(crlcache.issuers,
                                                        (void*)subject);
    }

    return rv;
}

/* retrieve the full CRL object that best matches the content of a DPCache */
static CERTSignedCrl*
GetBestCRL(CRLDPCache* cache, PRBool entries)
{
    CachedCrl* acrl = NULL;

    PORT_Assert(cache);
    if (!cache) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return NULL;
    }

    if (0 == cache->ncrls) {
        /* empty cache*/
        PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
        return NULL;
    }

    /* if we have a valid full CRL selected, return it */
    if (cache->selected) {
        return SEC_DupCrl(cache->selected->crl);
    }

    /* otherwise, use latest valid DER CRL */
    acrl = cache->crls[cache->ncrls - 1];

    if (acrl && (PR_FALSE == GetOpaqueCRLFields(acrl->crl)->decodingError)) {
        SECStatus rv = SECSuccess;
        if (PR_TRUE == entries) {
            rv = CERT_CompleteCRLDecodeEntries(acrl->crl);
        }
        if (SECSuccess == rv) {
            return SEC_DupCrl(acrl->crl);
        }
    }

    PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
    return NULL;
}

/* get a particular DPCache object from an IssuerCache */
static CRLDPCache*
IssuerCache_GetDPCache(CRLIssuerCache* cache, const SECItem* dp)
{
    CRLDPCache* dpp = NULL;
    PORT_Assert(cache);
    /* XCRL for now we only support the "default" DP, ie. the
       full CRL. So we can return the global one without locking. In
       the future we will have a lock */
    PORT_Assert(NULL == dp);
    if (!cache || dp) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return NULL;
    }
#ifdef XCRL
    NSSRWLock_LockRead(cache->lock);
#endif
    dpp = cache->dpp;
#ifdef XCRL
    NSSRWLock_UnlockRead(cache->lock);
#endif
    return dpp;
}

/* get a DPCache object for the given issuer subject and dp
   Automatically creates the cache object if it doesn't exist yet.
   */
SECStatus
AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
               const SECItem* dp, PRTime t, void* wincx, CRLDPCache** dpcache,
               PRBool* writeLocked)
{
    SECStatus rv = SECSuccess;
    CRLIssuerCache* issuercache = NULL;
#ifdef GLOBAL_RWLOCK
    PRBool globalwrite = PR_FALSE;
#endif
    PORT_Assert(crlcache.lock);
    if (!crlcache.lock) {
        /* CRL cache is not initialized */
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
#ifdef GLOBAL_RWLOCK
    NSSRWLock_LockRead(crlcache.lock);
#else
    PR_Lock(crlcache.lock);
#endif
    rv = CRLCache_GetIssuerCache(&crlcache, subject, &issuercache);
    if (SECSuccess != rv) {
#ifdef GLOBAL_RWLOCK
        NSSRWLock_UnlockRead(crlcache.lock);
#else
        PR_Unlock(crlcache.lock);
#endif
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    if (!issuercache) {
        /* there is no cache for this issuer yet. This means this is the
           first time we look up a cert from that issuer, and we need to
           create the cache. */

        rv = IssuerCache_Create(&issuercache, issuer, subject, dp);
        if (SECSuccess == rv && !issuercache) {
            PORT_Assert(issuercache);
            rv = SECFailure;
        }

        if (SECSuccess == rv) {
            /* This is the first time we look up a cert of this issuer.
               Create the DPCache for this DP . */
            rv = IssuerCache_AddDP(issuercache, issuer, subject, dp, dpcache);
        }

        if (SECSuccess == rv) {
            /* lock the DPCache for write to ensure the update happens in this
               thread */
            *writeLocked = PR_TRUE;
#ifdef DPC_RWLOCK
            NSSRWLock_LockWrite((*dpcache)->lock);
#else
            PR_Lock((*dpcache)->lock);
#endif
        }

        if (SECSuccess == rv) {
/* now add the new issuer cache to the global hash table of
   issuers */
#ifdef GLOBAL_RWLOCK
            CRLIssuerCache* existing = NULL;
            NSSRWLock_UnlockRead(crlcache.lock);
            /* when using a r/w lock for the global cache, check if the issuer
               already exists before adding to the hash table */
            NSSRWLock_LockWrite(crlcache.lock);
            globalwrite = PR_TRUE;
            rv = CRLCache_GetIssuerCache(&crlcache, subject, &existing);
            if (!existing) {
#endif
                rv = CRLCache_AddIssuer(issuercache);
                if (SECSuccess != rv) {
                    /* failure */
                    rv = SECFailure;
                }
#ifdef GLOBAL_RWLOCK
            } else {
                /* somebody else updated before we did */
                IssuerCache_Destroy(issuercache); /* destroy the new object */
                issuercache = existing;           /* use the existing one */
                *dpcache = IssuerCache_GetDPCache(issuercache, dp);
            }
#endif
        }

/* now unlock the global cache. We only want to lock the issuer hash
   table addition. Holding it longer would hurt scalability */
#ifdef GLOBAL_RWLOCK
        if (PR_TRUE == globalwrite) {
            NSSRWLock_UnlockWrite(crlcache.lock);
            globalwrite = PR_FALSE;
        } else {
            NSSRWLock_UnlockRead(crlcache.lock);
        }
#else
        PR_Unlock(crlcache.lock);
#endif

        /* if there was a failure adding an issuer cache object, destroy it */
        if (SECSuccess != rv && issuercache) {
            if (PR_TRUE == *writeLocked) {
#ifdef DPC_RWLOCK
                NSSRWLock_UnlockWrite((*dpcache)->lock);
#else
                PR_Unlock((*dpcache)->lock);
#endif
            }
            IssuerCache_Destroy(issuercache);
            issuercache = NULL;
        }

        if (SECSuccess != rv) {
            return SECFailure;
        }
    } else {
#ifdef GLOBAL_RWLOCK
        NSSRWLock_UnlockRead(crlcache.lock);
#else
        PR_Unlock(crlcache.lock);
#endif
        *dpcache = IssuerCache_GetDPCache(issuercache, dp);
    }
    /* we now have a DPCache that we can use for lookups */
    /* lock it for read, unless we already locked for write */
    if (PR_FALSE == *writeLocked) {
#ifdef DPC_RWLOCK
        NSSRWLock_LockRead((*dpcache)->lock);
#else
        PR_Lock((*dpcache)->lock);
#endif
    }

    if (SECSuccess == rv) {
        /* currently there is always one and only one DPCache per issuer */
        PORT_Assert(*dpcache);
        if (*dpcache) {
            /* make sure the DP cache is up to date before using it */
            rv = DPCache_GetUpToDate(*dpcache, issuer, PR_FALSE == *writeLocked,
                                     t, wincx);
        } else {
            rv = SECFailure;
        }
    }
    return rv;
}

/* unlock access to the DPCache */
void
ReleaseDPCache(CRLDPCache* dpcache, PRBool writeLocked)
{
    if (!dpcache) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return;
    }
#ifdef DPC_RWLOCK
    if (PR_TRUE == writeLocked) {
        NSSRWLock_UnlockWrite(dpcache->lock);
    } else {
        NSSRWLock_UnlockRead(dpcache->lock);
    }
#else
    PR_Unlock(dpcache->lock);
#endif
}

SECStatus
cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer,
                               const SECItem* dp, PRTime t, void* wincx,
                               CERTRevocationStatus* revStatus,
                               CERTCRLEntryReasonCode* revReason)
{
    PRBool lockedwrite = PR_FALSE;
    SECStatus rv = SECSuccess;
    CRLDPCache* dpcache = NULL;
    CERTRevocationStatus status = certRevocationStatusRevoked;
    CERTCRLEntryReasonCode reason = crlEntryReasonUnspecified;
    CERTCrlEntry* entry = NULL;
    dpcacheStatus ds;

    if (!cert || !issuer) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    if (revStatus) {
        *revStatus = status;
    }
    if (revReason) {
        *revReason = reason;
    }

    if (t &&
        secCertTimeValid != CERT_CheckCertValidTimes(issuer, t, PR_FALSE)) {
        /* we won't be able to check the CRL's signature if the issuer cert
           is expired as of the time we are verifying. This may cause a valid
           CRL to be cached as bad. short-circuit to avoid this case. */
        PORT_SetError(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE);
        return SECFailure;
    }

    rv = AcquireDPCache(issuer, &issuer->derSubject, dp, t, wincx, &dpcache,
                        &lockedwrite);
    PORT_Assert(SECSuccess == rv);
    if (SECSuccess != rv) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    /* now look up the certificate SN in the DP cache's CRL */
    ds = DPCache_Lookup(dpcache, &cert->serialNumber, &entry);
    switch (ds) {
        case dpcacheFoundEntry:
            PORT_Assert(entry);
            /* check the time if we have one */
            if (entry->revocationDate.data && entry->revocationDate.len) {
                PRTime revocationDate = 0;
                if (SECSuccess ==
                    DER_DecodeTimeChoice(&revocationDate,
                                         &entry->revocationDate)) {
                    /* we got a good revocation date, only consider the
                       certificate revoked if the time we are inquiring about
                       is past the revocation date */
                    if (t >= revocationDate) {
                        rv = SECFailure;
                    } else {
                        status = certRevocationStatusValid;
                    }
                } else {
                    /* invalid revocation date, consider the certificate
                       permanently revoked */
                    rv = SECFailure;
                }
            } else {
                /* no revocation date, certificate is permanently revoked */
                rv = SECFailure;
            }
            if (SECFailure == rv) {
                (void)CERT_FindCRLEntryReasonExten(entry, &reason);
                PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
            }
            break;

        case dpcacheEmpty:
            /* useful for NIST policy */
            status = certRevocationStatusUnknown;
            break;

        case dpcacheNoEntry:
            status = certRevocationStatusValid;
            break;

        case dpcacheInvalidCacheError:
            /* treat it as unknown and let the caller decide based on
               the policy */
            status = certRevocationStatusUnknown;
            break;

        default:
            /* leave status as revoked */
            break;
    }

    ReleaseDPCache(dpcache, lockedwrite);
    if (revStatus) {
        *revStatus = status;
    }
    if (revReason) {
        *revReason = reason;
    }
    return rv;
}

/* check CRL revocation status of given certificate and issuer */
SECStatus
CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer, const SECItem* dp,
              PRTime t, void* wincx)
{
    return cert_CheckCertRevocationStatus(cert, issuer, dp, t, wincx, NULL,
                                          NULL);
}

/* retrieve full CRL object that best matches the cache status */
CERTSignedCrl*
SEC_FindCrlByName(CERTCertDBHandle* handle, SECItem* crlKey, int type)
{
    CERTSignedCrl* acrl = NULL;
    CRLDPCache* dpcache = NULL;
    SECStatus rv = SECSuccess;
    PRBool writeLocked = PR_FALSE;

    if (!crlKey) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    rv = AcquireDPCache(NULL, crlKey, NULL, 0, NULL, &dpcache, &writeLocked);
    if (SECSuccess == rv) {
        acrl = GetBestCRL(dpcache, PR_TRUE); /* decode entries, because
        SEC_FindCrlByName always returned fully decoded CRLs in the past */
        ReleaseDPCache(dpcache, writeLocked);
    }
    return acrl;
}

/* invalidate the CRL cache for a given issuer, which forces a refetch of
   CRL objects from PKCS#11 tokens */
void
CERT_CRLCacheRefreshIssuer(CERTCertDBHandle* dbhandle, SECItem* crlKey)
{
    CRLDPCache* cache = NULL;
    SECStatus rv = SECSuccess;
    PRBool writeLocked = PR_FALSE;
    PRBool readlocked;

    (void)dbhandle; /* silence compiler warnings */

    /* XCRL we will need to refresh all the DPs of the issuer in the future,
            not just the default one */
    rv = AcquireDPCache(NULL, crlKey, NULL, 0, NULL, &cache, &writeLocked);
    if (SECSuccess != rv) {
        return;
    }
    /* we need to invalidate the DPCache here */
    readlocked = (writeLocked == PR_TRUE ? PR_FALSE : PR_TRUE);
    DPCache_LockWrite();
    cache->refresh = PR_TRUE;
    DPCache_UnlockWrite();
    ReleaseDPCache(cache, writeLocked);
    return;
}

/* add the specified RAM CRL object to the cache */
SECStatus
CERT_CacheCRL(CERTCertDBHandle* dbhandle, SECItem* newdercrl)
{
    CRLDPCache* cache = NULL;
    SECStatus rv = SECSuccess;
    PRBool writeLocked = PR_FALSE;
    PRBool readlocked;
    CachedCrl* returned = NULL;
    PRBool added = PR_FALSE;
    CERTSignedCrl* newcrl = NULL;
    int realerror = 0;

    if (!dbhandle || !newdercrl) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* first decode the DER CRL to make sure it's OK */
    newcrl = CERT_DecodeDERCrlWithFlags(NULL, newdercrl, SEC_CRL_TYPE,
                                        CRL_DECODE_DONT_COPY_DER |
                                            CRL_DECODE_SKIP_ENTRIES);

    if (!newcrl) {
        return SECFailure;
    }

    /* XXX check if it has IDP extension. If so, do not proceed and set error */

    rv = AcquireDPCache(NULL, &newcrl->crl.derName, NULL, 0, NULL, &cache,
                        &writeLocked);
    if (SECSuccess == rv) {
        readlocked = (writeLocked == PR_TRUE ? PR_FALSE : PR_TRUE);

        rv = CachedCrl_Create(&returned, newcrl, CRL_OriginExplicit);
        if (SECSuccess == rv && returned) {
            DPCache_LockWrite();
            rv = DPCache_AddCRL(cache, returned, &added);
            if (PR_TRUE != added) {
                realerror = PORT_GetError();
                CachedCrl_Destroy(returned);
                returned = NULL;
            }
            DPCache_UnlockWrite();
        }

        ReleaseDPCache(cache, writeLocked);

        if (!added) {
            rv = SECFailure;
        }
    }
    SEC_DestroyCrl(newcrl); /* free the CRL. Either it got added to the cache
        and the refcount got bumped, or not, and thus we need to free its
        RAM */
    if (realerror) {
        PORT_SetError(realerror);
    }
    return rv;
}

/* remove the specified RAM CRL object from the cache */
SECStatus
CERT_UncacheCRL(CERTCertDBHandle* dbhandle, SECItem* olddercrl)
{
    CRLDPCache* cache = NULL;
    SECStatus rv = SECSuccess;
    PRBool writeLocked = PR_FALSE;
    PRBool readlocked;
    PRBool removed = PR_FALSE;
    PRUint32 i;
    CERTSignedCrl* oldcrl = NULL;

    if (!dbhandle || !olddercrl) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* first decode the DER CRL to make sure it's OK */
    oldcrl = CERT_DecodeDERCrlWithFlags(NULL, olddercrl, SEC_CRL_TYPE,
                                        CRL_DECODE_DONT_COPY_DER |
                                            CRL_DECODE_SKIP_ENTRIES);

    if (!oldcrl) {
        /* if this DER CRL can't decode, it can't be in the cache */
        return SECFailure;
    }

    rv = AcquireDPCache(NULL, &oldcrl->crl.derName, NULL, 0, NULL, &cache,
                        &writeLocked);
    if (SECSuccess == rv) {
        CachedCrl* returned = NULL;

        readlocked = (writeLocked == PR_TRUE ? PR_FALSE : PR_TRUE);

        rv = CachedCrl_Create(&returned, oldcrl, CRL_OriginExplicit);
        if (SECSuccess == rv && returned) {
            DPCache_LockWrite();
            for (i = 0; i < cache->ncrls; i++) {
                PRBool dupe = PR_FALSE, updated = PR_FALSE;
                rv = CachedCrl_Compare(returned, cache->crls[i], &dupe,
                                       &updated);
                if (SECSuccess != rv) {
                    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
                    break;
                }
                if (PR_TRUE == dupe) {
                    rv = DPCache_RemoveCRL(cache, i); /* got a match */
                    if (SECSuccess == rv) {
                        cache->mustchoose = PR_TRUE;
                        removed = PR_TRUE;
                    }
                    break;
                }
            }

            DPCache_UnlockWrite();

            if (SECSuccess != CachedCrl_Destroy(returned)) {
                rv = SECFailure;
            }
        }

        ReleaseDPCache(cache, writeLocked);
    }
    if (SECSuccess != SEC_DestroyCrl(oldcrl)) {
        /* need to do this because object is refcounted */
        rv = SECFailure;
    }
    if (SECSuccess == rv && PR_TRUE != removed) {
        PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
    }
    return rv;
}

SECStatus
cert_AcquireNamedCRLCache(NamedCRLCache** returned)
{
    PORT_Assert(returned);
    if (!namedCRLCache.lock) {
        PORT_Assert(0);
        return SECFailure;
    }
    PR_Lock(namedCRLCache.lock);
    *returned = &namedCRLCache;
    return SECSuccess;
}

/* This must be called only while cache is acquired, and the entry is only
 * valid until cache is released.
 */
SECStatus
cert_FindCRLByGeneralName(NamedCRLCache* ncc, const SECItem* canonicalizedName,
                          NamedCRLCacheEntry** retEntry)
{
    if (!ncc || !canonicalizedName || !retEntry) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    *retEntry = (NamedCRLCacheEntry*)PL_HashTableLookup(
        namedCRLCache.entries, (void*)canonicalizedName);
    return SECSuccess;
}

SECStatus
cert_ReleaseNamedCRLCache(NamedCRLCache* ncc)
{
    if (!ncc) {
        return SECFailure;
    }
    if (!ncc->lock) {
        PORT_Assert(0);
        return SECFailure;
    }
    PR_Unlock(namedCRLCache.lock);
    return SECSuccess;
}

/* creates new named cache entry from CRL, and tries to add it to CRL cache */
static SECStatus
addCRLToCache(CERTCertDBHandle* dbhandle, SECItem* crl,
              const SECItem* canonicalizedName, NamedCRLCacheEntry** newEntry)
{
    SECStatus rv = SECSuccess;
    NamedCRLCacheEntry* entry = NULL;

    /* create new named entry */
    if (SECSuccess != NamedCRLCacheEntry_Create(newEntry) || !*newEntry) {
        /* no need to keep unused CRL around */
        SECITEM_ZfreeItem(crl, PR_TRUE);
        return SECFailure;
    }
    entry = *newEntry;
    entry->crl = crl; /* named CRL cache owns DER */
    entry->lastAttemptTime = PR_Now();
    entry->canonicalizedName = SECITEM_DupItem(canonicalizedName);
    if (!entry->canonicalizedName) {
        rv = NamedCRLCacheEntry_Destroy(entry); /* destroys CRL too */
        PORT_Assert(SECSuccess == rv);
        return SECFailure;
    }
    /* now, attempt to insert CRL into CRL cache */
    if (SECSuccess == CERT_CacheCRL(dbhandle, entry->crl)) {
        entry->inCRLCache = PR_TRUE;
        entry->successfulInsertionTime = entry->lastAttemptTime;
    } else {
        switch (PR_GetError()) {
            case SEC_ERROR_CRL_ALREADY_EXISTS:
                entry->dupe = PR_TRUE;
                break;

            case SEC_ERROR_BAD_DER:
                entry->badDER = PR_TRUE;
                break;

            /* all other reasons */
            default:
                entry->unsupported = PR_TRUE;
                break;
        }
        rv = SECFailure;
        /* no need to keep unused CRL around */
        SECITEM_ZfreeItem(entry->crl, PR_TRUE);
        entry->crl = NULL;
    }
    return rv;
}

/* take ownership of CRL, and insert it into the named CRL cache
 * and indexed CRL cache
 */
SECStatus
cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl,
                           const SECItem* canonicalizedName)
{
    NamedCRLCacheEntry *oldEntry, *newEntry = NULL;
    NamedCRLCache* ncc = NULL;
    SECStatus rv = SECSuccess;

    PORT_Assert(namedCRLCache.lock);
    PORT_Assert(namedCRLCache.entries);

    if (!crl || !canonicalizedName) {
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    rv = cert_AcquireNamedCRLCache(&ncc);
    PORT_Assert(SECSuccess == rv);
    if (SECSuccess != rv) {
        SECITEM_ZfreeItem(crl, PR_TRUE);
        return SECFailure;
    }
    rv = cert_FindCRLByGeneralName(ncc, canonicalizedName, &oldEntry);
    PORT_Assert(SECSuccess == rv);
    if (SECSuccess != rv) {
        (void)cert_ReleaseNamedCRLCache(ncc);
        SECITEM_ZfreeItem(crl, PR_TRUE);
        return SECFailure;
    }
    if (SECSuccess ==
        addCRLToCache(dbhandle, crl, canonicalizedName, &newEntry)) {
        if (!oldEntry) {
            /* add new good entry to the hash table */
            if (NULL == PL_HashTableAdd(namedCRLCache.entries,
                                        (void*)newEntry->canonicalizedName,
                                        (void*)newEntry)) {
                PORT_Assert(0);
                NamedCRLCacheEntry_Destroy(newEntry);
                rv = SECFailure;
            }
        } else {
            PRBool removed;
            /* remove the old CRL from the cache if needed */
            if (oldEntry->inCRLCache) {
                rv = CERT_UncacheCRL(dbhandle, oldEntry->crl);
                PORT_Assert(SECSuccess == rv);
            }
            removed = PL_HashTableRemove(namedCRLCache.entries,
                                         (void*)oldEntry->canonicalizedName);
            PORT_Assert(removed);
            if (!removed) {
                rv = SECFailure;
                /* leak old entry since we couldn't remove it from the hash
                 * table */
            } else {
                PORT_CheckSuccess(NamedCRLCacheEntry_Destroy(oldEntry));
            }
            if (NULL == PL_HashTableAdd(namedCRLCache.entries,
                                        (void*)newEntry->canonicalizedName,
                                        (void*)newEntry)) {
                PORT_Assert(0);
                rv = SECFailure;
            }
        }
    } else {
        /* error adding new CRL to cache */
        if (!oldEntry) {
            /* no old cache entry, use the new one even though it's bad */
            if (NULL == PL_HashTableAdd(namedCRLCache.entries,
                                        (void*)newEntry->canonicalizedName,
                                        (void*)newEntry)) {
                PORT_Assert(0);
                rv = SECFailure;
            }
        } else {
            if (oldEntry->inCRLCache) {
                /* previous cache entry was good, keep it and update time */
                oldEntry->lastAttemptTime = newEntry->lastAttemptTime;
                /* throw away new bad entry */
                rv = NamedCRLCacheEntry_Destroy(newEntry);
                PORT_Assert(SECSuccess == rv);
            } else {
                /* previous cache entry was bad, just replace it */
                PRBool removed = PL_HashTableRemove(
                    namedCRLCache.entries, (void*)oldEntry->canonicalizedName);
                PORT_Assert(removed);
                if (!removed) {
                    /* leak old entry since we couldn't remove it from the hash
                     * table */
                    rv = SECFailure;
                } else {
                    PORT_CheckSuccess(NamedCRLCacheEntry_Destroy(oldEntry));
                }
                if (NULL == PL_HashTableAdd(namedCRLCache.entries,
                                            (void*)newEntry->canonicalizedName,
                                            (void*)newEntry)) {
                    PORT_Assert(0);
                    rv = SECFailure;
                }
            }
        }
    }
    PORT_CheckSuccess(cert_ReleaseNamedCRLCache(ncc));

    return rv;
}

static SECStatus
CachedCrl_Create(CachedCrl** returned, CERTSignedCrl* crl, CRLOrigin origin)
{
    CachedCrl* newcrl = NULL;
    if (!returned) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    newcrl = PORT_ZAlloc(sizeof(CachedCrl));
    if (!newcrl) {
        return SECFailure;
    }
    newcrl->crl = SEC_DupCrl(crl);
    newcrl->origin = origin;
    *returned = newcrl;
    return SECSuccess;
}

/* empty the cache content */
static SECStatus
CachedCrl_Depopulate(CachedCrl* crl)
{
    if (!crl) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    /* destroy the hash table */
    if (crl->entries) {
        PL_HashTableDestroy(crl->entries);
        crl->entries = NULL;
    }

    /* free the pre buffer */
    if (crl->prebuffer) {
        PreAllocator_Destroy(crl->prebuffer);
        crl->prebuffer = NULL;
    }
    return SECSuccess;
}

static SECStatus
CachedCrl_Destroy(CachedCrl* crl)
{
    if (!crl) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    CachedCrl_Depopulate(crl);
    SEC_DestroyCrl(crl->crl);
    PORT_Free(crl);
    return SECSuccess;
}

/* create hash table of CRL entries */
static SECStatus
CachedCrl_Populate(CachedCrl* crlobject)
{
    SECStatus rv = SECFailure;
    CERTCrlEntry** crlEntry = NULL;
    PRUint32 numEntries = 0;

    if (!crlobject) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    /* complete the entry decoding . XXX thread-safety of CRL object */
    rv = CERT_CompleteCRLDecodeEntries(crlobject->crl);
    if (SECSuccess != rv) {
        crlobject->unbuildable = PR_TRUE; /* don't try to build this again */
        return SECFailure;
    }

    if (crlobject->entries && crlobject->prebuffer) {
        /* cache is already built */
        return SECSuccess;
    }

    /* build the hash table from the full CRL */
    /* count CRL entries so we can pre-allocate space for hash table entries */
    for (crlEntry = crlobject->crl->crl.entries; crlEntry && *crlEntry;
         crlEntry++) {
        numEntries++;
    }
    crlobject->prebuffer =
        PreAllocator_Create(numEntries * sizeof(PLHashEntry));
    PORT_Assert(crlobject->prebuffer);
    if (!crlobject->prebuffer) {
        return SECFailure;
    }
    /* create a new hash table */
    crlobject->entries =
        PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare, PL_CompareValues,
                        &preAllocOps, crlobject->prebuffer);
    PORT_Assert(crlobject->entries);
    if (!crlobject->entries) {
        return SECFailure;
    }
    /* add all serial numbers to the hash table */
    for (crlEntry = crlobject->crl->crl.entries; crlEntry && *crlEntry;
         crlEntry++) {
        PL_HashTableAdd(crlobject->entries, &(*crlEntry)->serialNumber,
                        *crlEntry);
    }

    return SECSuccess;
}

/* returns true if there are CRLs from PKCS#11 slots */
static PRBool
DPCache_HasTokenCRLs(CRLDPCache* cache)
{
    PRBool answer = PR_FALSE;
    PRUint32 i;
    for (i = 0; i < cache->ncrls; i++) {
        if (cache->crls[i] && (CRL_OriginToken == cache->crls[i]->origin)) {
            answer = PR_TRUE;
            break;
        }
    }
    return answer;
}

/* are these CRLs the same, as far as the cache is concerned ? */
/* are these CRLs the same token object but with different DER ?
   This can happen if the DER CRL got updated in the token, but the PKCS#11
   object ID did not change. NSS softoken has the unfortunate property to
   never change the object ID for CRL objects. */
static SECStatus
CachedCrl_Compare(CachedCrl* a, CachedCrl* b, PRBool* isDupe, PRBool* isUpdated)
{
    PORT_Assert(a);
    PORT_Assert(b);
    PORT_Assert(isDupe);
    PORT_Assert(isUpdated);
    if (!a || !b || !isDupe || !isUpdated || !a->crl || !b->crl) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    *isDupe = *isUpdated = PR_FALSE;

    if (a == b) {
        /* dupe */
        *isDupe = PR_TRUE;
        *isUpdated = PR_FALSE;
        return SECSuccess;
    }
    if (b->origin != a->origin) {
        /* CRLs of different origins are not considered dupes,
           and can't be updated either */
        return SECSuccess;
    }
    if (CRL_OriginToken == b->origin) {
        /* for token CRLs, slot and PKCS#11 object handle must match for CRL
           to truly be a dupe */
        if ((b->crl->slot == a->crl->slot) &&
            (b->crl->pkcs11ID == a->crl->pkcs11ID)) {
            /* ASN.1 DER needs to match for dupe check */
            /* could optimize by just checking a few fields like thisUpdate */
            if (SECEqual ==
                SECITEM_CompareItem(b->crl->derCrl, a->crl->derCrl)) {
                *isDupe = PR_TRUE;
            } else {
                *isUpdated = PR_TRUE;
            }
        }
        return SECSuccess;
    }
    if (CRL_OriginExplicit == b->origin) {
        /* We need to make sure this is the same object that the user provided
           to CERT_CacheCRL previously. That API takes a SECItem*, thus, we
           just do a pointer comparison here.
        */
        if (b->crl->derCrl == a->crl->derCrl) {
            *isDupe = PR_TRUE;
        }
    }
    return SECSuccess;
}
