/* 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* PreAllocator)
{
    if (!PreAllocator) {
        return;
    }
    if (PreAllocator->arena) {
        PORT_FreeArena(PreAllocator->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;
    }
    /* all CRLs are good, sort them by thisUpdate */
    qsort(cache->crls, cache->ncrls, sizeof(CachedCrl*), SortCRLsByThisUpdate);

    if (cache->ncrls) {
        /* 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) {
        rv = 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;
}
