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

/*
 * Implementation of OCSP services, for both client and server.
 * (XXX, really, mostly just for client right now, but intended to do both.)
 */

#include "prerror.h"
#include "prprf.h"
#include "plarena.h"
#include "prnetdb.h"

#include "seccomon.h"
#include "secitem.h"
#include "secoidt.h"
#include "secasn1.h"
#include "secder.h"
#include "cert.h"
#include "certi.h"
#include "xconst.h"
#include "secerr.h"
#include "secoid.h"
#include "hasht.h"
#include "sechash.h"
#include "secasn1.h"
#include "plbase64.h"
#include "keyhi.h"
#include "cryptohi.h"
#include "ocsp.h"
#include "ocspti.h"
#include "ocspi.h"
#include "genname.h"
#include "certxutl.h"
#include "pk11func.h" /* for PK11_HashBuf */
#include <stdarg.h>
#include <plhash.h>

#define DEFAULT_OCSP_CACHE_SIZE 1000
#define DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT 1 * 60 * 60L
#define DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT 24 * 60 * 60L
#define DEFAULT_OSCP_TIMEOUT_SECONDS 60
#define MICROSECONDS_PER_SECOND 1000000L

typedef struct OCSPCacheItemStr OCSPCacheItem;
typedef struct OCSPCacheDataStr OCSPCacheData;

struct OCSPCacheItemStr {
    /* LRU linking */
    OCSPCacheItem *moreRecent;
    OCSPCacheItem *lessRecent;

    /* key */
    CERTOCSPCertID *certID;
    /* CertID's arena also used to allocate "this" cache item */

    /* cache control information */
    PRTime nextFetchAttemptTime;

    /* Cached contents. Use a separate arena, because lifetime is different */
    PLArenaPool *certStatusArena; /* NULL means: no cert status cached */
    ocspCertStatus certStatus;

    /* This may contain an error code when no OCSP response is available. */
    SECErrorCodes missingResponseError;

    PRPackedBool haveThisUpdate;
    PRPackedBool haveNextUpdate;
    PRTime thisUpdate;
    PRTime nextUpdate;
};

struct OCSPCacheDataStr {
    PLHashTable *entries;
    PRUint32 numberOfEntries;
    OCSPCacheItem *MRUitem; /* most recently used cache item */
    OCSPCacheItem *LRUitem; /* least recently used cache item */
};

static struct OCSPGlobalStruct {
    PRMonitor *monitor;
    const SEC_HttpClientFcn *defaultHttpClientFcn;
    PRInt32 maxCacheEntries;
    PRUint32 minimumSecondsToNextFetchAttempt;
    PRUint32 maximumSecondsToNextFetchAttempt;
    PRUint32 timeoutSeconds;
    OCSPCacheData cache;
    SEC_OcspFailureMode ocspFailureMode;
    CERT_StringFromCertFcn alternateOCSPAIAFcn;
    PRBool forcePost;
} OCSP_Global = { NULL,
                  NULL,
                  DEFAULT_OCSP_CACHE_SIZE,
                  DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT,
                  DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT,
                  DEFAULT_OSCP_TIMEOUT_SECONDS,
                  { NULL, 0, NULL, NULL },
                  ocspMode_FailureIsVerificationFailure,
                  NULL,
                  PR_FALSE };

/* Forward declarations */
static SECItem *
ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena,
                                       CERTOCSPRequest *request,
                                       const char *location,
                                       const char *method,
                                       PRTime time,
                                       PRBool addServiceLocator,
                                       void *pwArg,
                                       CERTOCSPRequest **pRequest);
static SECStatus
ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
                              CERTOCSPCertID *certID,
                              CERTCertificate *cert,
                              PRTime time,
                              void *pwArg,
                              PRBool *certIDWasConsumed,
                              SECStatus *rv_ocsp);

static SECStatus
ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle,
                                           CERTOCSPCertID *certID,
                                           CERTCertificate *cert,
                                           PRTime time,
                                           void *pwArg,
                                           const SECItem *encodedResponse,
                                           CERTOCSPResponse **pDecodedResponse,
                                           CERTOCSPSingleResponse **pSingle);

static SECStatus
ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, PRTime time);

static CERTOCSPCertID *
cert_DupOCSPCertID(const CERTOCSPCertID *src);

#ifndef DEBUG
#define OCSP_TRACE(msg)
#define OCSP_TRACE_TIME(msg, time)
#define OCSP_TRACE_CERT(cert)
#define OCSP_TRACE_CERTID(certid)
#else
#define OCSP_TRACE(msg) ocsp_Trace msg
#define OCSP_TRACE_TIME(msg, time) ocsp_dumpStringWithTime(msg, time)
#define OCSP_TRACE_CERT(cert) dumpCertificate(cert)
#define OCSP_TRACE_CERTID(certid) dumpCertID(certid)

#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS) || \
    defined(XP_MACOSX)
#define NSS_HAVE_GETENV 1
#endif

static PRBool
wantOcspTrace(void)
{
    static PRBool firstTime = PR_TRUE;
    static PRBool wantTrace = PR_FALSE;

#ifdef NSS_HAVE_GETENV
    if (firstTime) {
        char *ev = PR_GetEnvSecure("NSS_TRACE_OCSP");
        if (ev && ev[0]) {
            wantTrace = PR_TRUE;
        }
        firstTime = PR_FALSE;
    }
#endif
    return wantTrace;
}

static void
ocsp_Trace(const char *format, ...)
{
    char buf[2000];
    va_list args;

    if (!wantOcspTrace())
        return;
    va_start(args, format);
    PR_vsnprintf(buf, sizeof(buf), format, args);
    va_end(args);
    PR_LogPrint("%s", buf);
}

static void
ocsp_dumpStringWithTime(const char *str, PRTime time)
{
    PRExplodedTime timePrintable;
    char timestr[256];

    if (!wantOcspTrace())
        return;
    PR_ExplodeTime(time, PR_GMTParameters, &timePrintable);
    if (PR_FormatTime(timestr, 256, "%a %b %d %H:%M:%S %Y", &timePrintable)) {
        ocsp_Trace("OCSP %s %s\n", str, timestr);
    }
}

static void
printHexString(const char *prefix, SECItem *hexval)
{
    unsigned int i;
    char *hexbuf = NULL;

    for (i = 0; i < hexval->len; i++) {
        if (i != hexval->len - 1) {
            hexbuf = PR_sprintf_append(hexbuf, "%02x:", hexval->data[i]);
        } else {
            hexbuf = PR_sprintf_append(hexbuf, "%02x", hexval->data[i]);
        }
    }
    if (hexbuf) {
        ocsp_Trace("%s %s\n", prefix, hexbuf);
        PR_smprintf_free(hexbuf);
    }
}

static void
dumpCertificate(CERTCertificate *cert)
{
    if (!wantOcspTrace())
        return;

    ocsp_Trace("OCSP ----------------\n");
    ocsp_Trace("OCSP ## SUBJECT:  %s\n", cert->subjectName);
    {
        PRTime timeBefore, timeAfter;
        PRExplodedTime beforePrintable, afterPrintable;
        char beforestr[256], afterstr[256];
        PRStatus rv1, rv2;
        DER_DecodeTimeChoice(&timeBefore, &cert->validity.notBefore);
        DER_DecodeTimeChoice(&timeAfter, &cert->validity.notAfter);
        PR_ExplodeTime(timeBefore, PR_GMTParameters, &beforePrintable);
        PR_ExplodeTime(timeAfter, PR_GMTParameters, &afterPrintable);
        rv1 = PR_FormatTime(beforestr, 256, "%a %b %d %H:%M:%S %Y",
                            &beforePrintable);
        rv2 = PR_FormatTime(afterstr, 256, "%a %b %d %H:%M:%S %Y",
                            &afterPrintable);
        ocsp_Trace("OCSP ## VALIDITY:  %s to %s\n", rv1 ? beforestr : "",
                   rv2 ? afterstr : "");
    }
    ocsp_Trace("OCSP ## ISSUER:  %s\n", cert->issuerName);
    printHexString("OCSP ## SERIAL NUMBER:", &cert->serialNumber);
}

static void
dumpCertID(CERTOCSPCertID *certID)
{
    if (!wantOcspTrace())
        return;

    printHexString("OCSP certID issuer", &certID->issuerNameHash);
    printHexString("OCSP certID serial", &certID->serialNumber);
}
#endif

SECStatus
SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable)
{
    if (!OCSP_Global.monitor) {
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
        return SECFailure;
    }

    PR_EnterMonitor(OCSP_Global.monitor);
    OCSP_Global.defaultHttpClientFcn = fcnTable;
    PR_ExitMonitor(OCSP_Global.monitor);

    return SECSuccess;
}

SECStatus
CERT_RegisterAlternateOCSPAIAInfoCallBack(
    CERT_StringFromCertFcn newCallback,
    CERT_StringFromCertFcn *oldCallback)
{
    CERT_StringFromCertFcn old;

    if (!OCSP_Global.monitor) {
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
        return SECFailure;
    }

    PR_EnterMonitor(OCSP_Global.monitor);
    old = OCSP_Global.alternateOCSPAIAFcn;
    OCSP_Global.alternateOCSPAIAFcn = newCallback;
    PR_ExitMonitor(OCSP_Global.monitor);
    if (oldCallback)
        *oldCallback = old;
    return SECSuccess;
}

static PLHashNumber PR_CALLBACK
ocsp_CacheKeyHashFunction(const void *key)
{
    CERTOCSPCertID *cid = (CERTOCSPCertID *)key;
    PLHashNumber hash = 0;
    unsigned int i;
    unsigned char *walk;

    /* a very simple hash calculation for the initial coding phase */
    walk = (unsigned char *)cid->issuerNameHash.data;
    for (i = 0; i < cid->issuerNameHash.len; ++i, ++walk) {
        hash += *walk;
    }
    walk = (unsigned char *)cid->issuerKeyHash.data;
    for (i = 0; i < cid->issuerKeyHash.len; ++i, ++walk) {
        hash += *walk;
    }
    walk = (unsigned char *)cid->serialNumber.data;
    for (i = 0; i < cid->serialNumber.len; ++i, ++walk) {
        hash += *walk;
    }
    return hash;
}

static PRIntn PR_CALLBACK
ocsp_CacheKeyCompareFunction(const void *v1, const void *v2)
{
    CERTOCSPCertID *cid1 = (CERTOCSPCertID *)v1;
    CERTOCSPCertID *cid2 = (CERTOCSPCertID *)v2;

    return (SECEqual == SECITEM_CompareItem(&cid1->issuerNameHash,
                                            &cid2->issuerNameHash) &&
            SECEqual == SECITEM_CompareItem(&cid1->issuerKeyHash,
                                            &cid2->issuerKeyHash) &&
            SECEqual == SECITEM_CompareItem(&cid1->serialNumber,
                                            &cid2->serialNumber));
}

static SECStatus
ocsp_CopyRevokedInfo(PLArenaPool *arena, ocspCertStatus *dest,
                     ocspRevokedInfo *src)
{
    SECStatus rv = SECFailure;
    void *mark;

    mark = PORT_ArenaMark(arena);

    dest->certStatusInfo.revokedInfo =
        (ocspRevokedInfo *)PORT_ArenaZAlloc(arena, sizeof(ocspRevokedInfo));
    if (!dest->certStatusInfo.revokedInfo) {
        goto loser;
    }

    rv = SECITEM_CopyItem(arena,
                          &dest->certStatusInfo.revokedInfo->revocationTime,
                          &src->revocationTime);
    if (rv != SECSuccess) {
        goto loser;
    }

    if (src->revocationReason) {
        dest->certStatusInfo.revokedInfo->revocationReason =
            SECITEM_ArenaDupItem(arena, src->revocationReason);
        if (!dest->certStatusInfo.revokedInfo->revocationReason) {
            goto loser;
        }
    } else {
        dest->certStatusInfo.revokedInfo->revocationReason = NULL;
    }

    PORT_ArenaUnmark(arena, mark);
    return SECSuccess;

loser:
    PORT_ArenaRelease(arena, mark);
    return SECFailure;
}

static SECStatus
ocsp_CopyCertStatus(PLArenaPool *arena, ocspCertStatus *dest,
                    ocspCertStatus *src)
{
    SECStatus rv = SECFailure;
    dest->certStatusType = src->certStatusType;

    switch (src->certStatusType) {
        case ocspCertStatus_good:
            dest->certStatusInfo.goodInfo =
                SECITEM_ArenaDupItem(arena, src->certStatusInfo.goodInfo);
            if (dest->certStatusInfo.goodInfo != NULL) {
                rv = SECSuccess;
            }
            break;
        case ocspCertStatus_revoked:
            rv = ocsp_CopyRevokedInfo(arena, dest,
                                      src->certStatusInfo.revokedInfo);
            break;
        case ocspCertStatus_unknown:
            dest->certStatusInfo.unknownInfo =
                SECITEM_ArenaDupItem(arena, src->certStatusInfo.unknownInfo);
            if (dest->certStatusInfo.unknownInfo != NULL) {
                rv = SECSuccess;
            }
            break;
        case ocspCertStatus_other:
        default:
            PORT_Assert(src->certStatusType == ocspCertStatus_other);
            dest->certStatusInfo.otherInfo =
                SECITEM_ArenaDupItem(arena, src->certStatusInfo.otherInfo);
            if (dest->certStatusInfo.otherInfo != NULL) {
                rv = SECSuccess;
            }
            break;
    }
    return rv;
}

static void
ocsp_AddCacheItemToLinkedList(OCSPCacheData *cache, OCSPCacheItem *new_most_recent)
{
    PR_EnterMonitor(OCSP_Global.monitor);

    if (!cache->LRUitem) {
        cache->LRUitem = new_most_recent;
    }
    new_most_recent->lessRecent = cache->MRUitem;
    new_most_recent->moreRecent = NULL;

    if (cache->MRUitem) {
        cache->MRUitem->moreRecent = new_most_recent;
    }
    cache->MRUitem = new_most_recent;

    PR_ExitMonitor(OCSP_Global.monitor);
}

static void
ocsp_RemoveCacheItemFromLinkedList(OCSPCacheData *cache, OCSPCacheItem *item)
{
    PR_EnterMonitor(OCSP_Global.monitor);

    if (!item->lessRecent && !item->moreRecent) {
        /*
         * Fail gracefully on attempts to remove an item from the list,
         * which is currently not part of the list.
         * But check for the edge case it is the single entry in the list.
         */
        if (item == cache->LRUitem &&
            item == cache->MRUitem) {
            /* remove the single entry */
            PORT_Assert(cache->numberOfEntries == 1);
            PORT_Assert(item->moreRecent == NULL);
            cache->MRUitem = NULL;
            cache->LRUitem = NULL;
        }
        PR_ExitMonitor(OCSP_Global.monitor);
        return;
    }

    PORT_Assert(cache->numberOfEntries > 1);

    if (item == cache->LRUitem) {
        PORT_Assert(item != cache->MRUitem);
        PORT_Assert(item->lessRecent == NULL);
        PORT_Assert(item->moreRecent != NULL);
        PORT_Assert(item->moreRecent->lessRecent == item);
        cache->LRUitem = item->moreRecent;
        cache->LRUitem->lessRecent = NULL;
    } else if (item == cache->MRUitem) {
        PORT_Assert(item->moreRecent == NULL);
        PORT_Assert(item->lessRecent != NULL);
        PORT_Assert(item->lessRecent->moreRecent == item);
        cache->MRUitem = item->lessRecent;
        cache->MRUitem->moreRecent = NULL;
    } else {
        /* remove an entry in the middle of the list */
        PORT_Assert(item->moreRecent != NULL);
        PORT_Assert(item->lessRecent != NULL);
        PORT_Assert(item->lessRecent->moreRecent == item);
        PORT_Assert(item->moreRecent->lessRecent == item);
        item->moreRecent->lessRecent = item->lessRecent;
        item->lessRecent->moreRecent = item->moreRecent;
    }

    item->lessRecent = NULL;
    item->moreRecent = NULL;

    PR_ExitMonitor(OCSP_Global.monitor);
}

static void
ocsp_MakeCacheEntryMostRecent(OCSPCacheData *cache, OCSPCacheItem *new_most_recent)
{
    OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent THREADID %p\n",
                PR_GetCurrentThread()));
    PR_EnterMonitor(OCSP_Global.monitor);
    if (cache->MRUitem == new_most_recent) {
        OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent ALREADY MOST\n"));
        PR_ExitMonitor(OCSP_Global.monitor);
        return;
    }
    OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent NEW entry\n"));
    ocsp_RemoveCacheItemFromLinkedList(cache, new_most_recent);
    ocsp_AddCacheItemToLinkedList(cache, new_most_recent);
    PR_ExitMonitor(OCSP_Global.monitor);
}

static PRBool
ocsp_IsCacheDisabled(void)
{
    /*
     * maxCacheEntries == 0 means unlimited cache entries
     * maxCacheEntries  < 0 means cache is disabled
     */
    PRBool retval;
    PR_EnterMonitor(OCSP_Global.monitor);
    retval = (OCSP_Global.maxCacheEntries < 0);
    PR_ExitMonitor(OCSP_Global.monitor);
    return retval;
}

static OCSPCacheItem *
ocsp_FindCacheEntry(OCSPCacheData *cache, CERTOCSPCertID *certID)
{
    OCSPCacheItem *found_ocsp_item = NULL;
    OCSP_TRACE(("OCSP ocsp_FindCacheEntry\n"));
    OCSP_TRACE_CERTID(certID);
    PR_EnterMonitor(OCSP_Global.monitor);
    if (ocsp_IsCacheDisabled())
        goto loser;

    found_ocsp_item = (OCSPCacheItem *)PL_HashTableLookup(
        cache->entries, certID);
    if (!found_ocsp_item)
        goto loser;

    OCSP_TRACE(("OCSP ocsp_FindCacheEntry FOUND!\n"));
    ocsp_MakeCacheEntryMostRecent(cache, found_ocsp_item);

loser:
    PR_ExitMonitor(OCSP_Global.monitor);
    return found_ocsp_item;
}

static void
ocsp_FreeCacheItem(OCSPCacheItem *item)
{
    OCSP_TRACE(("OCSP ocsp_FreeCacheItem\n"));
    if (item->certStatusArena) {
        PORT_FreeArena(item->certStatusArena, PR_FALSE);
    }
    if (item->certID->poolp) {
        /* freeing this poolp arena will also free item */
        PORT_FreeArena(item->certID->poolp, PR_FALSE);
    }
}

static void
ocsp_RemoveCacheItem(OCSPCacheData *cache, OCSPCacheItem *item)
{
    /* The item we're removing could be either the least recently used item,
     * or it could be an item that couldn't get updated with newer status info
     * because of an allocation failure, or it could get removed because we're
     * cleaning up.
     */
    OCSP_TRACE(("OCSP ocsp_RemoveCacheItem, THREADID %p\n", PR_GetCurrentThread()));
    PR_EnterMonitor(OCSP_Global.monitor);

    ocsp_RemoveCacheItemFromLinkedList(cache, item);
#ifdef DEBUG
    {
        PRBool couldRemoveFromHashTable = PL_HashTableRemove(cache->entries,
                                                             item->certID);
        PORT_Assert(couldRemoveFromHashTable);
    }
#else
    PL_HashTableRemove(cache->entries, item->certID);
#endif
    --cache->numberOfEntries;
    ocsp_FreeCacheItem(item);
    PR_ExitMonitor(OCSP_Global.monitor);
}

static void
ocsp_CheckCacheSize(OCSPCacheData *cache)
{
    OCSP_TRACE(("OCSP ocsp_CheckCacheSize\n"));
    PR_EnterMonitor(OCSP_Global.monitor);
    if (OCSP_Global.maxCacheEntries > 0) {
        /* Cache is not disabled. Number of cache entries is limited.
         * The monitor ensures that maxCacheEntries remains positive.
         */
        while (cache->numberOfEntries >
               (PRUint32)OCSP_Global.maxCacheEntries) {
            ocsp_RemoveCacheItem(cache, cache->LRUitem);
        }
    }
    PR_ExitMonitor(OCSP_Global.monitor);
}

SECStatus
CERT_ClearOCSPCache(void)
{
    OCSP_TRACE(("OCSP CERT_ClearOCSPCache\n"));
    PR_EnterMonitor(OCSP_Global.monitor);
    while (OCSP_Global.cache.numberOfEntries > 0) {
        ocsp_RemoveCacheItem(&OCSP_Global.cache,
                             OCSP_Global.cache.LRUitem);
    }
    PR_ExitMonitor(OCSP_Global.monitor);
    return SECSuccess;
}

static SECStatus
ocsp_CreateCacheItemAndConsumeCertID(OCSPCacheData *cache,
                                     CERTOCSPCertID *certID,
                                     OCSPCacheItem **pCacheItem)
{
    PLArenaPool *arena;
    void *mark;
    PLHashEntry *new_hash_entry;
    OCSPCacheItem *item;

    PORT_Assert(pCacheItem != NULL);
    *pCacheItem = NULL;

    PR_EnterMonitor(OCSP_Global.monitor);
    arena = certID->poolp;
    mark = PORT_ArenaMark(arena);

    /* ZAlloc will init all Bools to False and all Pointers to NULL
       and all error codes to zero/good. */
    item = (OCSPCacheItem *)PORT_ArenaZAlloc(certID->poolp,
                                             sizeof(OCSPCacheItem));
    if (!item) {
        goto loser;
    }
    item->certID = certID;
    new_hash_entry = PL_HashTableAdd(cache->entries, item->certID,
                                     item);
    if (!new_hash_entry) {
        goto loser;
    }
    ++cache->numberOfEntries;
    PORT_ArenaUnmark(arena, mark);
    ocsp_AddCacheItemToLinkedList(cache, item);
    *pCacheItem = item;

    PR_ExitMonitor(OCSP_Global.monitor);
    return SECSuccess;

loser:
    PORT_ArenaRelease(arena, mark);
    PR_ExitMonitor(OCSP_Global.monitor);
    return SECFailure;
}

static SECStatus
ocsp_SetCacheItemResponse(OCSPCacheItem *item,
                          const CERTOCSPSingleResponse *response)
{
    if (item->certStatusArena) {
        PORT_FreeArena(item->certStatusArena, PR_FALSE);
        item->certStatusArena = NULL;
    }
    item->haveThisUpdate = item->haveNextUpdate = PR_FALSE;
    if (response) {
        SECStatus rv;
        item->certStatusArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        if (item->certStatusArena == NULL) {
            return SECFailure;
        }
        rv = ocsp_CopyCertStatus(item->certStatusArena, &item->certStatus,
                                 response->certStatus);
        if (rv != SECSuccess) {
            PORT_FreeArena(item->certStatusArena, PR_FALSE);
            item->certStatusArena = NULL;
            return rv;
        }
        item->missingResponseError = 0;
        rv = DER_GeneralizedTimeToTime(&item->thisUpdate,
                                       &response->thisUpdate);
        item->haveThisUpdate = (rv == SECSuccess);
        if (response->nextUpdate) {
            rv = DER_GeneralizedTimeToTime(&item->nextUpdate,
                                           response->nextUpdate);
            item->haveNextUpdate = (rv == SECSuccess);
        } else {
            item->haveNextUpdate = PR_FALSE;
        }
    }
    return SECSuccess;
}

static void
ocsp_FreshenCacheItemNextFetchAttemptTime(OCSPCacheItem *cacheItem)
{
    PRTime now;
    PRTime earliestAllowedNextFetchAttemptTime;
    PRTime latestTimeWhenResponseIsConsideredFresh;

    OCSP_TRACE(("OCSP ocsp_FreshenCacheItemNextFetchAttemptTime\n"));

    PR_EnterMonitor(OCSP_Global.monitor);

    now = PR_Now();
    OCSP_TRACE_TIME("now:", now);

    if (cacheItem->haveThisUpdate) {
        OCSP_TRACE_TIME("thisUpdate:", cacheItem->thisUpdate);
        latestTimeWhenResponseIsConsideredFresh = cacheItem->thisUpdate +
                                                  OCSP_Global.maximumSecondsToNextFetchAttempt *
                                                      MICROSECONDS_PER_SECOND;
        OCSP_TRACE_TIME("latestTimeWhenResponseIsConsideredFresh:",
                        latestTimeWhenResponseIsConsideredFresh);
    } else {
        latestTimeWhenResponseIsConsideredFresh = now +
                                                  OCSP_Global.minimumSecondsToNextFetchAttempt *
                                                      MICROSECONDS_PER_SECOND;
        OCSP_TRACE_TIME("no thisUpdate, "
                        "latestTimeWhenResponseIsConsideredFresh:",
                        latestTimeWhenResponseIsConsideredFresh);
    }

    if (cacheItem->haveNextUpdate) {
        OCSP_TRACE_TIME("have nextUpdate:", cacheItem->nextUpdate);
    }

    if (cacheItem->haveNextUpdate &&
        cacheItem->nextUpdate < latestTimeWhenResponseIsConsideredFresh) {
        latestTimeWhenResponseIsConsideredFresh = cacheItem->nextUpdate;
        OCSP_TRACE_TIME("nextUpdate is smaller than latestFresh, setting "
                        "latestTimeWhenResponseIsConsideredFresh:",
                        latestTimeWhenResponseIsConsideredFresh);
    }

    earliestAllowedNextFetchAttemptTime = now +
                                          OCSP_Global.minimumSecondsToNextFetchAttempt *
                                              MICROSECONDS_PER_SECOND;
    OCSP_TRACE_TIME("earliestAllowedNextFetchAttemptTime:",
                    earliestAllowedNextFetchAttemptTime);

    if (latestTimeWhenResponseIsConsideredFresh <
        earliestAllowedNextFetchAttemptTime) {
        latestTimeWhenResponseIsConsideredFresh =
            earliestAllowedNextFetchAttemptTime;
        OCSP_TRACE_TIME("latest < earliest, setting latest to:",
                        latestTimeWhenResponseIsConsideredFresh);
    }

    cacheItem->nextFetchAttemptTime =
        latestTimeWhenResponseIsConsideredFresh;
    OCSP_TRACE_TIME("nextFetchAttemptTime",
                    latestTimeWhenResponseIsConsideredFresh);

    PR_ExitMonitor(OCSP_Global.monitor);
}

static PRBool
ocsp_IsCacheItemFresh(OCSPCacheItem *cacheItem)
{
    PRTime now;
    PRBool fresh;

    now = PR_Now();

    fresh = cacheItem->nextFetchAttemptTime > now;

    /* Work around broken OCSP responders that return unknown responses for
     * certificates, especially certificates that were just recently issued.
     */
    if (fresh && cacheItem->certStatusArena &&
        cacheItem->certStatus.certStatusType == ocspCertStatus_unknown) {
        fresh = PR_FALSE;
    }

    OCSP_TRACE(("OCSP ocsp_IsCacheItemFresh: %d\n", fresh));

    return fresh;
}

/*
 * Status in *certIDWasConsumed will always be correct, regardless of
 * return value.
 * If the caller is unable to transfer ownership of certID,
 * then the caller must set certIDWasConsumed to NULL,
 * and this function will potentially duplicate the certID object.
 */
static SECStatus
ocsp_CreateOrUpdateCacheEntry(OCSPCacheData *cache,
                              CERTOCSPCertID *certID,
                              CERTOCSPSingleResponse *single,
                              PRBool *certIDWasConsumed)
{
    SECStatus rv;
    OCSPCacheItem *cacheItem;
    OCSP_TRACE(("OCSP ocsp_CreateOrUpdateCacheEntry\n"));

    if (certIDWasConsumed)
        *certIDWasConsumed = PR_FALSE;

    PR_EnterMonitor(OCSP_Global.monitor);
    PORT_Assert(OCSP_Global.maxCacheEntries >= 0);

    cacheItem = ocsp_FindCacheEntry(cache, certID);

    /* Don't replace an unknown or revoked entry with an error entry, even if
     * the existing entry is expired. Instead, we'll continue to use the
     * existing (possibly expired) cache entry until we receive a valid signed
     * response to replace it.
     */
    if (!single && cacheItem && cacheItem->certStatusArena &&
        (cacheItem->certStatus.certStatusType == ocspCertStatus_revoked ||
         cacheItem->certStatus.certStatusType == ocspCertStatus_unknown)) {
        PR_ExitMonitor(OCSP_Global.monitor);
        return SECSuccess;
    }

    if (!cacheItem) {
        CERTOCSPCertID *myCertID;
        if (certIDWasConsumed) {
            myCertID = certID;
            *certIDWasConsumed = PR_TRUE;
        } else {
            myCertID = cert_DupOCSPCertID(certID);
            if (!myCertID) {
                PR_ExitMonitor(OCSP_Global.monitor);
                PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
                return SECFailure;
            }
        }

        rv = ocsp_CreateCacheItemAndConsumeCertID(cache, myCertID,
                                                  &cacheItem);
        if (rv != SECSuccess) {
            PR_ExitMonitor(OCSP_Global.monitor);
            return rv;
        }
    }
    if (single) {
        PRTime thisUpdate;
        rv = DER_GeneralizedTimeToTime(&thisUpdate, &single->thisUpdate);

        if (!cacheItem->haveThisUpdate ||
            (rv == SECSuccess && cacheItem->thisUpdate < thisUpdate)) {
            rv = ocsp_SetCacheItemResponse(cacheItem, single);
            if (rv != SECSuccess) {
                ocsp_RemoveCacheItem(cache, cacheItem);
                PR_ExitMonitor(OCSP_Global.monitor);
                return rv;
            }
        } else {
            OCSP_TRACE(("Not caching response because the response is not "
                        "newer than the cache"));
        }
    } else {
        cacheItem->missingResponseError = PORT_GetError();
        if (cacheItem->certStatusArena) {
            PORT_FreeArena(cacheItem->certStatusArena, PR_FALSE);
            cacheItem->certStatusArena = NULL;
        }
    }
    ocsp_FreshenCacheItemNextFetchAttemptTime(cacheItem);
    ocsp_CheckCacheSize(cache);

    PR_ExitMonitor(OCSP_Global.monitor);
    return SECSuccess;
}

extern SECStatus
CERT_SetOCSPFailureMode(SEC_OcspFailureMode ocspFailureMode)
{
    switch (ocspFailureMode) {
        case ocspMode_FailureIsVerificationFailure:
        case ocspMode_FailureIsNotAVerificationFailure:
            break;
        default:
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return SECFailure;
    }

    PR_EnterMonitor(OCSP_Global.monitor);
    OCSP_Global.ocspFailureMode = ocspFailureMode;
    PR_ExitMonitor(OCSP_Global.monitor);
    return SECSuccess;
}

SECStatus
CERT_OCSPCacheSettings(PRInt32 maxCacheEntries,
                       PRUint32 minimumSecondsToNextFetchAttempt,
                       PRUint32 maximumSecondsToNextFetchAttempt)
{
    if (minimumSecondsToNextFetchAttempt > maximumSecondsToNextFetchAttempt ||
        maxCacheEntries < -1) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    PR_EnterMonitor(OCSP_Global.monitor);

    if (maxCacheEntries < 0) {
        OCSP_Global.maxCacheEntries = -1; /* disable cache */
    } else if (maxCacheEntries == 0) {
        OCSP_Global.maxCacheEntries = 0; /* unlimited cache entries */
    } else {
        OCSP_Global.maxCacheEntries = maxCacheEntries;
    }

    if (minimumSecondsToNextFetchAttempt <
            OCSP_Global.minimumSecondsToNextFetchAttempt ||
        maximumSecondsToNextFetchAttempt <
            OCSP_Global.maximumSecondsToNextFetchAttempt) {
        /*
         * Ensure our existing cache entries are not used longer than the
         * new settings allow, we're lazy and just clear the cache
         */
        CERT_ClearOCSPCache();
    }

    OCSP_Global.minimumSecondsToNextFetchAttempt =
        minimumSecondsToNextFetchAttempt;
    OCSP_Global.maximumSecondsToNextFetchAttempt =
        maximumSecondsToNextFetchAttempt;
    ocsp_CheckCacheSize(&OCSP_Global.cache);

    PR_ExitMonitor(OCSP_Global.monitor);
    return SECSuccess;
}

SECStatus
CERT_SetOCSPTimeout(PRUint32 seconds)
{
    /* no locking, see bug 406120 */
    OCSP_Global.timeoutSeconds = seconds;
    return SECSuccess;
}

/* this function is called at NSS initialization time */
SECStatus
OCSP_InitGlobal(void)
{
    SECStatus rv = SECFailure;

    if (OCSP_Global.monitor == NULL) {
        OCSP_Global.monitor = PR_NewMonitor();
    }
    if (!OCSP_Global.monitor)
        return SECFailure;

    PR_EnterMonitor(OCSP_Global.monitor);
    if (!OCSP_Global.cache.entries) {
        OCSP_Global.cache.entries =
            PL_NewHashTable(0,
                            ocsp_CacheKeyHashFunction,
                            ocsp_CacheKeyCompareFunction,
                            PL_CompareValues,
                            NULL,
                            NULL);
        OCSP_Global.ocspFailureMode = ocspMode_FailureIsVerificationFailure;
        OCSP_Global.cache.numberOfEntries = 0;
        OCSP_Global.cache.MRUitem = NULL;
        OCSP_Global.cache.LRUitem = NULL;
    } else {
        /*
         * NSS might call this function twice while attempting to init.
         * But it's not allowed to call this again after any activity.
         */
        PORT_Assert(OCSP_Global.cache.numberOfEntries == 0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
    }
    if (OCSP_Global.cache.entries)
        rv = SECSuccess;
    PR_ExitMonitor(OCSP_Global.monitor);
    return rv;
}

SECStatus
OCSP_ShutdownGlobal(void)
{
    if (!OCSP_Global.monitor)
        return SECSuccess;

    PR_EnterMonitor(OCSP_Global.monitor);
    if (OCSP_Global.cache.entries) {
        CERT_ClearOCSPCache();
        PL_HashTableDestroy(OCSP_Global.cache.entries);
        OCSP_Global.cache.entries = NULL;
    }
    PORT_Assert(OCSP_Global.cache.numberOfEntries == 0);
    OCSP_Global.cache.MRUitem = NULL;
    OCSP_Global.cache.LRUitem = NULL;

    OCSP_Global.defaultHttpClientFcn = NULL;
    OCSP_Global.maxCacheEntries = DEFAULT_OCSP_CACHE_SIZE;
    OCSP_Global.minimumSecondsToNextFetchAttempt =
        DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT;
    OCSP_Global.maximumSecondsToNextFetchAttempt =
        DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT;
    OCSP_Global.ocspFailureMode =
        ocspMode_FailureIsVerificationFailure;
    PR_ExitMonitor(OCSP_Global.monitor);

    PR_DestroyMonitor(OCSP_Global.monitor);
    OCSP_Global.monitor = NULL;
    return SECSuccess;
}

/*
 * A return value of NULL means:
 *   The application did not register it's own HTTP client.
 */
const SEC_HttpClientFcn *
SEC_GetRegisteredHttpClient(void)
{
    const SEC_HttpClientFcn *retval;

    if (!OCSP_Global.monitor) {
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
        return NULL;
    }

    PR_EnterMonitor(OCSP_Global.monitor);
    retval = OCSP_Global.defaultHttpClientFcn;
    PR_ExitMonitor(OCSP_Global.monitor);

    return retval;
}

/*
 * The following structure is only used internally.  It is allocated when
 * someone turns on OCSP checking, and hangs off of the status-configuration
 * structure in the certdb structure.  We use it to keep configuration
 * information specific to OCSP checking.
 */
typedef struct ocspCheckingContextStr {
    PRBool useDefaultResponder;
    char *defaultResponderURI;
    char *defaultResponderNickname;
    CERTCertificate *defaultResponderCert;
} ocspCheckingContext;

SEC_ASN1_MKSUB(SEC_AnyTemplate)
SEC_ASN1_MKSUB(SEC_IntegerTemplate)
SEC_ASN1_MKSUB(SEC_NullTemplate)
SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
SEC_ASN1_MKSUB(SEC_PointerToAnyTemplate)
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
SEC_ASN1_MKSUB(SEC_SequenceOfAnyTemplate)
SEC_ASN1_MKSUB(SEC_PointerToGeneralizedTimeTemplate)
SEC_ASN1_MKSUB(SEC_PointerToEnumeratedTemplate)

/*
 * Forward declarations of sub-types, so I can lay out the types in the
 * same order as the ASN.1 is laid out in the OCSP spec itself.
 *
 * These are in alphabetical order (case-insensitive); please keep it that way!
 */
extern const SEC_ASN1Template ocsp_CertIDTemplate[];
extern const SEC_ASN1Template ocsp_PointerToSignatureTemplate[];
extern const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[];
extern const SEC_ASN1Template ocsp_ResponseDataTemplate[];
extern const SEC_ASN1Template ocsp_RevokedInfoTemplate[];
extern const SEC_ASN1Template ocsp_SingleRequestTemplate[];
extern const SEC_ASN1Template ocsp_SingleResponseTemplate[];
extern const SEC_ASN1Template ocsp_TBSRequestTemplate[];

/*
 * Request-related templates...
 */

/*
 * OCSPRequest	::=	SEQUENCE {
 *	tbsRequest		TBSRequest,
 *	optionalSignature	[0] EXPLICIT Signature OPTIONAL }
 */
static const SEC_ASN1Template ocsp_OCSPRequestTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTOCSPRequest) },
    { SEC_ASN1_POINTER,
      offsetof(CERTOCSPRequest, tbsRequest),
      ocsp_TBSRequestTemplate },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
      offsetof(CERTOCSPRequest, optionalSignature),
      ocsp_PointerToSignatureTemplate },
    { 0 }
};

/*
 * TBSRequest	::=	SEQUENCE {
 *	version			[0] EXPLICIT Version DEFAULT v1,
 *	requestorName		[1] EXPLICIT GeneralName OPTIONAL,
 *	requestList		SEQUENCE OF Request,
 *	requestExtensions	[2] EXPLICIT Extensions OPTIONAL }
 *
 * Version	::=	INTEGER { v1(0) }
 *
 * Note: this should be static but the AIX compiler doesn't like it (because it
 * was forward-declared above); it is not meant to be exported, but this
 * is the only way it will compile.
 */
const SEC_ASN1Template ocsp_TBSRequestTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(ocspTBSRequest) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      offsetof(ocspTBSRequest, version),
      SEC_ASN1_SUB(SEC_IntegerTemplate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
      offsetof(ocspTBSRequest, derRequestorName),
      SEC_ASN1_SUB(SEC_PointerToAnyTemplate) },
    { SEC_ASN1_SEQUENCE_OF,
      offsetof(ocspTBSRequest, requestList),
      ocsp_SingleRequestTemplate },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
      offsetof(ocspTBSRequest, requestExtensions),
      CERT_SequenceOfCertExtensionTemplate },
    { 0 }
};

/*
 * Signature	::=	SEQUENCE {
 *	signatureAlgorithm	AlgorithmIdentifier,
 *	signature		BIT STRING,
 *	certs			[0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
 */
static const SEC_ASN1Template ocsp_SignatureTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(ocspSignature) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(ocspSignature, signatureAlgorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_BIT_STRING,
      offsetof(ocspSignature, signature) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      offsetof(ocspSignature, derCerts),
      SEC_ASN1_SUB(SEC_SequenceOfAnyTemplate) },
    { 0 }
};

/*
 * This template is just an extra level to use in an explicitly-tagged
 * reference to a Signature.
 *
 * Note: this should be static but the AIX compiler doesn't like it (because it
 * was forward-declared above); it is not meant to be exported, but this
 * is the only way it will compile.
 */
const SEC_ASN1Template ocsp_PointerToSignatureTemplate[] = {
    { SEC_ASN1_POINTER, 0, ocsp_SignatureTemplate }
};

/*
 * Request	::=	SEQUENCE {
 *	reqCert			CertID,
 *	singleRequestExtensions	[0] EXPLICIT Extensions OPTIONAL }
 *
 * Note: this should be static but the AIX compiler doesn't like it (because it
 * was forward-declared above); it is not meant to be exported, but this
 * is the only way it will compile.
 */
const SEC_ASN1Template ocsp_SingleRequestTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(ocspSingleRequest) },
    { SEC_ASN1_POINTER,
      offsetof(ocspSingleRequest, reqCert),
      ocsp_CertIDTemplate },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
      offsetof(ocspSingleRequest, singleRequestExtensions),
      CERT_SequenceOfCertExtensionTemplate },
    { 0 }
};

/*
 * This data structure and template (CertID) is used by both OCSP
 * requests and responses.  It is the only one that is shared.
 *
 * CertID	::=	SEQUENCE {
 *	hashAlgorithm		AlgorithmIdentifier,
 *	issuerNameHash		OCTET STRING,	-- Hash of Issuer DN
 *	issuerKeyHash		OCTET STRING,	-- Hash of Issuer public key
 *	serialNumber		CertificateSerialNumber }
 *
 * CertificateSerialNumber ::=	INTEGER
 *
 * Note: this should be static but the AIX compiler doesn't like it (because it
 * was forward-declared above); it is not meant to be exported, but this
 * is the only way it will compile.
 */
const SEC_ASN1Template ocsp_CertIDTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTOCSPCertID) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(CERTOCSPCertID, hashAlgorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_OCTET_STRING,
      offsetof(CERTOCSPCertID, issuerNameHash) },
    { SEC_ASN1_OCTET_STRING,
      offsetof(CERTOCSPCertID, issuerKeyHash) },
    { SEC_ASN1_INTEGER,
      offsetof(CERTOCSPCertID, serialNumber) },
    { 0 }
};

/*
 * Response-related templates...
 */

/*
 * OCSPResponse	::=	SEQUENCE {
 *	responseStatus		OCSPResponseStatus,
 *	responseBytes		[0] EXPLICIT ResponseBytes OPTIONAL }
 */
const SEC_ASN1Template ocsp_OCSPResponseTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTOCSPResponse) },
    { SEC_ASN1_ENUMERATED,
      offsetof(CERTOCSPResponse, responseStatus) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
      offsetof(CERTOCSPResponse, responseBytes),
      ocsp_PointerToResponseBytesTemplate },
    { 0 }
};

/*
 * ResponseBytes	::=	SEQUENCE {
 *	responseType		OBJECT IDENTIFIER,
 *	response		OCTET STRING }
 */
const SEC_ASN1Template ocsp_ResponseBytesTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(ocspResponseBytes) },
    { SEC_ASN1_OBJECT_ID,
      offsetof(ocspResponseBytes, responseType) },
    { SEC_ASN1_OCTET_STRING,
      offsetof(ocspResponseBytes, response) },
    { 0 }
};

/*
 * This template is just an extra level to use in an explicitly-tagged
 * reference to a ResponseBytes.
 *
 * Note: this should be static but the AIX compiler doesn't like it (because it
 * was forward-declared above); it is not meant to be exported, but this
 * is the only way it will compile.
 */
const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[] = {
    { SEC_ASN1_POINTER, 0, ocsp_ResponseBytesTemplate }
};

/*
 * BasicOCSPResponse	::=	SEQUENCE {
 *	tbsResponseData		ResponseData,
 *	signatureAlgorithm	AlgorithmIdentifier,
 *	signature		BIT STRING,
 *	certs			[0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
 */
static const SEC_ASN1Template ocsp_BasicOCSPResponseTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(ocspBasicOCSPResponse) },
    { SEC_ASN1_ANY | SEC_ASN1_SAVE,
      offsetof(ocspBasicOCSPResponse, tbsResponseDataDER) },
    { SEC_ASN1_POINTER,
      offsetof(ocspBasicOCSPResponse, tbsResponseData),
      ocsp_ResponseDataTemplate },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_BIT_STRING,
      offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
      SEC_ASN1_SUB(SEC_SequenceOfAnyTemplate) },
    { 0 }
};

/*
 * ResponseData	::=	SEQUENCE {
 *	version			[0] EXPLICIT Version DEFAULT v1,
 *	responderID		ResponderID,
 *	producedAt		GeneralizedTime,
 *	responses		SEQUENCE OF SingleResponse,
 *	responseExtensions	[1] EXPLICIT Extensions OPTIONAL }
 *
 * Note: this should be static but the AIX compiler doesn't like it (because it
 * was forward-declared above); it is not meant to be exported, but this
 * is the only way it will compile.
 */
const SEC_ASN1Template ocsp_ResponseDataTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(ocspResponseData) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      offsetof(ocspResponseData, version),
      SEC_ASN1_SUB(SEC_IntegerTemplate) },
    { SEC_ASN1_ANY,
      offsetof(ocspResponseData, derResponderID) },
    { SEC_ASN1_GENERALIZED_TIME,
      offsetof(ocspResponseData, producedAt) },
    { SEC_ASN1_SEQUENCE_OF,
      offsetof(ocspResponseData, responses),
      ocsp_SingleResponseTemplate },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
      offsetof(ocspResponseData, responseExtensions),
      CERT_SequenceOfCertExtensionTemplate },
    { 0 }
};

/*
 * ResponderID	::=	CHOICE {
 *	byName			[1] EXPLICIT Name,
 *	byKey			[2] EXPLICIT KeyHash }
 *
 * KeyHash ::=	OCTET STRING -- SHA-1 hash of responder's public key
 * (excluding the tag and length fields)
 *
 * XXX Because the ASN.1 encoder and decoder currently do not provide
 * a way to automatically handle a CHOICE, we need to do it in two
 * steps, looking at the type tag and feeding the exact choice back
 * to the ASN.1 code.  Hopefully that will change someday and this
 * can all be simplified down into a single template.  Anyway, for
 * now we list each choice as its own template:
 */
const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[] = {
    { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
      offsetof(ocspResponderID, responderIDValue.name),
      CERT_NameTemplate }
};
const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[] = {
    { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
          SEC_ASN1_XTRN | 2,
      offsetof(ocspResponderID, responderIDValue.keyHash),
      SEC_ASN1_SUB(SEC_OctetStringTemplate) }
};
static const SEC_ASN1Template ocsp_ResponderIDOtherTemplate[] = {
    { SEC_ASN1_ANY,
      offsetof(ocspResponderID, responderIDValue.other) }
};

/* Decode choice container, but leave x509 name object encoded */
static const SEC_ASN1Template ocsp_ResponderIDDerNameTemplate[] = {
    { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
          SEC_ASN1_XTRN | 1,
      0, SEC_ASN1_SUB(SEC_AnyTemplate) }
};

/*
 * SingleResponse	::=	SEQUENCE {
 *	certID			CertID,
 *	certStatus		CertStatus,
 *	thisUpdate		GeneralizedTime,
 *	nextUpdate		[0] EXPLICIT GeneralizedTime OPTIONAL,
 *	singleExtensions	[1] EXPLICIT Extensions OPTIONAL }
 *
 * Note: this should be static but the AIX compiler doesn't like it (because it
 * was forward-declared above); it is not meant to be exported, but this
 * is the only way it will compile.
 */
const SEC_ASN1Template ocsp_SingleResponseTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTOCSPSingleResponse) },
    { SEC_ASN1_POINTER,
      offsetof(CERTOCSPSingleResponse, certID),
      ocsp_CertIDTemplate },
    { SEC_ASN1_ANY,
      offsetof(CERTOCSPSingleResponse, derCertStatus) },
    { SEC_ASN1_GENERALIZED_TIME,
      offsetof(CERTOCSPSingleResponse, thisUpdate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      offsetof(CERTOCSPSingleResponse, nextUpdate),
      SEC_ASN1_SUB(SEC_PointerToGeneralizedTimeTemplate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
      offsetof(CERTOCSPSingleResponse, singleExtensions),
      CERT_SequenceOfCertExtensionTemplate },
    { 0 }
};

/*
 * CertStatus	::=	CHOICE {
 *	good			[0] IMPLICIT NULL,
 *	revoked			[1] IMPLICIT RevokedInfo,
 *	unknown			[2] IMPLICIT UnknownInfo }
 *
 * Because the ASN.1 encoder and decoder currently do not provide
 * a way to automatically handle a CHOICE, we need to do it in two
 * steps, looking at the type tag and feeding the exact choice back
 * to the ASN.1 code.  Hopefully that will change someday and this
 * can all be simplified down into a single template.  Anyway, for
 * now we list each choice as its own template:
 */
static const SEC_ASN1Template ocsp_CertStatusGoodTemplate[] = {
    { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      offsetof(ocspCertStatus, certStatusInfo.goodInfo),
      SEC_ASN1_SUB(SEC_NullTemplate) }
};
static const SEC_ASN1Template ocsp_CertStatusRevokedTemplate[] = {
    { SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
      offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
      ocsp_RevokedInfoTemplate }
};
static const SEC_ASN1Template ocsp_CertStatusUnknownTemplate[] = {
    { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
      offsetof(ocspCertStatus, certStatusInfo.unknownInfo),
      SEC_ASN1_SUB(SEC_NullTemplate) }
};
static const SEC_ASN1Template ocsp_CertStatusOtherTemplate[] = {
    { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
      offsetof(ocspCertStatus, certStatusInfo.otherInfo),
      SEC_ASN1_SUB(SEC_AnyTemplate) }
};

/*
 * RevokedInfo	::=	SEQUENCE {
 *	revocationTime		GeneralizedTime,
 *	revocationReason	[0] EXPLICIT CRLReason OPTIONAL }
 *
 * Note: this should be static but the AIX compiler doesn't like it (because it
 * was forward-declared above); it is not meant to be exported, but this
 * is the only way it will compile.
 */
const SEC_ASN1Template ocsp_RevokedInfoTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(ocspRevokedInfo) },
    { SEC_ASN1_GENERALIZED_TIME,
      offsetof(ocspRevokedInfo, revocationTime) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
          SEC_ASN1_XTRN | 0,
      offsetof(ocspRevokedInfo, revocationReason),
      SEC_ASN1_SUB(SEC_PointerToEnumeratedTemplate) },
    { 0 }
};

/*
 * OCSP-specific extension templates:
 */

/*
 * ServiceLocator	::=	SEQUENCE {
 *	issuer			Name,
 *	locator			AuthorityInfoAccessSyntax OPTIONAL }
 */
static const SEC_ASN1Template ocsp_ServiceLocatorTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(ocspServiceLocator) },
    { SEC_ASN1_POINTER,
      offsetof(ocspServiceLocator, issuer),
      CERT_NameTemplate },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
      offsetof(ocspServiceLocator, locator) },
    { 0 }
};

/*
 * REQUEST SUPPORT FUNCTIONS (encode/create/decode/destroy):
 */

/*
 * FUNCTION: CERT_EncodeOCSPRequest
 *   DER encodes an OCSP Request, possibly adding a signature as well.
 *   XXX Signing is not yet supported, however; see comments in code.
 * INPUTS:
 *   PLArenaPool *arena
 *     The return value is allocated from here.
 *     If a NULL is passed in, allocation is done from the heap instead.
 *   CERTOCSPRequest *request
 *     The request to be encoded.
 *   void *pwArg
 *     Pointer to argument for password prompting, if needed.  (Definitely
 *     not needed if not signing.)
 * RETURN:
 *   Returns a NULL on error and a pointer to the SECItem with the
 *   encoded value otherwise.  Any error is likely to be low-level
 *   (e.g. no memory).
 */
SECItem *
CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
                       void *pwArg)
{
    SECStatus rv;

    /* XXX All of these should generate errors if they fail. */
    PORT_Assert(request);
    PORT_Assert(request->tbsRequest);

    if (request->tbsRequest->extensionHandle != NULL) {
        rv = CERT_FinishExtensions(request->tbsRequest->extensionHandle);
        request->tbsRequest->extensionHandle = NULL;
        if (rv != SECSuccess)
            return NULL;
    }

    /*
     * XXX When signed requests are supported and request->optionalSignature
     * is not NULL:
     *  - need to encode tbsRequest->requestorName
     *  - need to encode tbsRequest
     *  - need to sign that encoded result (using cert in sig), filling in the
     *    request->optionalSignature structure with the result, the signing
     *    algorithm and (perhaps?) the cert (and its chain?) in derCerts
     */

    return SEC_ASN1EncodeItem(arena, NULL, request, ocsp_OCSPRequestTemplate);
}

/*
 * FUNCTION: CERT_DecodeOCSPRequest
 *   Decode a DER encoded OCSP Request.
 * INPUTS:
 *   SECItem *src
 *     Pointer to a SECItem holding DER encoded OCSP Request.
 * RETURN:
 *   Returns a pointer to a CERTOCSPRequest containing the decoded request.
 *   On error, returns NULL.  Most likely error is trouble decoding
 *   (SEC_ERROR_OCSP_MALFORMED_REQUEST), or low-level problem (no memory).
 */
CERTOCSPRequest *
CERT_DecodeOCSPRequest(const SECItem *src)
{
    PLArenaPool *arena = NULL;
    SECStatus rv = SECFailure;
    CERTOCSPRequest *dest = NULL;
    int i;
    SECItem newSrc;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }
    dest = (CERTOCSPRequest *)PORT_ArenaZAlloc(arena,
                                               sizeof(CERTOCSPRequest));
    if (dest == NULL) {
        goto loser;
    }
    dest->arena = arena;

    /* copy the DER into the arena, since Quick DER returns data that points
       into the DER input, which may get freed by the caller */
    rv = SECITEM_CopyItem(arena, &newSrc, src);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = SEC_QuickDERDecodeItem(arena, dest, ocsp_OCSPRequestTemplate, &newSrc);
    if (rv != SECSuccess) {
        if (PORT_GetError() == SEC_ERROR_BAD_DER)
            PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);
        goto loser;
    }

    /*
     * XXX I would like to find a way to get rid of the necessity
     * of doing this copying of the arena pointer.
     */
    for (i = 0; dest->tbsRequest->requestList[i] != NULL; i++) {
        dest->tbsRequest->requestList[i]->arena = arena;
    }

    return dest;

loser:
    if (arena != NULL) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return NULL;
}

SECStatus
CERT_DestroyOCSPCertID(CERTOCSPCertID *certID)
{
    if (certID && certID->poolp) {
        PORT_FreeArena(certID->poolp, PR_FALSE);
        return SECSuccess;
    }
    PORT_SetError(SEC_ERROR_INVALID_ARGS);
    return SECFailure;
}

/*
 * Digest data using the specified algorithm.
 * The necessary storage for the digest data is allocated.  If "fill" is
 * non-null, the data is put there, otherwise a SECItem is allocated.
 * Allocation from "arena" if it is non-null, heap otherwise.  Any problem
 * results in a NULL being returned (and an appropriate error set).
 */

SECItem *
ocsp_DigestValue(PLArenaPool *arena, SECOidTag digestAlg,
                 SECItem *fill, const SECItem *src)
{
    const SECHashObject *digestObject;
    SECItem *result = NULL;
    void *mark = NULL;
    void *digestBuff = NULL;

    if (arena != NULL) {
        mark = PORT_ArenaMark(arena);
    }

    digestObject = HASH_GetHashObjectByOidTag(digestAlg);
    if (digestObject == NULL) {
        goto loser;
    }

    if (fill == NULL || fill->data == NULL) {
        result = SECITEM_AllocItem(arena, fill, digestObject->length);
        if (result == NULL) {
            goto loser;
        }
        digestBuff = result->data;
    } else {
        if (fill->len < digestObject->length) {
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            goto loser;
        }
        digestBuff = fill->data;
    }

    if (PK11_HashBuf(digestAlg, digestBuff,
                     src->data, src->len) != SECSuccess) {
        goto loser;
    }

    if (arena != NULL) {
        PORT_ArenaUnmark(arena, mark);
    }

    if (result == NULL) {
        result = fill;
    }
    return result;

loser:
    if (arena != NULL) {
        PORT_ArenaRelease(arena, mark);
    } else {
        if (result != NULL) {
            SECITEM_FreeItem(result, (fill == NULL) ? PR_TRUE : PR_FALSE);
        }
    }
    return (NULL);
}

/*
 * Digest the cert's subject public key using the specified algorithm.
 * The necessary storage for the digest data is allocated.  If "fill" is
 * non-null, the data is put there, otherwise a SECItem is allocated.
 * Allocation from "arena" if it is non-null, heap otherwise.  Any problem
 * results in a NULL being returned (and an appropriate error set).
 */
SECItem *
CERT_GetSubjectPublicKeyDigest(PLArenaPool *arena, const CERTCertificate *cert,
                               SECOidTag digestAlg, SECItem *fill)
{
    SECItem spk;

    /*
     * Copy just the length and data pointer (nothing needs to be freed)
     * of the subject public key so we can convert the length from bits
     * to bytes, which is what the digest function expects.
     */
    spk = cert->subjectPublicKeyInfo.subjectPublicKey;
    DER_ConvertBitString(&spk);

    return ocsp_DigestValue(arena, digestAlg, fill, &spk);
}

/*
 * Digest the cert's subject name using the specified algorithm.
 */
SECItem *
CERT_GetSubjectNameDigest(PLArenaPool *arena, const CERTCertificate *cert,
                          SECOidTag digestAlg, SECItem *fill)
{
    SECItem name;

    /*
     * Copy just the length and data pointer (nothing needs to be freed)
     * of the subject name
     */
    name = cert->derSubject;

    return ocsp_DigestValue(arena, digestAlg, fill, &name);
}

/*
 * Create and fill-in a CertID.  This function fills in the hash values
 * (issuerNameHash and issuerKeyHash), and is hardwired to use SHA1.
 * Someday it might need to be more flexible about hash algorithm, but
 * for now we have no intention/need to create anything else.
 *
 * Error causes a null to be returned; most likely cause is trouble
 * finding the certificate issuer (SEC_ERROR_UNKNOWN_ISSUER).
 * Other errors are low-level problems (no memory, bad database, etc.).
 */
static CERTOCSPCertID *
ocsp_CreateCertID(PLArenaPool *arena, CERTCertificate *cert, PRTime time)
{
    CERTOCSPCertID *certID;
    CERTCertificate *issuerCert = NULL;
    void *mark = PORT_ArenaMark(arena);
    SECStatus rv;

    PORT_Assert(arena != NULL);

    certID = PORT_ArenaZNew(arena, CERTOCSPCertID);
    if (certID == NULL) {
        goto loser;
    }

    rv = SECOID_SetAlgorithmID(arena, &certID->hashAlgorithm, SEC_OID_SHA1,
                               NULL);
    if (rv != SECSuccess) {
        goto loser;
    }

    issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);
    if (issuerCert == NULL) {
        goto loser;
    }

    if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_SHA1,
                                  &(certID->issuerNameHash)) == NULL) {
        goto loser;
    }
    certID->issuerSHA1NameHash.data = certID->issuerNameHash.data;
    certID->issuerSHA1NameHash.len = certID->issuerNameHash.len;

    if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD5,
                                  &(certID->issuerMD5NameHash)) == NULL) {
        goto loser;
    }

    if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD2,
                                  &(certID->issuerMD2NameHash)) == NULL) {
        goto loser;
    }

    if (CERT_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_SHA1,
                                       &certID->issuerKeyHash) == NULL) {
        goto loser;
    }
    certID->issuerSHA1KeyHash.data = certID->issuerKeyHash.data;
    certID->issuerSHA1KeyHash.len = certID->issuerKeyHash.len;
    /* cache the other two hash algorithms as well */
    if (CERT_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_MD5,
                                       &certID->issuerMD5KeyHash) == NULL) {
        goto loser;
    }
    if (CERT_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_MD2,
                                       &certID->issuerMD2KeyHash) == NULL) {
        goto loser;
    }

    /* now we are done with issuerCert */
    CERT_DestroyCertificate(issuerCert);
    issuerCert = NULL;

    rv = SECITEM_CopyItem(arena, &certID->serialNumber, &cert->serialNumber);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_ArenaUnmark(arena, mark);
    return certID;

loser:
    if (issuerCert != NULL) {
        CERT_DestroyCertificate(issuerCert);
    }
    PORT_ArenaRelease(arena, mark);
    return NULL;
}

CERTOCSPCertID *
CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time)
{
    PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    CERTOCSPCertID *certID;
    PORT_Assert(arena != NULL);
    if (!arena)
        return NULL;

    certID = ocsp_CreateCertID(arena, cert, time);
    if (!certID) {
        PORT_FreeArena(arena, PR_FALSE);
        return NULL;
    }
    certID->poolp = arena;
    return certID;
}

static CERTOCSPCertID *
cert_DupOCSPCertID(const CERTOCSPCertID *src)
{
    CERTOCSPCertID *dest;
    PLArenaPool *arena = NULL;

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

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena)
        goto loser;

    dest = PORT_ArenaZNew(arena, CERTOCSPCertID);
    if (!dest)
        goto loser;

#define DUPHELP(element)                                          \
    if (src->element.data &&                                      \
        SECITEM_CopyItem(arena, &dest->element, &src->element) != \
            SECSuccess) {                                         \
        goto loser;                                               \
    }

    DUPHELP(hashAlgorithm.algorithm)
    DUPHELP(hashAlgorithm.parameters)
    DUPHELP(issuerNameHash)
    DUPHELP(issuerKeyHash)
    DUPHELP(serialNumber)
    DUPHELP(issuerSHA1NameHash)
    DUPHELP(issuerMD5NameHash)
    DUPHELP(issuerMD2NameHash)
    DUPHELP(issuerSHA1KeyHash)
    DUPHELP(issuerMD5KeyHash)
    DUPHELP(issuerMD2KeyHash)

    dest->poolp = arena;
    return dest;

loser:
    if (arena)
        PORT_FreeArena(arena, PR_FALSE);
    PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
    return NULL;
}

/*
 * Callback to set Extensions in request object
 */
void
SetSingleReqExts(void *object, CERTCertExtension **exts)
{
    ocspSingleRequest *singleRequest =
        (ocspSingleRequest *)object;

    singleRequest->singleRequestExtensions = exts;
}

/*
 * Add the Service Locator extension to the singleRequestExtensions
 * for the given singleRequest.
 *
 * All errors are internal or low-level problems (e.g. no memory).
 */
static SECStatus
ocsp_AddServiceLocatorExtension(ocspSingleRequest *singleRequest,
                                CERTCertificate *cert)
{
    ocspServiceLocator *serviceLocator = NULL;
    void *extensionHandle = NULL;
    SECStatus rv = SECFailure;

    serviceLocator = PORT_ZNew(ocspServiceLocator);
    if (serviceLocator == NULL)
        goto loser;

    /*
     * Normally it would be a bad idea to do a direct reference like
     * this rather than allocate and copy the name *or* at least dup
     * a reference of the cert.  But all we need is to be able to read
     * the issuer name during the encoding we are about to do, so a
     * copy is just a waste of time.
     */
    serviceLocator->issuer = &cert->issuer;

    rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS,
                                &serviceLocator->locator);
    if (rv != SECSuccess) {
        if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND)
            goto loser;
    }

    /* prepare for following loser gotos */
    rv = SECFailure;
    PORT_SetError(0);

    extensionHandle = cert_StartExtensions(singleRequest,
                                           singleRequest->arena, SetSingleReqExts);
    if (extensionHandle == NULL)
        goto loser;

    rv = CERT_EncodeAndAddExtension(extensionHandle,
                                    SEC_OID_PKIX_OCSP_SERVICE_LOCATOR,
                                    serviceLocator, PR_FALSE,
                                    ocsp_ServiceLocatorTemplate);

loser:
    if (extensionHandle != NULL) {
        /*
	 * Either way we have to finish out the extension context (so it gets
	 * freed).  But careful not to override any already-set bad status.
	 */
        SECStatus tmprv = CERT_FinishExtensions(extensionHandle);
        if (rv == SECSuccess)
            rv = tmprv;
    }

    /*
     * Finally, free the serviceLocator structure itself and we are done.
     */
    if (serviceLocator != NULL) {
        if (serviceLocator->locator.data != NULL)
            SECITEM_FreeItem(&serviceLocator->locator, PR_FALSE);
        PORT_Free(serviceLocator);
    }

    return rv;
}

/*
 * Creates an array of ocspSingleRequest based on a list of certs.
 * Note that the code which later compares the request list with the
 * response expects this array to be in the exact same order as the
 * certs are found in the list.  It would be harder to change that
 * order than preserve it, but since the requirement is not obvious,
 * it deserves to be mentioned.
 *
 * Any problem causes a null return and error set:
 *      SEC_ERROR_UNKNOWN_ISSUER
 * Other errors are low-level problems (no memory, bad database, etc.).
 */
static ocspSingleRequest **
ocsp_CreateSingleRequestList(PLArenaPool *arena, CERTCertList *certList,
                             PRTime time, PRBool includeLocator)
{
    ocspSingleRequest **requestList = NULL;
    CERTCertListNode *node = NULL;
    int i, count;
    void *mark = PORT_ArenaMark(arena);

    node = CERT_LIST_HEAD(certList);
    for (count = 0; !CERT_LIST_END(node, certList); count++) {
        node = CERT_LIST_NEXT(node);
    }

    if (count == 0)
        goto loser;

    requestList = PORT_ArenaNewArray(arena, ocspSingleRequest *, count + 1);
    if (requestList == NULL)
        goto loser;

    node = CERT_LIST_HEAD(certList);
    for (i = 0; !CERT_LIST_END(node, certList); i++) {
        requestList[i] = PORT_ArenaZNew(arena, ocspSingleRequest);
        if (requestList[i] == NULL)
            goto loser;

        OCSP_TRACE(("OCSP CERT_CreateOCSPRequest %s\n", node->cert->subjectName));
        requestList[i]->arena = arena;
        requestList[i]->reqCert = ocsp_CreateCertID(arena, node->cert, time);
        if (requestList[i]->reqCert == NULL)
            goto loser;

        if (includeLocator == PR_TRUE) {
            SECStatus rv;

            rv = ocsp_AddServiceLocatorExtension(requestList[i], node->cert);
            if (rv != SECSuccess)
                goto loser;
        }

        node = CERT_LIST_NEXT(node);
    }

    PORT_Assert(i == count);

    PORT_ArenaUnmark(arena, mark);
    requestList[i] = NULL;
    return requestList;

loser:
    PORT_ArenaRelease(arena, mark);
    return NULL;
}

static ocspSingleRequest **
ocsp_CreateRequestFromCert(PLArenaPool *arena,
                           CERTOCSPCertID *certID,
                           CERTCertificate *singleCert,
                           PRTime time,
                           PRBool includeLocator)
{
    ocspSingleRequest **requestList = NULL;
    void *mark = PORT_ArenaMark(arena);
    PORT_Assert(certID != NULL && singleCert != NULL);

    /* meaning of value 2: one entry + one end marker */
    requestList = PORT_ArenaNewArray(arena, ocspSingleRequest *, 2);
    if (requestList == NULL)
        goto loser;
    requestList[0] = PORT_ArenaZNew(arena, ocspSingleRequest);
    if (requestList[0] == NULL)
        goto loser;
    requestList[0]->arena = arena;
    /* certID will live longer than the request */
    requestList[0]->reqCert = certID;

    if (includeLocator == PR_TRUE) {
        SECStatus rv;
        rv = ocsp_AddServiceLocatorExtension(requestList[0], singleCert);
        if (rv != SECSuccess)
            goto loser;
    }

    PORT_ArenaUnmark(arena, mark);
    requestList[1] = NULL;
    return requestList;

loser:
    PORT_ArenaRelease(arena, mark);
    return NULL;
}

static CERTOCSPRequest *
ocsp_prepareEmptyOCSPRequest(void)
{
    PLArenaPool *arena = NULL;
    CERTOCSPRequest *request = NULL;
    ocspTBSRequest *tbsRequest = NULL;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }
    request = PORT_ArenaZNew(arena, CERTOCSPRequest);
    if (request == NULL) {
        goto loser;
    }
    request->arena = arena;

    tbsRequest = PORT_ArenaZNew(arena, ocspTBSRequest);
    if (tbsRequest == NULL) {
        goto loser;
    }
    request->tbsRequest = tbsRequest;
    /* version 1 is the default, so we need not fill in a version number */
    return request;

loser:
    if (arena != NULL) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return NULL;
}

CERTOCSPRequest *
cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
                                 CERTCertificate *singleCert,
                                 PRTime time,
                                 PRBool addServiceLocator,
                                 CERTCertificate *signerCert)
{
    CERTOCSPRequest *request;
    OCSP_TRACE(("OCSP cert_CreateSingleCertOCSPRequest %s\n", singleCert->subjectName));

    /* XXX Support for signerCert may be implemented later,
     * see also the comment in CERT_CreateOCSPRequest.
     */
    if (signerCert != NULL) {
        PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
        return NULL;
    }

    request = ocsp_prepareEmptyOCSPRequest();
    if (!request)
        return NULL;
    /*
     * Version 1 is the default, so we need not fill in a version number.
     * Now create the list of single requests, one for each cert.
     */
    request->tbsRequest->requestList =
        ocsp_CreateRequestFromCert(request->arena,
                                   certID,
                                   singleCert,
                                   time,
                                   addServiceLocator);
    if (request->tbsRequest->requestList == NULL) {
        PORT_FreeArena(request->arena, PR_FALSE);
        return NULL;
    }
    return request;
}

/*
 * FUNCTION: CERT_CreateOCSPRequest
 *   Creates a CERTOCSPRequest, requesting the status of the certs in
 *   the given list.
 * INPUTS:
 *   CERTCertList *certList
 *     A list of certs for which status will be requested.
 *     Note that all of these certificates should have the same issuer,
 *     or it's expected the response will be signed by a trusted responder.
 *     If the certs need to be broken up into multiple requests, that
 *     must be handled by the caller (and thus by having multiple calls
 *     to this routine), who knows about where the request(s) are being
 *     sent and whether there are any trusted responders in place.
 *   PRTime time
 *     Indicates the time for which the certificate status is to be
 *     determined -- this may be used in the search for the cert's issuer
 *     but has no effect on the request itself.
 *   PRBool addServiceLocator
 *     If true, the Service Locator extension should be added to the
 *     single request(s) for each cert.
 *   CERTCertificate *signerCert
 *     If non-NULL, means sign the request using this cert.  Otherwise,
 *     do not sign.
 *     XXX note that request signing is not yet supported; see comment in code
 * RETURN:
 *   A pointer to a CERTOCSPRequest structure containing an OCSP request
 *   for the cert list.  On error, null is returned, with an error set
 *   indicating the reason.  This is likely SEC_ERROR_UNKNOWN_ISSUER.
 *   (The issuer is needed to create a request for the certificate.)
 *   Other errors are low-level problems (no memory, bad database, etc.).
 */
CERTOCSPRequest *
CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
                       PRBool addServiceLocator,
                       CERTCertificate *signerCert)
{
    CERTOCSPRequest *request = NULL;

    if (!certList) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    /*
     * XXX When we are prepared to put signing of requests back in,
     * we will need to allocate a signature
     * structure for the request, fill in the "derCerts" field in it,
     * save the signerCert there, as well as fill in the "requestorName"
     * field of the tbsRequest.
     */
    if (signerCert != NULL) {
        PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
        return NULL;
    }
    request = ocsp_prepareEmptyOCSPRequest();
    if (!request)
        return NULL;
    /*
     * Now create the list of single requests, one for each cert.
     */
    request->tbsRequest->requestList =
        ocsp_CreateSingleRequestList(request->arena,
                                     certList,
                                     time,
                                     addServiceLocator);
    if (request->tbsRequest->requestList == NULL) {
        PORT_FreeArena(request->arena, PR_FALSE);
        return NULL;
    }
    return request;
}

/*
 * FUNCTION: CERT_AddOCSPAcceptableResponses
 *   Add the AcceptableResponses extension to an OCSP Request.
 * INPUTS:
 *   CERTOCSPRequest *request
 *     The request to which the extension should be added.
 *   ...
 *     A list (of one or more) of SECOidTag -- each of the response types
 *     to be added.  The last OID *must* be SEC_OID_PKIX_OCSP_BASIC_RESPONSE.
 *     (This marks the end of the list, and it must be specified because a
 *     client conforming to the OCSP standard is required to handle the basic
 *     response type.)  The OIDs are not checked in any way.
 * RETURN:
 *   SECSuccess if the extension is added; SECFailure if anything goes wrong.
 *   All errors are internal or low-level problems (e.g. no memory).
 */

void
SetRequestExts(void *object, CERTCertExtension **exts)
{
    CERTOCSPRequest *request = (CERTOCSPRequest *)object;

    request->tbsRequest->requestExtensions = exts;
}

#if defined(__GNUC__) && !defined(NSS_NO_GCC48)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wvarargs"
#endif
SECStatus
CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
                                SECOidTag responseType0, ...)
{
    void *extHandle;
    va_list ap;
    int i, count;
    SECOidTag responseType;
    SECOidData *responseOid;
    SECItem **acceptableResponses = NULL;
    SECStatus rv = SECFailure;

    extHandle = request->tbsRequest->extensionHandle;
    if (extHandle == NULL) {
        extHandle = cert_StartExtensions(request, request->arena, SetRequestExts);
        if (extHandle == NULL)
            goto loser;
    }

    /* Count number of OIDS going into the extension value. */
    count = 1;
    if (responseType0 != SEC_OID_PKIX_OCSP_BASIC_RESPONSE) {
        va_start(ap, responseType0);
        do {
            count++;
            responseType = va_arg(ap, SECOidTag);
        } while (responseType != SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
        va_end(ap);
    }

    acceptableResponses = PORT_NewArray(SECItem *, count + 1);
    if (acceptableResponses == NULL)
        goto loser;

    i = 0;
    responseOid = SECOID_FindOIDByTag(responseType0);
    acceptableResponses[i++] = &(responseOid->oid);
    if (count > 1) {
        va_start(ap, responseType0);
        for (; i < count; i++) {
            responseType = va_arg(ap, SECOidTag);
            responseOid = SECOID_FindOIDByTag(responseType);
            acceptableResponses[i] = &(responseOid->oid);
        }
        va_end(ap);
    }
    acceptableResponses[i] = NULL;

    rv = CERT_EncodeAndAddExtension(extHandle, SEC_OID_PKIX_OCSP_RESPONSE,
                                    &acceptableResponses, PR_FALSE,
                                    SEC_ASN1_GET(SEC_SequenceOfObjectIDTemplate));
    if (rv != SECSuccess)
        goto loser;

    PORT_Free(acceptableResponses);
    if (request->tbsRequest->extensionHandle == NULL)
        request->tbsRequest->extensionHandle = extHandle;
    return SECSuccess;

loser:
    if (acceptableResponses != NULL)
        PORT_Free(acceptableResponses);
    if (extHandle != NULL)
        (void)CERT_FinishExtensions(extHandle);
    return rv;
}
#if defined(__GNUC__) && !defined(NSS_NO_GCC48)
#pragma GCC diagnostic pop
#endif

/*
 * FUNCTION: CERT_DestroyOCSPRequest
 *   Frees an OCSP Request structure.
 * INPUTS:
 *   CERTOCSPRequest *request
 *     Pointer to CERTOCSPRequest to be freed.
 * RETURN:
 *   No return value; no errors.
 */
void
CERT_DestroyOCSPRequest(CERTOCSPRequest *request)
{
    if (request == NULL)
        return;

    if (request->tbsRequest != NULL) {
        if (request->tbsRequest->requestorName != NULL)
            CERT_DestroyGeneralNameList(request->tbsRequest->requestorName);
        if (request->tbsRequest->extensionHandle != NULL)
            (void)CERT_FinishExtensions(request->tbsRequest->extensionHandle);
    }

    if (request->optionalSignature != NULL) {
        if (request->optionalSignature->cert != NULL)
            CERT_DestroyCertificate(request->optionalSignature->cert);

        /*
	 * XXX Need to free derCerts?  Or do they come out of arena?
	 * (Currently we never fill in derCerts, which is why the
	 * answer is not obvious.  Once we do, add any necessary code
	 * here and remove this comment.)
	 */
    }

    /*
     * We should actually never have a request without an arena,
     * but check just in case.  (If there isn't one, there is not
     * much we can do about it...)
     */
    PORT_Assert(request->arena != NULL);
    if (request->arena != NULL)
        PORT_FreeArena(request->arena, PR_FALSE);
}

/*
 * RESPONSE SUPPORT FUNCTIONS (encode/create/decode/destroy):
 */

/*
 * Helper function for encoding or decoding a ResponderID -- based on the
 * given type, return the associated template for that choice.
 */
static const SEC_ASN1Template *
ocsp_ResponderIDTemplateByType(CERTOCSPResponderIDType responderIDType)
{
    const SEC_ASN1Template *responderIDTemplate;

    switch (responderIDType) {
        case ocspResponderID_byName:
            responderIDTemplate = ocsp_ResponderIDByNameTemplate;
            break;
        case ocspResponderID_byKey:
            responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
            break;
        case ocspResponderID_other:
        default:
            PORT_Assert(responderIDType == ocspResponderID_other);
            responderIDTemplate = ocsp_ResponderIDOtherTemplate;
            break;
    }

    return responderIDTemplate;
}

/*
 * Helper function for encoding or decoding a CertStatus -- based on the
 * given type, return the associated template for that choice.
 */
static const SEC_ASN1Template *
ocsp_CertStatusTemplateByType(ocspCertStatusType certStatusType)
{
    const SEC_ASN1Template *certStatusTemplate;

    switch (certStatusType) {
        case ocspCertStatus_good:
            certStatusTemplate = ocsp_CertStatusGoodTemplate;
            break;
        case ocspCertStatus_revoked:
            certStatusTemplate = ocsp_CertStatusRevokedTemplate;
            break;
        case ocspCertStatus_unknown:
            certStatusTemplate = ocsp_CertStatusUnknownTemplate;
            break;
        case ocspCertStatus_other:
        default:
            PORT_Assert(certStatusType == ocspCertStatus_other);
            certStatusTemplate = ocsp_CertStatusOtherTemplate;
            break;
    }

    return certStatusTemplate;
}

/*
 * Helper function for decoding a certStatus -- turn the actual DER tag
 * into our local translation.
 */
static ocspCertStatusType
ocsp_CertStatusTypeByTag(int derTag)
{
    ocspCertStatusType certStatusType;

    switch (derTag) {
        case 0:
            certStatusType = ocspCertStatus_good;
            break;
        case 1:
            certStatusType = ocspCertStatus_revoked;
            break;
        case 2:
            certStatusType = ocspCertStatus_unknown;
            break;
        default:
            certStatusType = ocspCertStatus_other;
            break;
    }

    return certStatusType;
}

/*
 * Helper function for decoding SingleResponses -- they each contain
 * a status which is encoded as CHOICE, which needs to be decoded "by hand".
 *
 * Note -- on error, this routine does not release the memory it may
 * have allocated; it expects its caller to do that.
 */
static SECStatus
ocsp_FinishDecodingSingleResponses(PLArenaPool *reqArena,
                                   CERTOCSPSingleResponse **responses)
{
    ocspCertStatus *certStatus;
    ocspCertStatusType certStatusType;
    const SEC_ASN1Template *certStatusTemplate;
    int derTag;
    int i;
    SECStatus rv = SECFailure;

    if (!reqArena) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (responses == NULL) /* nothing to do */
        return SECSuccess;

    for (i = 0; responses[i] != NULL; i++) {
        SECItem *newStatus;
        /*
	 * The following assert points out internal errors (problems in
	 * the template definitions or in the ASN.1 decoder itself, etc.).
	 */
        PORT_Assert(responses[i]->derCertStatus.data != NULL);

        derTag = responses[i]->derCertStatus.data[0] & SEC_ASN1_TAGNUM_MASK;
        certStatusType = ocsp_CertStatusTypeByTag(derTag);
        certStatusTemplate = ocsp_CertStatusTemplateByType(certStatusType);

        certStatus = PORT_ArenaZAlloc(reqArena, sizeof(ocspCertStatus));
        if (certStatus == NULL) {
            goto loser;
        }
        newStatus = SECITEM_ArenaDupItem(reqArena, &responses[i]->derCertStatus);
        if (!newStatus) {
            goto loser;
        }
        rv = SEC_QuickDERDecodeItem(reqArena, certStatus, certStatusTemplate,
                                    newStatus);
        if (rv != SECSuccess) {
            if (PORT_GetError() == SEC_ERROR_BAD_DER)
                PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
            goto loser;
        }

        certStatus->certStatusType = certStatusType;
        responses[i]->certStatus = certStatus;
    }

    return SECSuccess;

loser:
    return rv;
}

/*
 * Helper function for decoding a responderID -- turn the actual DER tag
 * into our local translation.
 */
static CERTOCSPResponderIDType
ocsp_ResponderIDTypeByTag(int derTag)
{
    CERTOCSPResponderIDType responderIDType;

    switch (derTag) {
        case 1:
            responderIDType = ocspResponderID_byName;
            break;
        case 2:
            responderIDType = ocspResponderID_byKey;
            break;
        default:
            responderIDType = ocspResponderID_other;
            break;
    }

    return responderIDType;
}

/*
 * Decode "src" as a BasicOCSPResponse, returning the result.
 */
static ocspBasicOCSPResponse *
ocsp_DecodeBasicOCSPResponse(PLArenaPool *arena, SECItem *src)
{
    void *mark;
    ocspBasicOCSPResponse *basicResponse;
    ocspResponseData *responseData;
    ocspResponderID *responderID;
    CERTOCSPResponderIDType responderIDType;
    const SEC_ASN1Template *responderIDTemplate;
    int derTag;
    SECStatus rv;
    SECItem newsrc;

    mark = PORT_ArenaMark(arena);

    basicResponse = PORT_ArenaZAlloc(arena, sizeof(ocspBasicOCSPResponse));
    if (basicResponse == NULL) {
        goto loser;
    }

    /* copy the DER into the arena, since Quick DER returns data that points
       into the DER input, which may get freed by the caller */
    rv = SECITEM_CopyItem(arena, &newsrc, src);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = SEC_QuickDERDecodeItem(arena, basicResponse,
                                ocsp_BasicOCSPResponseTemplate, &newsrc);
    if (rv != SECSuccess) {
        if (PORT_GetError() == SEC_ERROR_BAD_DER)
            PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
        goto loser;
    }

    responseData = basicResponse->tbsResponseData;

    /*
     * The following asserts point out internal errors (problems in
     * the template definitions or in the ASN.1 decoder itself, etc.).
     */
    PORT_Assert(responseData != NULL);
    PORT_Assert(responseData->derResponderID.data != NULL);

    /*
     * XXX Because responderID is a CHOICE, which is not currently handled
     * by our ASN.1 decoder, we have to decode it "by hand".
     */
    derTag = responseData->derResponderID.data[0] & SEC_ASN1_TAGNUM_MASK;
    responderIDType = ocsp_ResponderIDTypeByTag(derTag);
    responderIDTemplate = ocsp_ResponderIDTemplateByType(responderIDType);

    responderID = PORT_ArenaZAlloc(arena, sizeof(ocspResponderID));
    if (responderID == NULL) {
        goto loser;
    }

    rv = SEC_QuickDERDecodeItem(arena, responderID, responderIDTemplate,
                                &responseData->derResponderID);
    if (rv != SECSuccess) {
        if (PORT_GetError() == SEC_ERROR_BAD_DER)
            PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
        goto loser;
    }

    responderID->responderIDType = responderIDType;
    responseData->responderID = responderID;

    /*
     * XXX Each SingleResponse also contains a CHOICE, which has to be
     * fixed up by hand.
     */
    rv = ocsp_FinishDecodingSingleResponses(arena, responseData->responses);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_ArenaUnmark(arena, mark);
    return basicResponse;

loser:
    PORT_ArenaRelease(arena, mark);
    return NULL;
}

/*
 * Decode the responseBytes based on the responseType found in "rbytes",
 * leaving the resulting translated/decoded information in there as well.
 */
static SECStatus
ocsp_DecodeResponseBytes(PLArenaPool *arena, ocspResponseBytes *rbytes)
{
    if (rbytes == NULL) {
        PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE);
        return SECFailure;
    }

    rbytes->responseTypeTag = SECOID_FindOIDTag(&rbytes->responseType);
    switch (rbytes->responseTypeTag) {
        case SEC_OID_PKIX_OCSP_BASIC_RESPONSE: {
            ocspBasicOCSPResponse *basicResponse;

            basicResponse = ocsp_DecodeBasicOCSPResponse(arena,
                                                         &rbytes->response);
            if (basicResponse == NULL)
                return SECFailure;

            rbytes->decodedResponse.basic = basicResponse;
        } break;

        /*
	 * Add new/future response types here.
	 */

        default:
            PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE);
            return SECFailure;
    }

    return SECSuccess;
}

/*
 * FUNCTION: CERT_DecodeOCSPResponse
 *   Decode a DER encoded OCSP Response.
 * INPUTS:
 *   SECItem *src
 *     Pointer to a SECItem holding DER encoded OCSP Response.
 * RETURN:
 *   Returns a pointer to a CERTOCSPResponse (the decoded OCSP Response);
 *   the caller is responsible for destroying it.  Or NULL if error (either
 *   response could not be decoded (SEC_ERROR_OCSP_MALFORMED_RESPONSE),
 *   it was of an unexpected type (SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE),
 *   or a low-level or internal error occurred).
 */
CERTOCSPResponse *
CERT_DecodeOCSPResponse(const SECItem *src)
{
    PLArenaPool *arena = NULL;
    CERTOCSPResponse *response = NULL;
    SECStatus rv = SECFailure;
    ocspResponseStatus sv;
    SECItem newSrc;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }
    response = (CERTOCSPResponse *)PORT_ArenaZAlloc(arena,
                                                    sizeof(CERTOCSPResponse));
    if (response == NULL) {
        goto loser;
    }
    response->arena = arena;

    /* copy the DER into the arena, since Quick DER returns data that points
       into the DER input, which may get freed by the caller */
    rv = SECITEM_CopyItem(arena, &newSrc, src);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = SEC_QuickDERDecodeItem(arena, response, ocsp_OCSPResponseTemplate, &newSrc);
    if (rv != SECSuccess) {
        if (PORT_GetError() == SEC_ERROR_BAD_DER)
            PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
        goto loser;
    }

    sv = (ocspResponseStatus)DER_GetInteger(&response->responseStatus);
    response->statusValue = sv;
    if (sv != ocspResponse_successful) {
        /*
	 * If the response status is anything but successful, then we
	 * are all done with decoding; the status is all there is.
	 */
        return response;
    }

    /*
     * A successful response contains much more information, still encoded.
     * Now we need to decode that.
     */
    rv = ocsp_DecodeResponseBytes(arena, response->responseBytes);
    if (rv != SECSuccess) {
        goto loser;
    }

    return response;

loser:
    if (arena != NULL) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return NULL;
}

/*
 * The way an OCSPResponse is defined, there are many levels to descend
 * before getting to the actual response information.  And along the way
 * we need to check that the response *type* is recognizable, which for
 * now means that it is a BasicOCSPResponse, because that is the only
 * type currently defined.  Rather than force all routines to perform
 * a bunch of sanity checking every time they want to work on a response,
 * this function isolates that and gives back the interesting part.
 * Note that no copying is done, this just returns a pointer into the
 * substructure of the response which is passed in.
 *
 * XXX This routine only works when a valid response structure is passed
 * into it; this is checked with many assertions.  Assuming the response
 * was creating by decoding, it wouldn't make it this far without being
 * okay.  That is a sufficient assumption since the entire OCSP interface
 * is only used internally.  When this interface is officially exported,
 * each assertion below will need to be followed-up with setting an error
 * and returning (null).
 *
 * FUNCTION: ocsp_GetResponseData
 *   Returns ocspResponseData structure and a pointer to tbs response
 *   data DER from a valid ocsp response.
 * INPUTS:
 *   CERTOCSPResponse *response
 *     structure of a valid ocsp response
 * RETURN:
 *   Returns a pointer to ocspResponseData structure: decoded OCSP response
 *   data, and a pointer(tbsResponseDataDER) to its undecoded data DER.
 */
ocspResponseData *
ocsp_GetResponseData(CERTOCSPResponse *response, SECItem **tbsResponseDataDER)
{
    ocspBasicOCSPResponse *basic;
    ocspResponseData *responseData;

    PORT_Assert(response != NULL);

    PORT_Assert(response->responseBytes != NULL);

    PORT_Assert(response->responseBytes->responseTypeTag ==
                SEC_OID_PKIX_OCSP_BASIC_RESPONSE);

    basic = response->responseBytes->decodedResponse.basic;
    PORT_Assert(basic != NULL);

    responseData = basic->tbsResponseData;
    PORT_Assert(responseData != NULL);

    if (tbsResponseDataDER) {
        *tbsResponseDataDER = &basic->tbsResponseDataDER;

        PORT_Assert((*tbsResponseDataDER)->data != NULL);
        PORT_Assert((*tbsResponseDataDER)->len != 0);
    }

    return responseData;
}

/*
 * Much like the routine above, except it returns the response signature.
 * Again, no copy is done.
 */
ocspSignature *
ocsp_GetResponseSignature(CERTOCSPResponse *response)
{
    ocspBasicOCSPResponse *basic;

    PORT_Assert(response != NULL);
    if (NULL == response->responseBytes) {
        return NULL;
    }
    if (response->responseBytes->responseTypeTag !=
        SEC_OID_PKIX_OCSP_BASIC_RESPONSE) {
        return NULL;
    }
    basic = response->responseBytes->decodedResponse.basic;
    PORT_Assert(basic != NULL);

    return &(basic->responseSignature);
}

/*
 * FUNCTION: CERT_DestroyOCSPResponse
 *   Frees an OCSP Response structure.
 * INPUTS:
 *   CERTOCSPResponse *request
 *     Pointer to CERTOCSPResponse to be freed.
 * RETURN:
 *   No return value; no errors.
 */
void
CERT_DestroyOCSPResponse(CERTOCSPResponse *response)
{
    if (response != NULL) {
        ocspSignature *signature = ocsp_GetResponseSignature(response);
        if (signature && signature->cert != NULL)
            CERT_DestroyCertificate(signature->cert);

        /*
	 * We should actually never have a response without an arena,
	 * but check just in case.  (If there isn't one, there is not
	 * much we can do about it...)
	 */
        PORT_Assert(response->arena != NULL);
        if (response->arena != NULL) {
            PORT_FreeArena(response->arena, PR_FALSE);
        }
    }
}

/*
 * OVERALL OCSP CLIENT SUPPORT (make and send a request, verify a response):
 */

/*
 * Pick apart a URL, saving the important things in the passed-in pointers.
 *
 * We expect to find "http://<hostname>[:<port>]/[path]", though we will
 * tolerate that final slash character missing, as well as beginning and
 * trailing whitespace, and any-case-characters for "http".  All of that
 * tolerance is what complicates this routine.  What we want is just to
 * pick out the hostname, the port, and the path.
 *
 * On a successful return, the caller will need to free the output pieces
 * of hostname and path, which are copies of the values found in the url.
 */
static SECStatus
ocsp_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
{
    unsigned short port = 80; /* default, in case not in url */
    char *hostname = NULL;
    char *path = NULL;
    const char *save;
    char c;
    int len;

    if (url == NULL)
        goto loser;

    /*
     * Skip beginning whitespace.
     */
    c = *url;
    while ((c == ' ' || c == '\t') && c != '\0') {
        url++;
        c = *url;
    }
    if (c == '\0')
        goto loser;

    /*
     * Confirm, then skip, protocol.  (Since we only know how to do http,
     * that is all we will accept).
     */
    if (PORT_Strncasecmp(url, "http://", 7) != 0)
        goto loser;
    url += 7;

    /*
     * Whatever comes next is the hostname (or host IP address).  We just
     * save it aside and then search for its end so we can determine its
     * length and copy it.
     *
     * XXX Note that because we treat a ':' as a terminator character
     * (and below, we expect that to mean there is a port specification
     * immediately following), we will not handle IPv6 addresses.  That is
     * apparently an acceptable limitation, for the time being.  Some day,
     * when there is a clear way to specify a URL with an IPv6 address that
     * can be parsed unambiguously, this code should be made to do that.
     */
    save = url;
    c = *url;
    while (c != '/' && c != ':' && c != '\0' && c != ' ' && c != '\t') {
        url++;
        c = *url;
    }
    len = url - save;
    hostname = PORT_Alloc(len + 1);
    if (hostname == NULL)
        goto loser;
    PORT_Memcpy(hostname, save, len);
    hostname[len] = '\0';

    /*
     * Now we figure out if there was a port specified or not.
     * If so, we need to parse it (as a number) and skip it.
     */
    if (c == ':') {
        url++;
        port = (unsigned short)PORT_Atoi(url);
        c = *url;
        while (c != '/' && c != '\0' && c != ' ' && c != '\t') {
            if (c < '0' || c > '9')
                goto loser;
            url++;
            c = *url;
        }
    }

    /*
     * Last thing to find is a path.  There *should* be a slash,
     * if nothing else -- but if there is not we provide one.
     */
    if (c == '/') {
        save = url;
        while (c != '\0' && c != ' ' && c != '\t') {
            url++;
            c = *url;
        }
        len = url - save;
        path = PORT_Alloc(len + 1);
        if (path == NULL)
            goto loser;
        PORT_Memcpy(path, save, len);
        path[len] = '\0';
    } else {
        path = PORT_Strdup("/");
        if (path == NULL)
            goto loser;
    }

    *pHostname = hostname;
    *pPort = port;
    *pPath = path;
    return SECSuccess;

loser:
    if (hostname != NULL)
        PORT_Free(hostname);
    PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
    return SECFailure;
}

/*
 * Open a socket to the specified host on the specified port, and return it.
 * The host is either a hostname or an IP address.
 */
static PRFileDesc *
ocsp_ConnectToHost(const char *host, PRUint16 port)
{
    PRFileDesc *sock = NULL;
    PRIntervalTime timeout;
    PRNetAddr addr;
    char *netdbbuf = NULL;

    sock = PR_NewTCPSocket();
    if (sock == NULL)
        goto loser;

    /* XXX Some day need a way to set (and get?) the following value */
    timeout = PR_SecondsToInterval(30);

    /*
     * If the following converts an IP address string in "dot notation"
     * into a PRNetAddr.  If it fails, we assume that is because we do not
     * have such an address, but instead a host *name*.  In that case we
     * then lookup the host by name.  Using the NSPR function this way
     * means we do not have to have our own logic for distinguishing a
     * valid numerical IP address from a hostname.
     */
    if (PR_StringToNetAddr(host, &addr) != PR_SUCCESS) {
        PRIntn hostIndex;
        PRHostEnt hostEntry;

        netdbbuf = PORT_Alloc(PR_NETDB_BUF_SIZE);
        if (netdbbuf == NULL)
            goto loser;

        if (PR_GetHostByName(host, netdbbuf, PR_NETDB_BUF_SIZE,
                             &hostEntry) != PR_SUCCESS)
            goto loser;

        hostIndex = 0;
        do {
            hostIndex = PR_EnumerateHostEnt(hostIndex, &hostEntry, port, &addr);
            if (hostIndex <= 0)
                goto loser;
        } while (PR_Connect(sock, &addr, timeout) != PR_SUCCESS);

        PORT_Free(netdbbuf);
    } else {
        /*
	 * First put the port into the address, then connect.
	 */
        if (PR_InitializeNetAddr(PR_IpAddrNull, port, &addr) != PR_SUCCESS)
            goto loser;
        if (PR_Connect(sock, &addr, timeout) != PR_SUCCESS)
            goto loser;
    }

    return sock;

loser:
    if (sock != NULL)
        PR_Close(sock);
    if (netdbbuf != NULL)
        PORT_Free(netdbbuf);
    return NULL;
}

/*
 * Sends an encoded OCSP request to the server identified by "location",
 * and returns the socket on which it was sent (so can listen for the reply).
 * "location" is expected to be a valid URL -- an error parsing it produces
 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION.  Other errors are likely problems
 * connecting to it, or writing to it, or allocating memory, and the low-level
 * errors appropriate to the problem will be set.
 * if (encodedRequest == NULL)
 *   then location MUST already include the full request,
 *        including base64 and urlencode,
 *        and the request will be sent with GET
 * if (encodedRequest != NULL)
 *   then the request will be sent with POST
 */
static PRFileDesc *
ocsp_SendEncodedRequest(const char *location, const SECItem *encodedRequest)
{
    char *hostname = NULL;
    char *path = NULL;
    PRUint16 port;
    SECStatus rv;
    PRFileDesc *sock = NULL;
    PRFileDesc *returnSock = NULL;
    char *header = NULL;
    char portstr[16];

    /*
     * Take apart the location, getting the hostname, port, and path.
     */
    rv = ocsp_ParseURL(location, &hostname, &port, &path);
    if (rv != SECSuccess)
        goto loser;

    PORT_Assert(hostname != NULL);
    PORT_Assert(path != NULL);

    sock = ocsp_ConnectToHost(hostname, port);
    if (sock == NULL)
        goto loser;

    portstr[0] = '\0';
    if (port != 80) {
        PR_snprintf(portstr, sizeof(portstr), ":%d", port);
    }

    if (!encodedRequest) {
        header = PR_smprintf("GET %s HTTP/1.0\r\n"
                             "Host: %s%s\r\n\r\n",
                             path, hostname, portstr);
        if (header == NULL)
            goto loser;

        /*
         * The NSPR documentation promises that if it can, it will write the full
         * amount; this will not return a partial value expecting us to loop.
         */
        if (PR_Write(sock, header, (PRInt32)PORT_Strlen(header)) < 0)
            goto loser;
    } else {
        header = PR_smprintf("POST %s HTTP/1.0\r\n"
                             "Host: %s%s\r\n"
                             "Content-Type: application/ocsp-request\r\n"
                             "Content-Length: %u\r\n\r\n",
                             path, hostname, portstr, encodedRequest->len);
        if (header == NULL)
            goto loser;

        /*
         * The NSPR documentation promises that if it can, it will write the full
         * amount; this will not return a partial value expecting us to loop.
         */
        if (PR_Write(sock, header, (PRInt32)PORT_Strlen(header)) < 0)
            goto loser;

        if (PR_Write(sock, encodedRequest->data,
                     (PRInt32)encodedRequest->len) < 0)
            goto loser;
    }

    returnSock = sock;
    sock = NULL;

loser:
    if (header != NULL)
        PORT_Free(header);
    if (sock != NULL)
        PR_Close(sock);
    if (path != NULL)
        PORT_Free(path);
    if (hostname != NULL)
        PORT_Free(hostname);

    return returnSock;
}

/*
 * Read from "fd" into "buf" -- expect/attempt to read a given number of bytes
 * Obviously, stop if hit end-of-stream. Timeout is passed in.
 */

static int
ocsp_read(PRFileDesc *fd, char *buf, int toread, PRIntervalTime timeout)
{
    int total = 0;

    while (total < toread) {
        PRInt32 got;

        got = PR_Recv(fd, buf + total, (PRInt32)(toread - total), 0, timeout);
        if (got < 0) {
            if (0 == total) {
                total = -1; /* report the error if we didn't read anything yet */
            }
            break;
        } else if (got == 0) { /* EOS */
            break;
        }

        total += got;
    }

    return total;
}

#define OCSP_BUFSIZE 1024

#define AbortHttpDecode(error)   \
    {                            \
        if (inBuffer)            \
            PORT_Free(inBuffer); \
        PORT_SetError(error);    \
        return NULL;             \
    }

/*
 * Reads on the given socket and returns an encoded response when received.
 * Properly formatted HTTP/1.0 response headers are expected to be read
 * from the socket, preceding a binary-encoded OCSP response.  Problems
 * with parsing cause the error SEC_ERROR_OCSP_BAD_HTTP_RESPONSE to be
 * set; any other problems are likely low-level i/o or memory allocation
 * errors.
 */
static SECItem *
ocsp_GetEncodedResponse(PLArenaPool *arena, PRFileDesc *sock)
{
    /* first read HTTP status line and headers */

    char *inBuffer = NULL;
    PRInt32 offset = 0;
    PRInt32 inBufsize = 0;
    const PRInt32 bufSizeIncrement = OCSP_BUFSIZE;   /* 1 KB at a time */
    const PRInt32 maxBufSize = 8 * bufSizeIncrement; /* 8 KB max */
    const char *CRLF = "\r\n";
    const PRInt32 CRLFlen = strlen(CRLF);
    const char *headerEndMark = "\r\n\r\n";
    const PRInt32 markLen = strlen(headerEndMark);
    const PRIntervalTime ocsptimeout =
        PR_SecondsToInterval(30); /* hardcoded to 30s for now */
    char *headerEnd = NULL;
    PRBool EOS = PR_FALSE;
    const char *httpprotocol = "HTTP/";
    const PRInt32 httplen = strlen(httpprotocol);
    const char *httpcode = NULL;
    const char *contenttype = NULL;
    PRInt32 contentlength = 0;
    PRInt32 bytesRead = 0;
    char *statusLineEnd = NULL;
    char *space = NULL;
    char *nextHeader = NULL;
    SECItem *result = NULL;

    /* read up to at least the end of the HTTP headers */
    do {
        inBufsize += bufSizeIncrement;
        inBuffer = PORT_Realloc(inBuffer, inBufsize + 1);
        if (NULL == inBuffer) {
            AbortHttpDecode(SEC_ERROR_NO_MEMORY);
        }
        bytesRead = ocsp_read(sock, inBuffer + offset, bufSizeIncrement,
                              ocsptimeout);
        if (bytesRead > 0) {
            PRInt32 searchOffset = (offset - markLen) > 0 ? offset - markLen : 0;
            offset += bytesRead;
            *(inBuffer + offset) = '\0'; /* NULL termination */
            headerEnd = strstr((const char *)inBuffer + searchOffset, headerEndMark);
            if (bytesRead < bufSizeIncrement) {
                /* we read less data than requested, therefore we are at
                   EOS or there was a read error */
                EOS = PR_TRUE;
            }
        } else {
            /* recv error or EOS */
            EOS = PR_TRUE;
        }
    } while ((!headerEnd) && (PR_FALSE == EOS) &&
             (inBufsize < maxBufSize));

    if (!headerEnd) {
        AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
    }

    /* parse the HTTP status line  */
    statusLineEnd = strstr((const char *)inBuffer, CRLF);
    if (!statusLineEnd) {
        AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
    }
    *statusLineEnd = '\0';

    /* check for HTTP/ response */
    space = strchr((const char *)inBuffer, ' ');
    if (!space || PORT_Strncasecmp((const char *)inBuffer, httpprotocol, httplen) != 0) {
        AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
    }

    /* check the HTTP status code of 200 */
    httpcode = space + 1;
    space = strchr(httpcode, ' ');
    if (!space) {
        AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
    }
    *space = 0;
    if (0 != strcmp(httpcode, "200")) {
        AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
    }

    /* parse the HTTP headers in the buffer . We only care about
       content-type and content-length
    */

    nextHeader = statusLineEnd + CRLFlen;
    *headerEnd = '\0'; /* terminate */
    do {
        char *thisHeaderEnd = NULL;
        char *value = NULL;
        char *colon = strchr(nextHeader, ':');

        if (!colon) {
            AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
        }

        *colon = '\0';
        value = colon + 1;

        /* jpierre - note : the following code will only handle the basic form
           of HTTP/1.0 response headers, of the form "name: value" . Headers
           split among multiple lines are not supported. This is not common
           and should not be an issue, but it could become one in the
           future */

        if (*value != ' ') {
            AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
        }

        value++;
        thisHeaderEnd = strstr(value, CRLF);
        if (thisHeaderEnd) {
            *thisHeaderEnd = '\0';
        }

        if (0 == PORT_Strcasecmp(nextHeader, "content-type")) {
            contenttype = value;
        } else if (0 == PORT_Strcasecmp(nextHeader, "content-length")) {
            contentlength = atoi(value);
        }

        if (thisHeaderEnd) {
            nextHeader = thisHeaderEnd + CRLFlen;
        } else {
            nextHeader = NULL;
        }

    } while (nextHeader && (nextHeader < (headerEnd + CRLFlen)));

    /* check content-type */
    if (!contenttype ||
        (0 != PORT_Strcasecmp(contenttype, "application/ocsp-response"))) {
        AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
    }

    /* read the body of the OCSP response */
    offset = offset - (PRInt32)(headerEnd - (const char *)inBuffer) - markLen;
    if (offset) {
        /* move all data to the beginning of the buffer */
        PORT_Memmove(inBuffer, headerEnd + markLen, offset);
    }

    /* resize buffer to only what's needed to hold the current response */
    inBufsize = (1 + (offset - 1) / bufSizeIncrement) * bufSizeIncrement;

    while ((PR_FALSE == EOS) &&
           ((contentlength == 0) || (offset < contentlength)) &&
           (inBufsize < maxBufSize)) {
        /* we still need to receive more body data */
        inBufsize += bufSizeIncrement;
        inBuffer = PORT_Realloc(inBuffer, inBufsize + 1);
        if (NULL == inBuffer) {
            AbortHttpDecode(SEC_ERROR_NO_MEMORY);
        }
        bytesRead = ocsp_read(sock, inBuffer + offset, bufSizeIncrement,
                              ocsptimeout);
        if (bytesRead > 0) {
            offset += bytesRead;
            if (bytesRead < bufSizeIncrement) {
                /* we read less data than requested, therefore we are at
                   EOS or there was a read error */
                EOS = PR_TRUE;
            }
        } else {
            /* recv error or EOS */
            EOS = PR_TRUE;
        }
    }

    if (0 == offset) {
        AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
    }

    /*
     * Now allocate the item to hold the data.
     */
    result = SECITEM_AllocItem(arena, NULL, offset);
    if (NULL == result) {
        AbortHttpDecode(SEC_ERROR_NO_MEMORY);
    }

    /*
     * And copy the data left in the buffer.
     */
    PORT_Memcpy(result->data, inBuffer, offset);

    /* and free the temporary buffer */
    PORT_Free(inBuffer);
    return result;
}

SECStatus
CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
{
    return ocsp_ParseURL(url, pHostname, pPort, pPath);
}

/*
 * Limit the size of http responses we are willing to accept.
 */
#define MAX_WANTED_OCSP_RESPONSE_LEN 64 * 1024

/* if (encodedRequest == NULL)
 *   then location MUST already include the full request,
 *        including base64 and urlencode,
 *        and the request will be sent with GET
 * if (encodedRequest != NULL)
 *   then the request will be sent with POST
 */
static SECItem *
fetchOcspHttpClientV1(PLArenaPool *arena,
                      const SEC_HttpClientFcnV1 *hcv1,
                      const char *location,
                      const SECItem *encodedRequest)
{
    char *hostname = NULL;
    char *path = NULL;
    PRUint16 port;
    SECItem *encodedResponse = NULL;
    SEC_HTTP_SERVER_SESSION pServerSession = NULL;
    SEC_HTTP_REQUEST_SESSION pRequestSession = NULL;
    PRUint16 myHttpResponseCode;
    const char *myHttpResponseData;
    PRUint32 myHttpResponseDataLen;

    if (ocsp_ParseURL(location, &hostname, &port, &path) == SECFailure) {
        PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);
        goto loser;
    }

    PORT_Assert(hostname != NULL);
    PORT_Assert(path != NULL);

    if ((*hcv1->createSessionFcn)(
            hostname,
            port,
            &pServerSession) != SECSuccess) {
        PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
        goto loser;
    }

    /* We use a non-zero timeout, which means:
       - the client will use blocking I/O
       - TryFcn will not return WOULD_BLOCK nor a poll descriptor
       - it's sufficient to call TryFcn once
       No lock for accessing OCSP_Global.timeoutSeconds, bug 406120
    */

    if ((*hcv1->createFcn)(
            pServerSession,
            "http",
            path,
            encodedRequest ? "POST" : "GET",
            PR_TicksPerSecond() * OCSP_Global.timeoutSeconds,
            &pRequestSession) != SECSuccess) {
        PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
        goto loser;
    }

    if (encodedRequest &&
        (*hcv1->setPostDataFcn)(
            pRequestSession,
            (char *)encodedRequest->data,
            encodedRequest->len,
            "application/ocsp-request") != SECSuccess) {
        PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
        goto loser;
    }

    /* we don't want result objects larger than this: */
    myHttpResponseDataLen = MAX_WANTED_OCSP_RESPONSE_LEN;

    OCSP_TRACE(("OCSP trySendAndReceive %s\n", location));

    if ((*hcv1->trySendAndReceiveFcn)(
            pRequestSession,
            NULL,
            &myHttpResponseCode,
            NULL,
            NULL,
            &myHttpResponseData,
            &myHttpResponseDataLen) != SECSuccess) {
        PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
        goto loser;
    }

    OCSP_TRACE(("OCSP trySendAndReceive result http %d\n", myHttpResponseCode));

    if (myHttpResponseCode != 200) {
        PORT_SetError(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
        goto loser;
    }

    encodedResponse = SECITEM_AllocItem(arena, NULL, myHttpResponseDataLen);

    if (!encodedResponse) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    PORT_Memcpy(encodedResponse->data, myHttpResponseData, myHttpResponseDataLen);

loser:
    if (pRequestSession != NULL)
        (*hcv1->freeFcn)(pRequestSession);
    if (pServerSession != NULL)
        (*hcv1->freeSessionFcn)(pServerSession);
    if (path != NULL)
        PORT_Free(path);
    if (hostname != NULL)
        PORT_Free(hostname);

    return encodedResponse;
}

/*
 * FUNCTION: CERT_GetEncodedOCSPResponseByMethod
 *   Creates and sends a request to an OCSP responder, then reads and
 *   returns the (encoded) response.
 * INPUTS:
 *   PLArenaPool *arena
 *     Pointer to arena from which return value will be allocated.
 *     If NULL, result will be allocated from the heap (and thus should
 *     be freed via SECITEM_FreeItem).
 *   CERTCertList *certList
 *     A list of certs for which status will be requested.
 *     Note that all of these certificates should have the same issuer,
 *     or it's expected the response will be signed by a trusted responder.
 *     If the certs need to be broken up into multiple requests, that
 *     must be handled by the caller (and thus by having multiple calls
 *     to this routine), who knows about where the request(s) are being
 *     sent and whether there are any trusted responders in place.
 *   const char *location
 *     The location of the OCSP responder (a URL).
 *   const char *method
 *     The protocol method used when retrieving the OCSP response.
 *     Currently support: "GET" (http GET) and "POST" (http POST).
 *     Additionals methods for http or other protocols might be added
 *     in the future.
 *   PRTime time
 *     Indicates the time for which the certificate status is to be
 *     determined -- this may be used in the search for the cert's issuer
 *     but has no other bearing on the operation.
 *   PRBool addServiceLocator
 *     If true, the Service Locator extension should be added to the
 *     single request(s) for each cert.
 *   CERTCertificate *signerCert
 *     If non-NULL, means sign the request using this cert.  Otherwise,
 *     do not sign.
 *   void *pwArg
 *     Pointer to argument for password prompting, if needed.  (Definitely
 *     not needed if not signing.)
 * OUTPUTS:
 *   CERTOCSPRequest **pRequest
 *     Pointer in which to store the OCSP request created for the given
 *     list of certificates.  It is only filled in if the entire operation
 *     is successful and the pointer is not null -- and in that case the
 *     caller is then reponsible for destroying it.
 * RETURN:
 *   Returns a pointer to the SECItem holding the response.
 *   On error, returns null with error set describing the reason:
 *	SEC_ERROR_UNKNOWN_ISSUER
 *	SEC_ERROR_CERT_BAD_ACCESS_LOCATION
 *	SEC_ERROR_OCSP_BAD_HTTP_RESPONSE
 *   Other errors are low-level problems (no memory, bad database, etc.).
 */
SECItem *
CERT_GetEncodedOCSPResponseByMethod(PLArenaPool *arena, CERTCertList *certList,
                                    const char *location, const char *method,
                                    PRTime time, PRBool addServiceLocator,
                                    CERTCertificate *signerCert, void *pwArg,
                                    CERTOCSPRequest **pRequest)
{
    CERTOCSPRequest *request;
    request = CERT_CreateOCSPRequest(certList, time, addServiceLocator,
                                     signerCert);
    if (!request)
        return NULL;
    return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location,
                                                  method, time, addServiceLocator,
                                                  pwArg, pRequest);
}

/*
 * FUNCTION: CERT_GetEncodedOCSPResponse
 *   Creates and sends a request to an OCSP responder, then reads and
 *   returns the (encoded) response.
 *
 * This is a legacy API that behaves identically to
 * CERT_GetEncodedOCSPResponseByMethod using the "POST" method.
 */
SECItem *
CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
                            const char *location, PRTime time,
                            PRBool addServiceLocator,
                            CERTCertificate *signerCert, void *pwArg,
                            CERTOCSPRequest **pRequest)
{
    return CERT_GetEncodedOCSPResponseByMethod(arena, certList, location,
                                               "POST", time, addServiceLocator,
                                               signerCert, pwArg, pRequest);
}

/* URL encode a buffer that consists of base64-characters, only,
 * which means we can use a simple encoding logic.
 *
 * No output buffer size checking is performed.
 * You should call the function twice, to calculate the required buffer size.
 *
 * If the outpufBuf parameter is NULL, the function will calculate the
 * required size, including the trailing zero termination char.
 *
 * The function returns the number of bytes calculated or produced.
 */
size_t
ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf)
{
    const char *walkInput = NULL;
    char *walkOutput = outputBuf;
    size_t count = 0;

    for (walkInput = base64Buf; *walkInput; ++walkInput) {
        char c = *walkInput;
        if (isspace(c))
            continue;
        switch (c) {
            case '+':
                if (outputBuf) {
                    strcpy(walkOutput, "%2B");
                    walkOutput += 3;
                }
                count += 3;
                break;
            case '/':
                if (outputBuf) {
                    strcpy(walkOutput, "%2F");
                    walkOutput += 3;
                }
                count += 3;
                break;
            case '=':
                if (outputBuf) {
                    strcpy(walkOutput, "%3D");
                    walkOutput += 3;
                }
                count += 3;
                break;
            default:
                if (outputBuf) {
                    *walkOutput = *walkInput;
                    ++walkOutput;
                }
                ++count;
                break;
        }
    }
    if (outputBuf) {
        *walkOutput = 0;
    }
    ++count;
    return count;
}

enum { max_get_request_size = 255 }; /* defined by RFC2560 */

static SECItem *
cert_GetOCSPResponse(PLArenaPool *arena, const char *location,
                     const SECItem *encodedRequest);

static SECItem *
ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena,
                                       CERTOCSPRequest *request,
                                       const char *location,
                                       const char *method,
                                       PRTime time,
                                       PRBool addServiceLocator,
                                       void *pwArg,
                                       CERTOCSPRequest **pRequest)
{
    SECItem *encodedRequest = NULL;
    SECItem *encodedResponse = NULL;
    SECStatus rv;

    if (!location || !*location) /* location should be at least one byte */
        goto loser;

    rv = CERT_AddOCSPAcceptableResponses(request,
                                         SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
    if (rv != SECSuccess)
        goto loser;

    encodedRequest = CERT_EncodeOCSPRequest(NULL, request, pwArg);
    if (encodedRequest == NULL)
        goto loser;

    if (!strcmp(method, "GET")) {
        encodedResponse = cert_GetOCSPResponse(arena, location, encodedRequest);
    } else if (!strcmp(method, "POST")) {
        encodedResponse = CERT_PostOCSPRequest(arena, location, encodedRequest);
    } else {
        goto loser;
    }

    if (encodedResponse != NULL && pRequest != NULL) {
        *pRequest = request;
        request = NULL; /* avoid destroying below */
    }

loser:
    if (request != NULL)
        CERT_DestroyOCSPRequest(request);
    if (encodedRequest != NULL)
        SECITEM_FreeItem(encodedRequest, PR_TRUE);
    return encodedResponse;
}

static SECItem *
cert_FetchOCSPResponse(PLArenaPool *arena, const char *location,
                       const SECItem *encodedRequest);

/* using HTTP GET method */
static SECItem *
cert_GetOCSPResponse(PLArenaPool *arena, const char *location,
                     const SECItem *encodedRequest)
{
    char *walkOutput = NULL;
    char *fullGetPath = NULL;
    size_t pathLength;
    PRInt32 urlEncodedBufLength;
    size_t base64size;
    char b64ReqBuf[max_get_request_size + 1];
    size_t slashLengthIfNeeded = 0;
    size_t getURLLength;
    SECItem *item;

    if (!location || !*location) {
        return NULL;
    }

    pathLength = strlen(location);
    if (location[pathLength - 1] != '/') {
        slashLengthIfNeeded = 1;
    }

    /* Calculation as documented by PL_Base64Encode function.
     * Use integer conversion to avoid having to use function ceil().
     */
    base64size = (((encodedRequest->len + 2) / 3) * 4);
    if (base64size > max_get_request_size) {
        return NULL;
    }
    memset(b64ReqBuf, 0, sizeof(b64ReqBuf));
    PL_Base64Encode((const char *)encodedRequest->data, encodedRequest->len,
                    b64ReqBuf);

    urlEncodedBufLength = ocsp_UrlEncodeBase64Buf(b64ReqBuf, NULL);
    getURLLength = pathLength + urlEncodedBufLength + slashLengthIfNeeded;

    /* urlEncodedBufLength already contains room for the zero terminator.
     * Add another if we must add the '/' char.
     */
    if (arena) {
        fullGetPath = (char *)PORT_ArenaAlloc(arena, getURLLength);
    } else {
        fullGetPath = (char *)PORT_Alloc(getURLLength);
    }
    if (!fullGetPath) {
        return NULL;
    }

    strcpy(fullGetPath, location);
    walkOutput = fullGetPath + pathLength;

    if (walkOutput > fullGetPath && slashLengthIfNeeded) {
        strcpy(walkOutput, "/");
        ++walkOutput;
    }
    ocsp_UrlEncodeBase64Buf(b64ReqBuf, walkOutput);

    item = cert_FetchOCSPResponse(arena, fullGetPath, NULL);
    if (!arena) {
        PORT_Free(fullGetPath);
    }
    return item;
}

SECItem *
CERT_PostOCSPRequest(PLArenaPool *arena, const char *location,
                     const SECItem *encodedRequest)
{
    return cert_FetchOCSPResponse(arena, location, encodedRequest);
}

SECItem *
cert_FetchOCSPResponse(PLArenaPool *arena, const char *location,
                       const SECItem *encodedRequest)
{
    const SEC_HttpClientFcn *registeredHttpClient;
    SECItem *encodedResponse = NULL;

    registeredHttpClient = SEC_GetRegisteredHttpClient();

    if (registeredHttpClient && registeredHttpClient->version == 1) {
        encodedResponse = fetchOcspHttpClientV1(
            arena,
            &registeredHttpClient->fcnTable.ftable1,
            location,
            encodedRequest);
    } else {
        /* use internal http client */
        PRFileDesc *sock = ocsp_SendEncodedRequest(location, encodedRequest);
        if (sock) {
            encodedResponse = ocsp_GetEncodedResponse(arena, sock);
            PR_Close(sock);
        }
    }

    return encodedResponse;
}

static SECItem *
ocsp_GetEncodedOCSPResponseForSingleCert(PLArenaPool *arena,
                                         CERTOCSPCertID *certID,
                                         CERTCertificate *singleCert,
                                         const char *location,
                                         const char *method,
                                         PRTime time,
                                         PRBool addServiceLocator,
                                         void *pwArg,
                                         CERTOCSPRequest **pRequest)
{
    CERTOCSPRequest *request;
    request = cert_CreateSingleCertOCSPRequest(certID, singleCert, time,
                                               addServiceLocator, NULL);
    if (!request)
        return NULL;
    return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location,
                                                  method, time, addServiceLocator,
                                                  pwArg, pRequest);
}

/* Checks a certificate for the key usage extension of OCSP signer. */
static PRBool
ocsp_CertIsOCSPDesignatedResponder(CERTCertificate *cert)
{
    SECStatus rv;
    SECItem extItem;
    SECItem **oids;
    SECItem *oid;
    SECOidTag oidTag;
    PRBool retval;
    CERTOidSequence *oidSeq = NULL;

    extItem.data = NULL;
    rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem);
    if (rv != SECSuccess) {
        goto loser;
    }

    oidSeq = CERT_DecodeOidSequence(&extItem);
    if (oidSeq == NULL) {
        goto loser;
    }

    oids = oidSeq->oids;
    while (*oids != NULL) {
        oid = *oids;

        oidTag = SECOID_FindOIDTag(oid);

        if (oidTag == SEC_OID_OCSP_RESPONDER) {
            goto success;
        }

        oids++;
    }

loser:
    retval = PR_FALSE;
    PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
    goto done;
success:
    retval = PR_TRUE;
done:
    if (extItem.data != NULL) {
        PORT_Free(extItem.data);
    }
    if (oidSeq != NULL) {
        CERT_DestroyOidSequence(oidSeq);
    }

    return (retval);
}

#ifdef LATER /*                                                    \
              * XXX This function is not currently used, but will  \
              * be needed later when we do revocation checking of  \
              * the responder certificate.  Of course, it may need \
              * revising then, if the cert extension interface has \
              * changed.  (Hopefully it will!)                     \
              */

/* Checks a certificate to see if it has the OCSP no check extension. */
static PRBool
ocsp_CertHasNoCheckExtension(CERTCertificate *cert)
{
    SECStatus rv;

    rv = CERT_FindCertExtension(cert, SEC_OID_PKIX_OCSP_NO_CHECK,
                                NULL);
    if (rv == SECSuccess) {
        return PR_TRUE;
    }
    return PR_FALSE;
}
#endif /* LATER */

static PRBool
ocsp_matchcert(SECItem *certIndex, CERTCertificate *testCert)
{
    SECItem item;
    unsigned char buf[HASH_LENGTH_MAX];

    item.data = buf;
    item.len = SHA1_LENGTH;

    if (CERT_GetSubjectPublicKeyDigest(NULL, testCert, SEC_OID_SHA1,
                                       &item) == NULL) {
        return PR_FALSE;
    }
    if (SECITEM_ItemsAreEqual(certIndex, &item)) {
        return PR_TRUE;
    }
    if (CERT_GetSubjectPublicKeyDigest(NULL, testCert, SEC_OID_MD5,
                                       &item) == NULL) {
        return PR_FALSE;
    }
    if (SECITEM_ItemsAreEqual(certIndex, &item)) {
        return PR_TRUE;
    }
    if (CERT_GetSubjectPublicKeyDigest(NULL, testCert, SEC_OID_MD2,
                                       &item) == NULL) {
        return PR_FALSE;
    }
    if (SECITEM_ItemsAreEqual(certIndex, &item)) {
        return PR_TRUE;
    }

    return PR_FALSE;
}

static CERTCertificate *
ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle, CERTOCSPCertID *certID);

CERTCertificate *
ocsp_GetSignerCertificate(CERTCertDBHandle *handle, ocspResponseData *tbsData,
                          ocspSignature *signature, CERTCertificate *issuer)
{
    CERTCertificate **certs = NULL;
    CERTCertificate *signerCert = NULL;
    SECStatus rv = SECFailure;
    PRBool lookupByName = PR_TRUE;
    void *certIndex = NULL;
    int certCount = 0;

    PORT_Assert(tbsData->responderID != NULL);
    switch (tbsData->responderID->responderIDType) {
        case ocspResponderID_byName:
            lookupByName = PR_TRUE;
            certIndex = &tbsData->derResponderID;
            break;
        case ocspResponderID_byKey:
            lookupByName = PR_FALSE;
            certIndex = &tbsData->responderID->responderIDValue.keyHash;
            break;
        case ocspResponderID_other:
        default:
            PORT_Assert(0);
            PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
            return NULL;
    }

    /*
     * If the signature contains some certificates as well, temporarily
     * import them in case they are needed for verification.
     *
     * Note that the result of this is that each cert in "certs" needs
     * to be destroyed.
     */
    if (signature->derCerts != NULL) {
        for (; signature->derCerts[certCount] != NULL; certCount++) {
            /* just counting */
        }
        rv = CERT_ImportCerts(handle, certUsageStatusResponder, certCount,
                              signature->derCerts, &certs,
                              PR_FALSE, PR_FALSE, NULL);
        if (rv != SECSuccess)
            goto finish;
    }

    /*
     * Now look up the certificate that did the signing.
     * The signer can be specified either by name or by key hash.
     */
    if (lookupByName) {
        SECItem *crIndex = (SECItem *)certIndex;
        SECItem encodedName;
        PLArenaPool *arena;

        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        if (arena != NULL) {

            rv = SEC_QuickDERDecodeItem(arena, &encodedName,
                                        ocsp_ResponderIDDerNameTemplate,
                                        crIndex);
            if (rv != SECSuccess) {
                if (PORT_GetError() == SEC_ERROR_BAD_DER)
                    PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
            } else {
                signerCert = CERT_FindCertByName(handle, &encodedName);
            }
            PORT_FreeArena(arena, PR_FALSE);
        }
    } else {
        /*
    	 * The signer is either 1) a known issuer CA we passed in,
    	 * 2) the default OCSP responder, or 3) an intermediate CA
    	 * passed in the cert list to use. Figure out which it is.
    	 */
        int i;
        CERTCertificate *responder =
            ocsp_CertGetDefaultResponder(handle, NULL);
        if (responder && ocsp_matchcert(certIndex, responder)) {
            signerCert = CERT_DupCertificate(responder);
        } else if (issuer && ocsp_matchcert(certIndex, issuer)) {
            signerCert = CERT_DupCertificate(issuer);
        }
        for (i = 0; (signerCert == NULL) && (i < certCount); i++) {
            if (ocsp_matchcert(certIndex, certs[i])) {
                signerCert = CERT_DupCertificate(certs[i]);
            }
        }
        if (signerCert == NULL) {
            PORT_SetError(SEC_ERROR_UNKNOWN_CERT);
        }
    }

finish:
    if (certs != NULL) {
        CERT_DestroyCertArray(certs, certCount);
    }

    return signerCert;
}

SECStatus
ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
                             ocspSignature *signature,
                             SECItem *tbsResponseDataDER,
                             void *pwArg)
{
    SECKEYPublicKey *signerKey = NULL;
    SECStatus rv = SECFailure;
    CERTSignedData signedData;

    /*
     * Now get the public key from the signer's certificate; we need
     * it to perform the verification.
     */
    signerKey = CERT_ExtractPublicKey(signerCert);
    if (signerKey == NULL) {
        return SECFailure;
    }

    /*
     * We copy the signature data *pointer* and length, so that we can
     * modify the length without damaging the original copy.  This is a
     * simple copy, not a dup, so no destroy/free is necessary.
     */
    signedData.signature = signature->signature;
    signedData.signatureAlgorithm = signature->signatureAlgorithm;
    signedData.data = *tbsResponseDataDER;

    rv = CERT_VerifySignedDataWithPublicKey(&signedData, signerKey, pwArg);
    if (rv != SECSuccess &&
        (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE ||
         PORT_GetError() == SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED)) {
        PORT_SetError(SEC_ERROR_OCSP_BAD_SIGNATURE);
    }

    if (signerKey != NULL) {
        SECKEY_DestroyPublicKey(signerKey);
    }

    return rv;
}

/*
 * FUNCTION: CERT_VerifyOCSPResponseSignature
 *   Check the signature on an OCSP Response.  Will also perform a
 *   verification of the signer's certificate.  Note, however, that a
 *   successful verification does not make any statement about the
 *   signer's *authority* to provide status for the certificate(s),
 *   that must be checked individually for each certificate.
 * INPUTS:
 *   CERTOCSPResponse *response
 *     Pointer to response structure with signature to be checked.
 *   CERTCertDBHandle *handle
 *     Pointer to CERTCertDBHandle for certificate DB to use for verification.
 *   void *pwArg
 *     Pointer to argument for password prompting, if needed.
 * OUTPUTS:
 *   CERTCertificate **pSignerCert
 *     Pointer in which to store signer's certificate; only filled-in if
 *     non-null.
 * RETURN:
 *   Returns SECSuccess when signature is valid, anything else means invalid.
 *   Possible errors set:
 *	SEC_ERROR_OCSP_MALFORMED_RESPONSE - unknown type of ResponderID
 *	SEC_ERROR_INVALID_TIME - bad format of "ProducedAt" time
 *	SEC_ERROR_UNKNOWN_SIGNER - signer's cert could not be found
 *	SEC_ERROR_BAD_SIGNATURE - the signature did not verify
 *   Other errors are any of the many possible failures in cert verification
 *   (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when
 *   verifying the signer's cert, or low-level problems (no memory, etc.)
 */
SECStatus
CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
                                 CERTCertDBHandle *handle, void *pwArg,
                                 CERTCertificate **pSignerCert,
                                 CERTCertificate *issuer)
{
    SECItem *tbsResponseDataDER;
    CERTCertificate *signerCert = NULL;
    SECStatus rv = SECFailure;
    PRTime producedAt;

    /* ocsp_DecodeBasicOCSPResponse will fail if asn1 decoder is unable
     * to properly decode tbsData (see the function and
     * ocsp_BasicOCSPResponseTemplate). Thus, tbsData can not be
     * equal to null */
    ocspResponseData *tbsData = ocsp_GetResponseData(response,
                                                     &tbsResponseDataDER);
    ocspSignature *signature = ocsp_GetResponseSignature(response);

    if (!signature) {
        PORT_SetError(SEC_ERROR_OCSP_BAD_SIGNATURE);
        return SECFailure;
    }

    /*
     * If this signature has already gone through verification, just
     * return the cached result.
     */
    if (signature->wasChecked) {
        if (signature->status == SECSuccess) {
            if (pSignerCert != NULL)
                *pSignerCert = CERT_DupCertificate(signature->cert);
        } else {
            PORT_SetError(signature->failureReason);
        }
        return signature->status;
    }

    signerCert = ocsp_GetSignerCertificate(handle, tbsData,
                                           signature, issuer);
    if (signerCert == NULL) {
        rv = SECFailure;
        if (PORT_GetError() == SEC_ERROR_UNKNOWN_CERT) {
            /* Make the error a little more specific. */
            PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
        }
        goto finish;
    }

    /*
     * We could mark this true at the top of this function, or always
     * below at "finish", but if the problem was just that we could not
     * find the signer's cert, leave that as if the signature hasn't
     * been checked in case a subsequent call might have better luck.
     */
    signature->wasChecked = PR_TRUE;

    /*
     * The function will also verify the signer certificate; we
     * need to tell it *when* that certificate must be valid -- for our
     * purposes we expect it to be valid when the response was signed.
     * The value of "producedAt" is the signing time.
     */
    rv = DER_GeneralizedTimeToTime(&producedAt, &tbsData->producedAt);
    if (rv != SECSuccess)
        goto finish;

    /*
     * Just because we have a cert does not mean it is any good; check
     * it for validity, trust and usage.
     */
    if (!ocsp_CertIsOCSPDefaultResponder(handle, signerCert)) {
        SECCertUsage certUsage;
        if (CERT_IsCACert(signerCert, NULL)) {
            certUsage = certUsageAnyCA;
        } else {
            certUsage = certUsageStatusResponder;
        }
        rv = cert_VerifyCertWithFlags(handle, signerCert, PR_TRUE, certUsage,
                                      producedAt, CERT_VERIFYCERT_SKIP_OCSP,
                                      pwArg, NULL);
        if (rv != SECSuccess) {
            PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
            goto finish;
        }
    }

    rv = ocsp_VerifyResponseSignature(signerCert, signature,
                                      tbsResponseDataDER,
                                      pwArg);

finish:
    if (signature->wasChecked)
        signature->status = rv;

    if (rv != SECSuccess) {
        signature->failureReason = PORT_GetError();
        if (signerCert != NULL)
            CERT_DestroyCertificate(signerCert);
    } else {
        /*
    	 * Save signer's certificate in signature.
    	 */
        signature->cert = signerCert;
        if (pSignerCert != NULL) {
            /*
    	     * Pass pointer to signer's certificate back to our caller,
    	     * who is also now responsible for destroying it.
    	     */
            *pSignerCert = CERT_DupCertificate(signerCert);
        }
    }

    return rv;
}

/*
 * See if the request's certID and the single response's certID match.
 * This can be easy or difficult, depending on whether the same hash
 * algorithm was used.
 */
static PRBool
ocsp_CertIDsMatch(CERTOCSPCertID *requestCertID,
                  CERTOCSPCertID *responseCertID)
{
    PRBool match = PR_FALSE;
    SECOidTag hashAlg;
    SECItem *keyHash = NULL;
    SECItem *nameHash = NULL;

    /*
     * In order to match, they must have the same issuer and the same
     * serial number.
     *
     * We just compare the easier things first.
     */
    if (SECITEM_CompareItem(&requestCertID->serialNumber,
                            &responseCertID->serialNumber) != SECEqual) {
        goto done;
    }

    /*
     * Make sure the "parameters" are not too bogus.  Since we encoded
     * requestCertID->hashAlgorithm, we don't need to check it.
     */
    if (responseCertID->hashAlgorithm.parameters.len > 2) {
        goto done;
    }
    if (SECITEM_CompareItem(&requestCertID->hashAlgorithm.algorithm,
                            &responseCertID->hashAlgorithm.algorithm) ==
        SECEqual) {
        /*
    	 * If the hash algorithms match then we can do a simple compare
    	 * of the hash values themselves.
    	 */
        if ((SECITEM_CompareItem(&requestCertID->issuerNameHash,
                                 &responseCertID->issuerNameHash) == SECEqual) &&
            (SECITEM_CompareItem(&requestCertID->issuerKeyHash,
                                 &responseCertID->issuerKeyHash) == SECEqual)) {
            match = PR_TRUE;
        }
        goto done;
    }

    hashAlg = SECOID_FindOIDTag(&responseCertID->hashAlgorithm.algorithm);
    switch (hashAlg) {
        case SEC_OID_SHA1:
            keyHash = &requestCertID->issuerSHA1KeyHash;
            nameHash = &requestCertID->issuerSHA1NameHash;
            break;
        case SEC_OID_MD5:
            keyHash = &requestCertID->issuerMD5KeyHash;
            nameHash = &requestCertID->issuerMD5NameHash;
            break;
        case SEC_OID_MD2:
            keyHash = &requestCertID->issuerMD2KeyHash;
            nameHash = &requestCertID->issuerMD2NameHash;
            break;
        default:
            PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
            return PR_FALSE;
    }

    if ((keyHash != NULL) &&
        (SECITEM_CompareItem(nameHash,
                             &responseCertID->issuerNameHash) == SECEqual) &&
        (SECITEM_CompareItem(keyHash,
                             &responseCertID->issuerKeyHash) == SECEqual)) {
        match = PR_TRUE;
    }

done:
    return match;
}

/*
 * Find the single response for the cert specified by certID.
 * No copying is done; this just returns a pointer to the appropriate
 * response within responses, if it is found (and null otherwise).
 * This is fine, of course, since this function is internal-use only.
 */
static CERTOCSPSingleResponse *
ocsp_GetSingleResponseForCertID(CERTOCSPSingleResponse **responses,
                                CERTCertDBHandle *handle,
                                CERTOCSPCertID *certID)
{
    CERTOCSPSingleResponse *single;
    int i;

    if (responses == NULL)
        return NULL;

    for (i = 0; responses[i] != NULL; i++) {
        single = responses[i];
        if (ocsp_CertIDsMatch(certID, single->certID)) {
            return single;
        }
    }

    /*
     * The OCSP server should have included a response even if it knew
     * nothing about the certificate in question.  Since it did not,
     * this will make it look as if it had.
     *
     * XXX Should we make this a separate error to notice the server's
     * bad behavior?
     */
    PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT);
    return NULL;
}

static ocspCheckingContext *
ocsp_GetCheckingContext(CERTCertDBHandle *handle)
{
    CERTStatusConfig *statusConfig;
    ocspCheckingContext *ocspcx = NULL;

    statusConfig = CERT_GetStatusConfig(handle);
    if (statusConfig != NULL) {
        ocspcx = statusConfig->statusContext;

        /*
    	 * This is actually an internal error, because we should never
    	 * have a good statusConfig without a good statusContext, too.
    	 * For lack of anything better, though, we just assert and use
    	 * the same error as if there were no statusConfig (set below).
    	 */
        PORT_Assert(ocspcx != NULL);
    }

    if (ocspcx == NULL)
        PORT_SetError(SEC_ERROR_OCSP_NOT_ENABLED);

    return ocspcx;
}

/*
 * Return cert reference if the given signerCert is the default responder for
 * the given certID.  If not, or if any error, return NULL.
 */
static CERTCertificate *
ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle, CERTOCSPCertID *certID)
{
    ocspCheckingContext *ocspcx;

    ocspcx = ocsp_GetCheckingContext(handle);
    if (ocspcx == NULL)
        goto loser;

    /*
     * Right now we have only one default responder.  It applies to
     * all certs when it is used, so the check is simple and certID
     * has no bearing on the answer.  Someday in the future we may
     * allow configuration of different responders for different
     * issuers, and then we would have to use the issuer specified
     * in certID to determine if signerCert is the right one.
     */
    if (ocspcx->useDefaultResponder) {
        PORT_Assert(ocspcx->defaultResponderCert != NULL);
        return ocspcx->defaultResponderCert;
    }

loser:
    return NULL;
}

/*
 * Return true if the cert is one of the default responders configured for
 * ocsp context. If not, or if any error, return false.
 */
PRBool
ocsp_CertIsOCSPDefaultResponder(CERTCertDBHandle *handle, CERTCertificate *cert)
{
    ocspCheckingContext *ocspcx;

    ocspcx = ocsp_GetCheckingContext(handle);
    if (ocspcx == NULL)
        return PR_FALSE;

    /*
     * Right now we have only one default responder.  It applies to
     * all certs when it is used, so the check is simple and certID
     * has no bearing on the answer.  Someday in the future we may
     * allow configuration of different responders for different
     * issuers, and then we would have to use the issuer specified
     * in certID to determine if signerCert is the right one.
     */
    if (ocspcx->useDefaultResponder &&
        CERT_CompareCerts(ocspcx->defaultResponderCert, cert)) {
        return PR_TRUE;
    }

    return PR_FALSE;
}

/*
 * Check that the given signer certificate is authorized to sign status
 * information for the given certID.  Return true if it is, false if not
 * (or if there is any error along the way).  If false is returned because
 * the signer is not authorized, the following error will be set:
 *	SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE
 * Other errors are low-level problems (no memory, bad database, etc.).
 *
 * There are three ways to be authorized.  In the order in which we check,
 * using the terms used in the OCSP spec, the signer must be one of:
 *  1.  A "trusted responder" -- it matches a local configuration
 *      of OCSP signing authority for the certificate in question.
 *  2.  The CA who issued the certificate in question.
 *  3.  A "CA designated responder", aka an "authorized responder" -- it
 *      must be represented by a special cert issued by the CA who issued
 *      the certificate in question.
 */
static PRBool
ocsp_AuthorizedResponderForCertID(CERTCertDBHandle *handle,
                                  CERTCertificate *signerCert,
                                  CERTOCSPCertID *certID,
                                  PRTime thisUpdate)
{
    CERTCertificate *issuerCert = NULL, *defRespCert;
    SECItem *keyHash = NULL;
    SECItem *nameHash = NULL;
    SECOidTag hashAlg;
    PRBool keyHashEQ = PR_FALSE, nameHashEQ = PR_FALSE;

    /*
     * Check first for a trusted responder, which overrides everything else.
     */
    if ((defRespCert = ocsp_CertGetDefaultResponder(handle, certID)) &&
        CERT_CompareCerts(defRespCert, signerCert)) {
        return PR_TRUE;
    }

    /*
     * In the other two cases, we need to do an issuer comparison.
     * How we do it depends on whether the signer certificate has the
     * special extension (for a designated responder) or not.
     *
     * First, lets check if signer of the response is the actual issuer
     * of the cert. For that we will use signer cert key hash and cert subj
     * name hash and will compare them with already calculated issuer key
     * hash and issuer name hash. The hash algorithm is picked from response
     * certID hash to avoid second hash calculation.
     */

    hashAlg = SECOID_FindOIDTag(&certID->hashAlgorithm.algorithm);

    keyHash = CERT_GetSubjectPublicKeyDigest(NULL, signerCert, hashAlg, NULL);
    if (keyHash != NULL) {

        keyHashEQ =
            (SECITEM_CompareItem(keyHash,
                                 &certID->issuerKeyHash) == SECEqual);
        SECITEM_FreeItem(keyHash, PR_TRUE);
    }
    if (keyHashEQ &&
        (nameHash = CERT_GetSubjectNameDigest(NULL, signerCert,
                                              hashAlg, NULL))) {
        nameHashEQ =
            (SECITEM_CompareItem(nameHash,
                                 &certID->issuerNameHash) == SECEqual);

        SECITEM_FreeItem(nameHash, PR_TRUE);
        if (nameHashEQ) {
            /* The issuer of the cert is the the signer of the response */
            return PR_TRUE;
        }
    }

    keyHashEQ = PR_FALSE;
    nameHashEQ = PR_FALSE;

    if (!ocsp_CertIsOCSPDesignatedResponder(signerCert)) {
        PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE);
        return PR_FALSE;
    }

    /*
     * The signer is a designated responder.  Its issuer must match
     * the issuer of the cert being checked.
     */
    issuerCert = CERT_FindCertIssuer(signerCert, thisUpdate,
                                     certUsageAnyCA);
    if (issuerCert == NULL) {
        /*
         * We could leave the SEC_ERROR_UNKNOWN_ISSUER error alone,
         * but the following will give slightly more information.
         * Once we have an error stack, things will be much better.
         */
        PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE);
        return PR_FALSE;
    }

    keyHash = CERT_GetSubjectPublicKeyDigest(NULL, issuerCert, hashAlg, NULL);
    nameHash = CERT_GetSubjectNameDigest(NULL, issuerCert, hashAlg, NULL);

    CERT_DestroyCertificate(issuerCert);

    if (keyHash != NULL && nameHash != NULL) {
        keyHashEQ =
            (SECITEM_CompareItem(keyHash,
                                 &certID->issuerKeyHash) == SECEqual);

        nameHashEQ =
            (SECITEM_CompareItem(nameHash,
                                 &certID->issuerNameHash) == SECEqual);
    }

    if (keyHash) {
        SECITEM_FreeItem(keyHash, PR_TRUE);
    }
    if (nameHash) {
        SECITEM_FreeItem(nameHash, PR_TRUE);
    }

    if (keyHashEQ && nameHashEQ) {
        return PR_TRUE;
    }

    PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE);
    return PR_FALSE;
}

/*
 * We need to check that a responder gives us "recent" information.
 * Since a responder can pre-package responses, we need to pick an amount
 * of time that is acceptable to us, and reject any response that is
 * older than that.
 *
 * XXX This *should* be based on some configuration parameter, so that
 * different usages could specify exactly what constitutes "sufficiently
 * recent".  But that is not going to happen right away.  For now, we
 * want something from within the last 24 hours.  This macro defines that
 * number in seconds.
 */
#define OCSP_ALLOWABLE_LAPSE_SECONDS (24L * 60L * 60L)

static PRBool
ocsp_TimeIsRecent(PRTime checkTime)
{
    PRTime now = PR_Now();
    PRTime lapse, tmp;

    LL_I2L(lapse, OCSP_ALLOWABLE_LAPSE_SECONDS);
    LL_I2L(tmp, PR_USEC_PER_SEC);
    LL_MUL(lapse, lapse, tmp); /* allowable lapse in microseconds */

    LL_ADD(checkTime, checkTime, lapse);
    if (LL_CMP(now, >, checkTime))
        return PR_FALSE;

    return PR_TRUE;
}

#define OCSP_SLOP (5L * 60L) /* OCSP responses are allowed to be 5 minutes \
                                in the future by default */

static PRUint32 ocspsloptime = OCSP_SLOP; /* seconds */

/*
 * If an old response contains the revoked certificate status, we want
 * to return SECSuccess so the response will be used.
 */
static SECStatus
ocsp_HandleOldSingleResponse(CERTOCSPSingleResponse *single, PRTime time)
{
    SECStatus rv;
    ocspCertStatus *status = single->certStatus;
    if (status->certStatusType == ocspCertStatus_revoked) {
        rv = ocsp_CertRevokedAfter(status->certStatusInfo.revokedInfo, time);
        if (rv != SECSuccess &&
            PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE) {
            /*
             * Return SECSuccess now.  The subsequent ocsp_CertRevokedAfter
             * call in ocsp_CertHasGoodStatus will cause
             * ocsp_CertHasGoodStatus to fail with
             * SEC_ERROR_REVOKED_CERTIFICATE.
             */
            return SECSuccess;
        }
    }
    PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE);
    return SECFailure;
}

/*
 * Check that this single response is okay.  A return of SECSuccess means:
 *   1. The signer (represented by "signerCert") is authorized to give status
 *	for the cert represented by the individual response in "single".
 *   2. The value of thisUpdate is earlier than now.
 *   3. The value of producedAt is later than or the same as thisUpdate.
 *   4. If nextUpdate is given:
 *	- The value of nextUpdate is later than now.
 *	- The value of producedAt is earlier than nextUpdate.
 *	Else if no nextUpdate:
 *	- The value of thisUpdate is fairly recent.
 *	- The value of producedAt is fairly recent.
 *	However we do not need to perform an explicit check for this last
 *	constraint because it is already guaranteed by checking that
 *	producedAt is later than thisUpdate and thisUpdate is recent.
 * Oh, and any responder is "authorized" to say that a cert is unknown to it.
 *
 * If any of those checks fail, SECFailure is returned and an error is set:
 *	SEC_ERROR_OCSP_FUTURE_RESPONSE
 *	SEC_ERROR_OCSP_OLD_RESPONSE
 *	SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE
 * Other errors are low-level problems (no memory, bad database, etc.).
 */
static SECStatus
ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single,
                          CERTCertDBHandle *handle,
                          CERTCertificate *signerCert,
                          PRTime producedAt)
{
    CERTOCSPCertID *certID = single->certID;
    PRTime now, thisUpdate, nextUpdate, tmstamp, tmp;
    SECStatus rv;

    OCSP_TRACE(("OCSP ocsp_VerifySingleResponse, nextUpdate: %d\n",
                ((single->nextUpdate) != 0)));
    /*
     * If all the responder said was that the given cert was unknown to it,
     * that is a valid response.  Not very interesting to us, of course,
     * but all this function is concerned with is validity of the response,
     * not the status of the cert.
     */
    PORT_Assert(single->certStatus != NULL);
    if (single->certStatus->certStatusType == ocspCertStatus_unknown)
        return SECSuccess;

    /*
     * We need to extract "thisUpdate" for use below and to pass along
     * to AuthorizedResponderForCertID in case it needs it for doing an
     * issuer look-up.
     */
    rv = DER_GeneralizedTimeToTime(&thisUpdate, &single->thisUpdate);
    if (rv != SECSuccess)
        return rv;

    /*
     * First confirm that signerCert is authorized to give this status.
     */
    if (ocsp_AuthorizedResponderForCertID(handle, signerCert, certID,
                                          thisUpdate) != PR_TRUE)
        return SECFailure;

    /*
     * Now check the time stuff, as described above.
     */
    now = PR_Now();
    /* allow slop time for future response */
    LL_UI2L(tmstamp, ocspsloptime); /* get slop time in seconds */
    LL_UI2L(tmp, PR_USEC_PER_SEC);
    LL_MUL(tmp, tmstamp, tmp); /* convert the slop time to PRTime */
    LL_ADD(tmstamp, tmp, now); /* add current time to it */

    if (LL_CMP(thisUpdate, >, tmstamp) || LL_CMP(producedAt, <, thisUpdate)) {
        PORT_SetError(SEC_ERROR_OCSP_FUTURE_RESPONSE);
        return SECFailure;
    }
    if (single->nextUpdate != NULL) {
        rv = DER_GeneralizedTimeToTime(&nextUpdate, single->nextUpdate);
        if (rv != SECSuccess)
            return rv;

        LL_ADD(tmp, tmp, nextUpdate);
        if (LL_CMP(tmp, <, now) || LL_CMP(producedAt, >, nextUpdate))
            return ocsp_HandleOldSingleResponse(single, now);
    } else if (ocsp_TimeIsRecent(thisUpdate) != PR_TRUE) {
        return ocsp_HandleOldSingleResponse(single, now);
    }

    return SECSuccess;
}

/*
 * FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
 *   Get the value of the URI of the OCSP responder for the given cert.
 *   This is found in the (optional) Authority Information Access extension
 *   in the cert.
 * INPUTS:
 *   CERTCertificate *cert
 *     The certificate being examined.
 * RETURN:
 *   char *
 *     A copy of the URI for the OCSP method, if found.  If either the
 *     extension is not present or it does not contain an entry for OCSP,
 *     SEC_ERROR_CERT_BAD_ACCESS_LOCATION will be set and a NULL returned.
 *     Any other error will also result in a NULL being returned.
 *
 *     This result should be freed (via PORT_Free) when no longer in use.
 */
char *
CERT_GetOCSPAuthorityInfoAccessLocation(const CERTCertificate *cert)
{
    CERTGeneralName *locname = NULL;
    SECItem *location = NULL;
    SECItem *encodedAuthInfoAccess = NULL;
    CERTAuthInfoAccess **authInfoAccess = NULL;
    char *locURI = NULL;
    PLArenaPool *arena = NULL;
    SECStatus rv;
    int i;

    /*
     * Allocate this one from the heap because it will get filled in
     * by CERT_FindCertExtension which will also allocate from the heap,
     * and we can free the entire thing on our way out.
     */
    encodedAuthInfoAccess = SECITEM_AllocItem(NULL, NULL, 0);
    if (encodedAuthInfoAccess == NULL)
        goto loser;

    rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS,
                                encodedAuthInfoAccess);
    if (rv == SECFailure) {
        PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
        goto loser;
    }

    /*
     * The rest of the things allocated in the routine will come out of
     * this arena, which is temporary just for us to decode and get at the
     * AIA extension.  The whole thing will be destroyed on our way out,
     * after we have copied the location string (url) itself (if found).
     */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL)
        goto loser;

    authInfoAccess = CERT_DecodeAuthInfoAccessExtension(arena,
                                                        encodedAuthInfoAccess);
    if (authInfoAccess == NULL)
        goto loser;

    for (i = 0; authInfoAccess[i] != NULL; i++) {
        if (SECOID_FindOIDTag(&authInfoAccess[i]->method) == SEC_OID_PKIX_OCSP)
            locname = authInfoAccess[i]->location;
    }

    /*
     * If we found an AIA extension, but it did not include an OCSP method,
     * that should look to our caller as if we did not find the extension
     * at all, because it is only an OCSP method that we care about.
     * So set the same error that would be set if the AIA extension was
     * not there at all.
     */
    if (locname == NULL) {
        PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
        goto loser;
    }

    /*
     * The following is just a pointer back into locname (i.e. not a copy);
     * thus it should not be freed.
     */
    location = CERT_GetGeneralNameByType(locname, certURI, PR_FALSE);
    if (location == NULL) {
        /*
    	 * XXX Appears that CERT_GetGeneralNameByType does not set an
    	 * error if there is no name by that type.  For lack of anything
    	 * better, act as if the extension was not found.  In the future
    	 * this should probably be something more like the extension was
    	 * badly formed.
    	 */
        PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
        goto loser;
    }

    /*
     * That location is really a string, but it has a specified length
     * without a null-terminator.  We need a real string that does have
     * a null-terminator, and we need a copy of it anyway to return to
     * our caller -- so allocate and copy.
     */
    locURI = PORT_Alloc(location->len + 1);
    if (locURI == NULL) {
        goto loser;
    }
    PORT_Memcpy(locURI, location->data, location->len);
    locURI[location->len] = '\0';

loser:
    if (arena != NULL)
        PORT_FreeArena(arena, PR_FALSE);

    if (encodedAuthInfoAccess != NULL)
        SECITEM_FreeItem(encodedAuthInfoAccess, PR_TRUE);

    return locURI;
}

/*
 * Figure out where we should go to find out the status of the given cert
 * via OCSP.  If allowed to use a default responder uri and a default
 * responder is set up, then that is our answer.
 * If not, see if the certificate has an Authority Information Access (AIA)
 * extension for OCSP, and return the value of that.  Otherwise return NULL.
 * We also let our caller know whether or not the responder chosen was
 * a default responder or not through the output variable isDefault;
 * its value has no meaning unless a good (non-null) value is returned
 * for the location.
 *
 * The result needs to be freed (PORT_Free) when no longer in use.
 */
char *
ocsp_GetResponderLocation(CERTCertDBHandle *handle, CERTCertificate *cert,
                          PRBool canUseDefault, PRBool *isDefault)
{
    ocspCheckingContext *ocspcx = NULL;
    char *ocspUrl = NULL;

    if (canUseDefault) {
        ocspcx = ocsp_GetCheckingContext(handle);
    }
    if (ocspcx != NULL && ocspcx->useDefaultResponder) {
        /*
    	 * A default responder wins out, if specified.
    	 * XXX Someday this may be a more complicated determination based
    	 * on the cert's issuer.  (That is, we could have different default
    	 * responders configured for different issuers.)
    	 */
        PORT_Assert(ocspcx->defaultResponderURI != NULL);
        *isDefault = PR_TRUE;
        return (PORT_Strdup(ocspcx->defaultResponderURI));
    }

    /*
     * No default responder set up, so go see if we can find an AIA
     * extension that has a value for OCSP, and get the url from that.
     */
    *isDefault = PR_FALSE;
    ocspUrl = CERT_GetOCSPAuthorityInfoAccessLocation(cert);
    if (!ocspUrl) {
        CERT_StringFromCertFcn altFcn;

        PR_EnterMonitor(OCSP_Global.monitor);
        altFcn = OCSP_Global.alternateOCSPAIAFcn;
        PR_ExitMonitor(OCSP_Global.monitor);
        if (altFcn) {
            ocspUrl = (*altFcn)(cert);
            if (ocspUrl)
                *isDefault = PR_TRUE;
        }
    }
    return ocspUrl;
}

/*
 * Return SECSuccess if the cert was revoked *after* "time",
 * SECFailure otherwise.
 */
static SECStatus
ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, PRTime time)
{
    PRTime revokedTime;
    SECStatus rv;

    rv = DER_GeneralizedTimeToTime(&revokedTime, &revokedInfo->revocationTime);
    if (rv != SECSuccess)
        return rv;

    /*
     * Set the error even if we will return success; someone might care.
     */
    PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);

    if (LL_CMP(revokedTime, >, time))
        return SECSuccess;

    return SECFailure;
}

/*
 * See if the cert represented in the single response had a good status
 * at the specified time.
 */
SECStatus
ocsp_CertHasGoodStatus(ocspCertStatus *status, PRTime time)
{
    SECStatus rv;
    switch (status->certStatusType) {
        case ocspCertStatus_good:
            rv = SECSuccess;
            break;
        case ocspCertStatus_revoked:
            rv = ocsp_CertRevokedAfter(status->certStatusInfo.revokedInfo, time);
            break;
        case ocspCertStatus_unknown:
            PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT);
            rv = SECFailure;
            break;
        case ocspCertStatus_other:
        default:
            PORT_Assert(0);
            PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
            rv = SECFailure;
            break;
    }
    return rv;
}

static SECStatus
ocsp_SingleResponseCertHasGoodStatus(CERTOCSPSingleResponse *single,
                                     PRTime time)
{
    return ocsp_CertHasGoodStatus(single->certStatus, time);
}

/* SECFailure means the arguments were invalid.
 * On SECSuccess, the out parameters contain the OCSP status.
 * rvOcsp contains the overall result of the OCSP operation.
 * Depending on input parameter ignoreGlobalOcspFailureSetting,
 * a soft failure might be converted into *rvOcsp=SECSuccess.
 * If the cached attempt to obtain OCSP information had resulted
 * in a failure, missingResponseError shows the error code of
 * that failure.
 * cacheFreshness is ocspMissing if no entry was found,
 *                   ocspFresh if a fresh entry was found, or
 *                   ocspStale if a stale entry was found.
 */
SECStatus
ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
                                 PRTime time,
                                 PRBool ignoreGlobalOcspFailureSetting,
                                 SECStatus *rvOcsp,
                                 SECErrorCodes *missingResponseError,
                                 OCSPFreshness *cacheFreshness)
{
    OCSPCacheItem *cacheItem = NULL;

    if (!certID || !missingResponseError || !rvOcsp || !cacheFreshness) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    *rvOcsp = SECFailure;
    *missingResponseError = 0;
    *cacheFreshness = ocspMissing;

    PR_EnterMonitor(OCSP_Global.monitor);
    cacheItem = ocsp_FindCacheEntry(&OCSP_Global.cache, certID);
    if (cacheItem) {
        *cacheFreshness = ocsp_IsCacheItemFresh(cacheItem) ? ocspFresh
                                                           : ocspStale;
        /* having an arena means, we have a cached certStatus */
        if (cacheItem->certStatusArena) {
            *rvOcsp = ocsp_CertHasGoodStatus(&cacheItem->certStatus, time);
            if (*rvOcsp != SECSuccess) {
                *missingResponseError = PORT_GetError();
            }
        } else {
            /*
             * No status cached, the previous attempt failed.
             * If OCSP is required, we never decide based on a failed attempt
             * However, if OCSP is optional, a recent OCSP failure is
             * an allowed good state.
             */
            if (*cacheFreshness == ocspFresh &&
                !ignoreGlobalOcspFailureSetting &&
                OCSP_Global.ocspFailureMode ==
                    ocspMode_FailureIsNotAVerificationFailure) {
                *rvOcsp = SECSuccess;
            }
            *missingResponseError = cacheItem->missingResponseError;
        }
    }
    PR_ExitMonitor(OCSP_Global.monitor);
    return SECSuccess;
}

PRBool
ocsp_FetchingFailureIsVerificationFailure(void)
{
    PRBool isFailure;

    PR_EnterMonitor(OCSP_Global.monitor);
    isFailure =
        OCSP_Global.ocspFailureMode == ocspMode_FailureIsVerificationFailure;
    PR_ExitMonitor(OCSP_Global.monitor);
    return isFailure;
}

/*
 * FUNCTION: CERT_CheckOCSPStatus
 *   Checks the status of a certificate via OCSP.  Will only check status for
 *   a certificate that has an AIA (Authority Information Access) extension
 *   for OCSP *or* when a "default responder" is specified and enabled.
 *   (If no AIA extension for OCSP and no default responder in place, the
 *   cert is considered to have a good status and SECSuccess is returned.)
 * INPUTS:
 *   CERTCertDBHandle *handle
 *     certificate DB of the cert that is being checked
 *   CERTCertificate *cert
 *     the certificate being checked
 *   XXX in the long term also need a boolean parameter that specifies
 *	whether to check the cert chain, as well; for now we check only
 *	the leaf (the specified certificate)
 *   PRTime time
 *     time for which status is to be determined
 *   void *pwArg
 *     argument for password prompting, if needed
 * RETURN:
 *   Returns SECSuccess if an approved OCSP responder "knows" the cert
 *   *and* returns a non-revoked status for it; SECFailure otherwise,
 *   with an error set describing the reason:
 *
 *	SEC_ERROR_OCSP_BAD_HTTP_RESPONSE
 *	SEC_ERROR_OCSP_FUTURE_RESPONSE
 *	SEC_ERROR_OCSP_MALFORMED_REQUEST
 *	SEC_ERROR_OCSP_MALFORMED_RESPONSE
 *	SEC_ERROR_OCSP_OLD_RESPONSE
 *	SEC_ERROR_OCSP_REQUEST_NEEDS_SIG
 *	SEC_ERROR_OCSP_SERVER_ERROR
 *	SEC_ERROR_OCSP_TRY_SERVER_LATER
 *	SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST
 *	SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE
 *	SEC_ERROR_OCSP_UNKNOWN_CERT
 *	SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS
 *	SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE
 *
 *	SEC_ERROR_BAD_SIGNATURE
 *	SEC_ERROR_CERT_BAD_ACCESS_LOCATION
 *	SEC_ERROR_INVALID_TIME
 *	SEC_ERROR_REVOKED_CERTIFICATE
 *	SEC_ERROR_UNKNOWN_ISSUER
 *	SEC_ERROR_UNKNOWN_SIGNER
 *
 *   Other errors are any of the many possible failures in cert verification
 *   (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when
 *   verifying the signer's cert, or low-level problems (error allocating
 *   memory, error performing ASN.1 decoding, etc.).
 */
SECStatus
CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
                     PRTime time, void *pwArg)
{
    CERTOCSPCertID *certID;
    PRBool certIDWasConsumed = PR_FALSE;
    SECStatus rv;
    SECStatus rvOcsp;
    SECErrorCodes cachedErrorCode;
    OCSPFreshness cachedResponseFreshness;

    OCSP_TRACE_CERT(cert);
    OCSP_TRACE_TIME("## requested validity time:", time);

    certID = CERT_CreateOCSPCertID(cert, time);
    if (!certID)
        return SECFailure;
    rv = ocsp_GetCachedOCSPResponseStatus(
        certID, time, PR_FALSE, /* ignoreGlobalOcspFailureSetting */
        &rvOcsp, &cachedErrorCode, &cachedResponseFreshness);
    if (rv != SECSuccess) {
        CERT_DestroyOCSPCertID(certID);
        return SECFailure;
    }
    if (cachedResponseFreshness == ocspFresh) {
        CERT_DestroyOCSPCertID(certID);
        if (rvOcsp != SECSuccess) {
            PORT_SetError(cachedErrorCode);
        }
        return rvOcsp;
    }

    rv = ocsp_GetOCSPStatusFromNetwork(handle, certID, cert, time, pwArg,
                                       &certIDWasConsumed,
                                       &rvOcsp);
    if (rv != SECSuccess) {
        PRErrorCode err = PORT_GetError();
        if (ocsp_FetchingFailureIsVerificationFailure()) {
            PORT_SetError(err);
            rvOcsp = SECFailure;
        } else if (cachedResponseFreshness == ocspStale &&
                   (cachedErrorCode == SEC_ERROR_OCSP_UNKNOWN_CERT ||
                    cachedErrorCode == SEC_ERROR_REVOKED_CERTIFICATE)) {
            /* If we couldn't get a response for a certificate that the OCSP
             * responder previously told us was bad, then assume it is still
             * bad until we hear otherwise, as it is very unlikely that the
             * certificate status has changed from "revoked" to "good" and it
             * is also unlikely that the certificate status has changed from
             * "unknown" to "good", except for some buggy OCSP responders.
             */
            PORT_SetError(cachedErrorCode);
            rvOcsp = SECFailure;
        } else {
            rvOcsp = SECSuccess;
        }
    }
    if (!certIDWasConsumed) {
        CERT_DestroyOCSPCertID(certID);
    }
    return rvOcsp;
}

/*
 * FUNCTION: CERT_CacheOCSPResponseFromSideChannel
 *   First, this function checks the OCSP cache to see if a good response
 *   for the given certificate already exists. If it does, then the function
 *   returns successfully.
 *
 *   If not, then it validates that the given OCSP response is a valid,
 *   good response for the given certificate and inserts it into the
 *   cache.
 *
 *   This function is intended for use when OCSP responses are provided via a
 *   side-channel, i.e. TLS OCSP stapling (a.k.a. the status_request extension).
 *
 * INPUTS:
 *   CERTCertDBHandle *handle
 *     certificate DB of the cert that is being checked
 *   CERTCertificate *cert
 *     the certificate being checked
 *   PRTime time
 *     time for which status is to be determined
 *   SECItem *encodedResponse
 *     the DER encoded bytes of the OCSP response
 *   void *pwArg
 *     argument for password prompting, if needed
 * RETURN:
 *   SECSuccess if the cert was found in the cache, or if the OCSP response was
 *   found to be valid and inserted into the cache. SECFailure otherwise.
 */
SECStatus
CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
                                      CERTCertificate *cert,
                                      PRTime time,
                                      const SECItem *encodedResponse,
                                      void *pwArg)
{
    CERTOCSPCertID *certID = NULL;
    PRBool certIDWasConsumed = PR_FALSE;
    SECStatus rv = SECFailure;
    SECStatus rvOcsp = SECFailure;
    SECErrorCodes dummy_error_code; /* we ignore this */
    CERTOCSPResponse *decodedResponse = NULL;
    CERTOCSPSingleResponse *singleResponse = NULL;
    OCSPFreshness freshness;

    /* The OCSP cache can be in three states regarding this certificate:
     *    + Good (cached, timely, 'good' response, or revoked in the future)
     *    + Revoked (cached, timely, but doesn't fit in the last category)
     *    + Miss (no knowledge)
     *
     * Likewise, the side-channel information can be
     *    + Good (timely, 'good' response, or revoked in the future)
     *    + Revoked (timely, but doesn't fit in the last category)
     *    + Invalid (bad syntax, bad signature, not timely etc)
     *
     * The common case is that the cache result is Good and so is the
     * side-channel information. We want to save processing time in this case
     * so we say that any time we see a Good result from the cache we return
     * early.
     *
     *                       Cache result
     *      | Good             Revoked               Miss
     *   ---+--------------------------------------------
     *    G |  noop           Cache more           Cache it
     * S    |                 recent result
     * i    |
     * d    |
     * e    |
     *    R |  noop           Cache more           Cache it
     * C    |                 recent result
     * h    |
     * a    |
     * n    |
     * n  I |  noop           Noop                  Noop
     * e    |
     * l    |
     *
     * When we fetch from the network we might choose to cache a negative
     * result when the response is invalid. This saves us hammering, uselessly,
     * at a broken responder. However, side channels are commonly attacker
     * controlled and so we must not cache a negative result for an Invalid
     * side channel.
     */

    if (!cert || !encodedResponse) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    certID = CERT_CreateOCSPCertID(cert, time);
    if (!certID)
        return SECFailure;

    /* We pass PR_TRUE for ignoreGlobalOcspFailureSetting so that a cached
     * error entry is not interpreted as being a 'Good' entry here.
     */
    rv = ocsp_GetCachedOCSPResponseStatus(
        certID, time, PR_TRUE, /* ignoreGlobalOcspFailureSetting */
        &rvOcsp, &dummy_error_code, &freshness);
    if (rv == SECSuccess && rvOcsp == SECSuccess && freshness == ocspFresh) {
        /* The cached value is good. We don't want to waste time validating
         * this OCSP response. This is the first column in the table above. */
        CERT_DestroyOCSPCertID(certID);
        return rv;
    }

    /* The logic for caching the more recent response is handled in
     * ocsp_CacheSingleResponse. */

    rv = ocsp_GetDecodedVerifiedSingleResponseForID(handle, certID, cert,
                                                    time, pwArg,
                                                    encodedResponse,
                                                    &decodedResponse,
                                                    &singleResponse);
    if (rv == SECSuccess) {
        rvOcsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time);
        /* Cache any valid singleResponse, regardless of status. */
        ocsp_CacheSingleResponse(certID, singleResponse, &certIDWasConsumed);
    }
    if (decodedResponse) {
        CERT_DestroyOCSPResponse(decodedResponse);
    }
    if (!certIDWasConsumed) {
        CERT_DestroyOCSPCertID(certID);
    }
    return rv == SECSuccess ? rvOcsp : rv;
}

/*
 * Status in *certIDWasConsumed will always be correct, regardless of
 * return value.
 */
static SECStatus
ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
                              CERTOCSPCertID *certID,
                              CERTCertificate *cert,
                              PRTime time,
                              void *pwArg,
                              PRBool *certIDWasConsumed,
                              SECStatus *rv_ocsp)
{
    char *location = NULL;
    PRBool locationIsDefault;
    SECItem *encodedResponse = NULL;
    CERTOCSPRequest *request = NULL;
    SECStatus rv = SECFailure;

    CERTOCSPResponse *decodedResponse = NULL;
    CERTOCSPSingleResponse *singleResponse = NULL;
    enum { stageGET,
           stagePOST } currentStage;
    PRBool retry = PR_FALSE;

    if (!certIDWasConsumed || !rv_ocsp) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    *certIDWasConsumed = PR_FALSE;
    *rv_ocsp = SECFailure;

    if (!OCSP_Global.monitor) {
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
        return SECFailure;
    }
    PR_EnterMonitor(OCSP_Global.monitor);
    if (OCSP_Global.forcePost) {
        currentStage = stagePOST;
    } else {
        currentStage = stageGET;
    }
    PR_ExitMonitor(OCSP_Global.monitor);

    /*
     * The first thing we need to do is find the location of the responder.
     * This will be the value of the default responder (if enabled), else
     * it will come out of the AIA extension in the cert (if present).
     * If we have no such location, then this cert does not "deserve" to
     * be checked -- that is, we consider it a success and just return.
     * The way we tell that is by looking at the error number to see if
     * the problem was no AIA extension was found; any other error was
     * a true failure that we unfortunately have to treat as an overall
     * failure here.
     */
    location = ocsp_GetResponderLocation(handle, cert, PR_TRUE,
                                         &locationIsDefault);
    if (location == NULL) {
        int err = PORT_GetError();
        if (err == SEC_ERROR_EXTENSION_NOT_FOUND ||
            err == SEC_ERROR_CERT_BAD_ACCESS_LOCATION) {
            PORT_SetError(0);
            *rv_ocsp = SECSuccess;
            return SECSuccess;
        }
        return SECFailure;
    }

    /*
     * XXX In the fullness of time, we will want/need to handle a
     * certificate chain.  This will be done either when a new parameter
     * tells us to, or some configuration variable tells us to.  In any
     * case, handling it is complicated because we may need to send as
     * many requests (and receive as many responses) as we have certs
     * in the chain.  If we are going to talk to a default responder,
     * and we only support one default responder, we can put all of the
     * certs together into one request.  Otherwise, we must break them up
     * into multiple requests.  (Even if all of the requests will go to
     * the same location, the signature on each response will be different,
     * because each issuer is different.  Carefully read the OCSP spec
     * if you do not understand this.)
     */

    /*
     * XXX If/when signing of requests is supported, that second NULL
     * should be changed to be the signer certificate.  Not sure if that
     * should be passed into this function or retrieved via some operation
     * on the handle/context.
     */

    do {
        const char *method;
        PRBool validResponseWithAccurateInfo = PR_FALSE;
        retry = PR_FALSE;
        *rv_ocsp = SECFailure;

        if (currentStage == stageGET) {
            method = "GET";
        } else {
            PORT_Assert(currentStage == stagePOST);
            method = "POST";
        }

        encodedResponse =
            ocsp_GetEncodedOCSPResponseForSingleCert(NULL, certID, cert,
                                                     location, method,
                                                     time, locationIsDefault,
                                                     pwArg, &request);

        if (encodedResponse) {
            rv = ocsp_GetDecodedVerifiedSingleResponseForID(handle, certID, cert,
                                                            time, pwArg,
                                                            encodedResponse,
                                                            &decodedResponse,
                                                            &singleResponse);
            if (rv == SECSuccess) {
                switch (singleResponse->certStatus->certStatusType) {
                    case ocspCertStatus_good:
                    case ocspCertStatus_revoked:
                        validResponseWithAccurateInfo = PR_TRUE;
                        break;
                    default:
                        break;
                }
                *rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time);
            }
        }

        if (currentStage == stageGET) {
            /* only accept GET response if good or revoked */
            if (validResponseWithAccurateInfo) {
                ocsp_CacheSingleResponse(certID, singleResponse,
                                         certIDWasConsumed);
            } else {
                retry = PR_TRUE;
                currentStage = stagePOST;
            }
        } else {
            /* cache the POST respone, regardless of status */
            if (!singleResponse) {
                cert_RememberOCSPProcessingFailure(certID, certIDWasConsumed);
            } else {
                ocsp_CacheSingleResponse(certID, singleResponse,
                                         certIDWasConsumed);
            }
        }

        if (encodedResponse) {
            SECITEM_FreeItem(encodedResponse, PR_TRUE);
            encodedResponse = NULL;
        }
        if (request) {
            CERT_DestroyOCSPRequest(request);
            request = NULL;
        }
        if (decodedResponse) {
            CERT_DestroyOCSPResponse(decodedResponse);
            decodedResponse = NULL;
        }
        singleResponse = NULL;

    } while (retry);

    PORT_Free(location);
    return rv;
}

/*
 * FUNCTION: ocsp_GetDecodedVerifiedSingleResponseForID
 *   This function decodes an OCSP response and checks for a valid response
 *   concerning the given certificate.
 *
 *   Note: a 'valid' response is one that parses successfully, is not an OCSP
 *   exception (see RFC 2560 Section 2.3), is correctly signed and is current.
 *   A 'good' response is a valid response that attests that the certificate
 *   is not currently revoked (see RFC 2560 Section 2.2).
 *
 * INPUTS:
 *   CERTCertDBHandle *handle
 *     certificate DB of the cert that is being checked
 *   CERTOCSPCertID *certID
 *     the cert ID corresponding to |cert|
 *   CERTCertificate *cert
 *     the certificate being checked
 *   PRTime time
 *     time for which status is to be determined
 *   void *pwArg
 *     the opaque argument to the password prompting function.
 *   SECItem *encodedResponse
 *     the DER encoded bytes of the OCSP response
 *   CERTOCSPResponse **pDecodedResponse
 *     (output) The caller must ALWAYS check for this output parameter,
 *     and if it's non-null, must destroy it using CERT_DestroyOCSPResponse.
 *   CERTOCSPSingleResponse **pSingle
 *     (output) on success, this points to the single response that corresponds
 *     to the certID parameter. Points to the inside of pDecodedResponse.
 *     It isn't a copy, don't free it.
 * RETURN:
 *   SECSuccess iff the response is valid.
 */
static SECStatus
ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle,
                                           CERTOCSPCertID *certID,
                                           CERTCertificate *cert,
                                           PRTime time,
                                           void *pwArg,
                                           const SECItem *encodedResponse,
                                           CERTOCSPResponse **pDecodedResponse,
                                           CERTOCSPSingleResponse **pSingle)
{
    CERTCertificate *signerCert = NULL;
    CERTCertificate *issuerCert = NULL;
    SECStatus rv = SECFailure;

    if (!pSingle || !pDecodedResponse) {
        return SECFailure;
    }
    *pSingle = NULL;
    *pDecodedResponse = CERT_DecodeOCSPResponse(encodedResponse);
    if (!*pDecodedResponse) {
        return SECFailure;
    }

    /*
     * Okay, we at least have a response that *looks* like a response!
     * Now see if the overall response status value is good or not.
     * If not, we set an error and give up.  (It means that either the
     * server had a problem, or it didn't like something about our
     * request.  Either way there is nothing to do but give up.)
     * Otherwise, we continue to find the actual per-cert status
     * in the response.
     */
    if (CERT_GetOCSPResponseStatus(*pDecodedResponse) != SECSuccess) {
        goto loser;
    }

    /*
     * If we've made it this far, we expect a response with a good signature.
     * So, check for that.
     */
    issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);
    rv = CERT_VerifyOCSPResponseSignature(*pDecodedResponse, handle, pwArg,
                                          &signerCert, issuerCert);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_Assert(signerCert != NULL); /* internal consistency check */
    /* XXX probably should set error, return failure if signerCert is null */

    /*
     * Again, we are only doing one request for one cert.
     * XXX When we handle cert chains, the following code will obviously
     * have to be modified, in coordation with the code above that will
     * have to determine how to make multiple requests, etc.
     */
    rv = ocsp_GetVerifiedSingleResponseForCertID(handle, *pDecodedResponse, certID,
                                                 signerCert, time, pSingle);
loser:
    if (issuerCert != NULL)
        CERT_DestroyCertificate(issuerCert);
    if (signerCert != NULL)
        CERT_DestroyCertificate(signerCert);
    return rv;
}

/*
 * FUNCTION: ocsp_CacheSingleResponse
 *   This function requires that the caller has checked that the response
 *   is valid and verified.
 *   The (positive or negative) valid response will be used to update the cache.
 * INPUTS:
 *   CERTOCSPCertID *certID
 *     the cert ID corresponding to |cert|
 *   PRBool *certIDWasConsumed
 *     (output) on return, this is true iff |certID| was consumed by this
 *     function.
 */
void
ocsp_CacheSingleResponse(CERTOCSPCertID *certID,
                         CERTOCSPSingleResponse *single,
                         PRBool *certIDWasConsumed)
{
    if (single != NULL) {
        PR_EnterMonitor(OCSP_Global.monitor);
        if (OCSP_Global.maxCacheEntries >= 0) {
            ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, single,
                                          certIDWasConsumed);
            /* ignore cache update failures */
        }
        PR_ExitMonitor(OCSP_Global.monitor);
    }
}

SECStatus
ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
                                        CERTOCSPResponse *response,
                                        CERTOCSPCertID *certID,
                                        CERTCertificate *signerCert,
                                        PRTime time,
                                        CERTOCSPSingleResponse
                                            **pSingleResponse)
{
    SECStatus rv;
    ocspResponseData *responseData;
    PRTime producedAt;
    CERTOCSPSingleResponse *single;

    /*
     * The ResponseData part is the real guts of the response.
     */
    responseData = ocsp_GetResponseData(response, NULL);
    if (responseData == NULL) {
        rv = SECFailure;
        goto loser;
    }

    /*
     * There is one producedAt time for the entire response (and a separate
     * thisUpdate time for each individual single response).  We need to
     * compare them, so get the overall time to pass into the check of each
     * single response.
     */
    rv = DER_GeneralizedTimeToTime(&producedAt, &responseData->producedAt);
    if (rv != SECSuccess)
        goto loser;

    single = ocsp_GetSingleResponseForCertID(responseData->responses,
                                             handle, certID);
    if (single == NULL) {
        rv = SECFailure;
        goto loser;
    }

    rv = ocsp_VerifySingleResponse(single, handle, signerCert, producedAt);
    if (rv != SECSuccess)
        goto loser;
    *pSingleResponse = single;

loser:
    return rv;
}

SECStatus
CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
                            CERTOCSPResponse *response,
                            CERTOCSPCertID *certID,
                            CERTCertificate *signerCert,
                            PRTime time)
{
    /*
     * We do not update the cache, because:
     *
     * CERT_GetOCSPStatusForCertID is an old exported API that was introduced
     * before the OCSP cache got implemented.
     *
     * The implementation of helper function cert_ProcessOCSPResponse
     * requires the ability to transfer ownership of the the given certID to
     * the cache. The external API doesn't allow us to prevent the caller from
     * destroying the certID. We don't have the original certificate available,
     * therefore we are unable to produce another certID object (that could
     * be stored in the cache).
     *
     * Should we ever implement code to produce a deep copy of certID,
     * then this could be changed to allow updating the cache.
     * The duplication would have to be done in
     * cert_ProcessOCSPResponse, if the out parameter to indicate
     * a transfer of ownership is NULL.
     */
    return cert_ProcessOCSPResponse(handle, response, certID,
                                    signerCert, time,
                                    NULL, NULL);
}

/*
 * The first 5 parameters match the definition of CERT_GetOCSPStatusForCertID.
 */
SECStatus
cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
                         CERTOCSPResponse *response,
                         CERTOCSPCertID *certID,
                         CERTCertificate *signerCert,
                         PRTime time,
                         PRBool *certIDWasConsumed,
                         SECStatus *cacheUpdateStatus)
{
    SECStatus rv;
    SECStatus rv_cache = SECSuccess;
    CERTOCSPSingleResponse *single = NULL;

    rv = ocsp_GetVerifiedSingleResponseForCertID(handle, response, certID,
                                                 signerCert, time, &single);
    if (rv == SECSuccess) {
        /*
         * Check whether the status says revoked, and if so
         * how that compares to the time value passed into this routine.
         */
        rv = ocsp_SingleResponseCertHasGoodStatus(single, time);
    }

    if (certIDWasConsumed) {
        /*
         * We don't have copy-of-certid implemented. In order to update
         * the cache, the caller must supply an out variable
         * certIDWasConsumed, allowing us to return ownership status.
         */

        PR_EnterMonitor(OCSP_Global.monitor);
        if (OCSP_Global.maxCacheEntries >= 0) {
            /* single == NULL means: remember response failure */
            rv_cache =
                ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID,
                                              single, certIDWasConsumed);
        }
        PR_ExitMonitor(OCSP_Global.monitor);
        if (cacheUpdateStatus) {
            *cacheUpdateStatus = rv_cache;
        }
    }

    return rv;
}

SECStatus
cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
                                   PRBool *certIDWasConsumed)
{
    SECStatus rv = SECSuccess;
    PR_EnterMonitor(OCSP_Global.monitor);
    if (OCSP_Global.maxCacheEntries >= 0) {
        rv = ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, NULL,
                                           certIDWasConsumed);
    }
    PR_ExitMonitor(OCSP_Global.monitor);
    return rv;
}

/*
 * Disable status checking and destroy related structures/data.
 */
static SECStatus
ocsp_DestroyStatusChecking(CERTStatusConfig *statusConfig)
{
    ocspCheckingContext *statusContext;

    /*
     * Disable OCSP checking
     */
    statusConfig->statusChecker = NULL;

    statusContext = statusConfig->statusContext;
    PORT_Assert(statusContext != NULL);
    if (statusContext == NULL)
        return SECFailure;

    if (statusContext->defaultResponderURI != NULL)
        PORT_Free(statusContext->defaultResponderURI);
    if (statusContext->defaultResponderNickname != NULL)
        PORT_Free(statusContext->defaultResponderNickname);

    PORT_Free(statusContext);
    statusConfig->statusContext = NULL;

    PORT_Free(statusConfig);

    return SECSuccess;
}

/*
 * FUNCTION: CERT_DisableOCSPChecking
 *   Turns off OCSP checking for the given certificate database.
 *   This routine disables OCSP checking.  Though it will return
 *   SECFailure if OCSP checking is not enabled, it is "safe" to
 *   call it that way and just ignore the return value, if it is
 *   easier to just call it than to "remember" whether it is enabled.
 * INPUTS:
 *   CERTCertDBHandle *handle
 *     Certificate database for which OCSP checking will be disabled.
 * RETURN:
 *   Returns SECFailure if an error occurred (usually means that OCSP
 *   checking was not enabled or status contexts were not initialized --
 *   error set will be SEC_ERROR_OCSP_NOT_ENABLED); SECSuccess otherwise.
 */
SECStatus
CERT_DisableOCSPChecking(CERTCertDBHandle *handle)
{
    CERTStatusConfig *statusConfig;
    ocspCheckingContext *statusContext;

    if (handle == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    statusConfig = CERT_GetStatusConfig(handle);
    statusContext = ocsp_GetCheckingContext(handle);
    if (statusContext == NULL)
        return SECFailure;

    if (statusConfig->statusChecker != CERT_CheckOCSPStatus) {
        /*
    	 * Status configuration is present, but either not currently
    	 * enabled or not for OCSP.
    	 */
        PORT_SetError(SEC_ERROR_OCSP_NOT_ENABLED);
        return SECFailure;
    }

    /* cache no longer necessary */
    CERT_ClearOCSPCache();

    /*
     * This is how we disable status checking.  Everything else remains
     * in place in case we are enabled again.
     */
    statusConfig->statusChecker = NULL;

    return SECSuccess;
}

/*
 * Allocate and initialize the informational structures for status checking.
 * This is done when some configuration of OCSP is being done or when OCSP
 * checking is being turned on, whichever comes first.
 */
static SECStatus
ocsp_InitStatusChecking(CERTCertDBHandle *handle)
{
    CERTStatusConfig *statusConfig = NULL;
    ocspCheckingContext *statusContext = NULL;

    PORT_Assert(CERT_GetStatusConfig(handle) == NULL);
    if (CERT_GetStatusConfig(handle) != NULL) {
        /* XXX or call statusConfig->statusDestroy and continue? */
        return SECFailure;
    }

    statusConfig = PORT_ZNew(CERTStatusConfig);
    if (statusConfig == NULL)
        goto loser;

    statusContext = PORT_ZNew(ocspCheckingContext);
    if (statusContext == NULL)
        goto loser;

    statusConfig->statusDestroy = ocsp_DestroyStatusChecking;
    statusConfig->statusContext = statusContext;

    CERT_SetStatusConfig(handle, statusConfig);

    return SECSuccess;

loser:
    if (statusConfig != NULL)
        PORT_Free(statusConfig);
    return SECFailure;
}

/*
 * FUNCTION: CERT_EnableOCSPChecking
 *   Turns on OCSP checking for the given certificate database.
 * INPUTS:
 *   CERTCertDBHandle *handle
 *     Certificate database for which OCSP checking will be enabled.
 * RETURN:
 *   Returns SECFailure if an error occurred (likely only problem
 *   allocating memory); SECSuccess otherwise.
 */
SECStatus
CERT_EnableOCSPChecking(CERTCertDBHandle *handle)
{
    CERTStatusConfig *statusConfig;

    SECStatus rv;

    if (handle == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    statusConfig = CERT_GetStatusConfig(handle);
    if (statusConfig == NULL) {
        rv = ocsp_InitStatusChecking(handle);
        if (rv != SECSuccess)
            return rv;

        /* Get newly established value */
        statusConfig = CERT_GetStatusConfig(handle);
        PORT_Assert(statusConfig != NULL);
    }

    /*
     * Setting the checker function is what really enables the checking
     * when each cert verification is done.
     */
    statusConfig->statusChecker = CERT_CheckOCSPStatus;

    return SECSuccess;
}

/*
 * FUNCTION: CERT_SetOCSPDefaultResponder
 *   Specify the location and cert of the default responder.
 *   If OCSP checking is already enabled *and* use of a default responder
 *   is also already enabled, all OCSP checking from now on will go directly
 *   to the specified responder.  If OCSP checking is not enabled, or if
 *   it is but use of a default responder is not enabled, the information
 *   will be recorded and take effect whenever both are enabled.
 * INPUTS:
 *   CERTCertDBHandle *handle
 *     Cert database on which OCSP checking should use the default responder.
 *   char *url
 *     The location of the default responder (e.g. "http://foo.com:80/ocsp")
 *     Note that the location will not be tested until the first attempt
 *     to send a request there.
 *   char *name
 *     The nickname of the cert to trust (expected) to sign the OCSP responses.
 *     If the corresponding cert cannot be found, SECFailure is returned.
 * RETURN:
 *   Returns SECFailure if an error occurred; SECSuccess otherwise.
 *   The most likely error is that the cert for "name" could not be found
 *   (probably SEC_ERROR_UNKNOWN_CERT).  Other errors are low-level (no memory,
 *   bad database, etc.).
 */
SECStatus
CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
                             const char *url, const char *name)
{
    CERTCertificate *cert;
    ocspCheckingContext *statusContext;
    char *url_copy = NULL;
    char *name_copy = NULL;
    SECStatus rv;

    if (handle == NULL || url == NULL || name == NULL) {
        /*
    	 * XXX When interface is exported, probably want better errors;
    	 * perhaps different one for each parameter.
    	 */
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /*
     * Find the certificate for the specified nickname.  Do this first
     * because it seems the most likely to fail.
     *
     * XXX Shouldn't need that cast if the FindCertByNickname interface
     * used const to convey that it does not modify the name.  Maybe someday.
     */
    cert = CERT_FindCertByNickname(handle, (char *)name);
    if (cert == NULL) {
        /*
         * look for the cert on an external token.
         */
        cert = PK11_FindCertFromNickname((char *)name, NULL);
    }
    if (cert == NULL)
        return SECFailure;

    /*
     * Make a copy of the url and nickname.
     */
    url_copy = PORT_Strdup(url);
    name_copy = PORT_Strdup(name);
    if (url_copy == NULL || name_copy == NULL) {
        rv = SECFailure;
        goto loser;
    }

    statusContext = ocsp_GetCheckingContext(handle);

    /*
     * Allocate and init the context if it doesn't already exist.
     */
    if (statusContext == NULL) {
        rv = ocsp_InitStatusChecking(handle);
        if (rv != SECSuccess)
            goto loser;

        statusContext = ocsp_GetCheckingContext(handle);
        PORT_Assert(statusContext != NULL); /* extreme paranoia */
    }

    /*
     * Note -- we do not touch the status context until after all of
     * the steps which could cause errors.  If something goes wrong,
     * we want to leave things as they were.
     */

    /*
     * Get rid of old url and name if there.
     */
    if (statusContext->defaultResponderNickname != NULL)
        PORT_Free(statusContext->defaultResponderNickname);
    if (statusContext->defaultResponderURI != NULL)
        PORT_Free(statusContext->defaultResponderURI);

    /*
     * And replace them with the new ones.
     */
    statusContext->defaultResponderURI = url_copy;
    statusContext->defaultResponderNickname = name_copy;

    /*
     * If there was already a cert in place, get rid of it and replace it.
     * Otherwise, we are not currently enabled, so we don't want to save it;
     * it will get re-found and set whenever use of a default responder is
     * enabled.
     */
    if (statusContext->defaultResponderCert != NULL) {
        CERT_DestroyCertificate(statusContext->defaultResponderCert);
        statusContext->defaultResponderCert = cert;
        /*OCSP enabled, switching responder: clear cache*/
        CERT_ClearOCSPCache();
    } else {
        PORT_Assert(statusContext->useDefaultResponder == PR_FALSE);
        CERT_DestroyCertificate(cert);
        /*OCSP currently not enabled, no need to clear cache*/
    }

    return SECSuccess;

loser:
    CERT_DestroyCertificate(cert);
    if (url_copy != NULL)
        PORT_Free(url_copy);
    if (name_copy != NULL)
        PORT_Free(name_copy);
    return rv;
}

/*
 * FUNCTION: CERT_EnableOCSPDefaultResponder
 *   Turns on use of a default responder when OCSP checking.
 *   If OCSP checking is already enabled, this will make subsequent checks
 *   go directly to the default responder.  (The location of the responder
 *   and the nickname of the responder cert must already be specified.)
 *   If OCSP checking is not enabled, this will be recorded and take effect
 *   whenever it is enabled.
 * INPUTS:
 *   CERTCertDBHandle *handle
 *     Cert database on which OCSP checking should use the default responder.
 * RETURN:
 *   Returns SECFailure if an error occurred; SECSuccess otherwise.
 *   No errors are especially likely unless the caller did not previously
 *   perform a successful call to SetOCSPDefaultResponder (in which case
 *   the error set will be SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER).
 */
SECStatus
CERT_EnableOCSPDefaultResponder(CERTCertDBHandle *handle)
{
    ocspCheckingContext *statusContext;
    CERTCertificate *cert;
    SECStatus rv;
    SECCertificateUsage usage;

    if (handle == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    statusContext = ocsp_GetCheckingContext(handle);

    if (statusContext == NULL) {
        /*
    	 * Strictly speaking, the error already set is "correct",
    	 * but cover over it with one more helpful in this context.
    	 */
        PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
        return SECFailure;
    }

    if (statusContext->defaultResponderURI == NULL) {
        PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
        return SECFailure;
    }

    if (statusContext->defaultResponderNickname == NULL) {
        PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
        return SECFailure;
    }

    /*
     * Find the cert for the nickname.
     */
    cert = CERT_FindCertByNickname(handle,
                                   statusContext->defaultResponderNickname);
    if (cert == NULL) {
        cert = PK11_FindCertFromNickname(statusContext->defaultResponderNickname,
                                         NULL);
    }
    /*
     * We should never have trouble finding the cert, because its
     * existence should have been proven by SetOCSPDefaultResponder.
     */
    PORT_Assert(cert != NULL);
    if (cert == NULL)
        return SECFailure;

    /*
     * Supplied cert should at least have  a signing capability in order for us
     * to use it as a trusted responder cert. Ability to sign is guaranteed  if
     * cert is validated to have any set of the usages below.
     */
    rv = CERT_VerifyCertificateNow(handle, cert, PR_TRUE,
                                   certificateUsageCheckAllUsages,
                                   NULL, &usage);
    if (rv != SECSuccess || (usage & (certificateUsageSSLClient | certificateUsageSSLServer | certificateUsageSSLServerWithStepUp | certificateUsageEmailSigner | certificateUsageObjectSigner | certificateUsageStatusResponder | certificateUsageSSLCA)) == 0) {
        PORT_SetError(SEC_ERROR_OCSP_RESPONDER_CERT_INVALID);
        return SECFailure;
    }

    /*
     * And hang onto it.
     */
    statusContext->defaultResponderCert = cert;

    /* we don't allow a mix of cache entries from different responders */
    CERT_ClearOCSPCache();

    /*
     * Finally, record the fact that we now have a default responder enabled.
     */
    statusContext->useDefaultResponder = PR_TRUE;
    return SECSuccess;
}

/*
 * FUNCTION: CERT_DisableOCSPDefaultResponder
 *   Turns off use of a default responder when OCSP checking.
 *   (Does nothing if use of a default responder is not enabled.)
 * INPUTS:
 *   CERTCertDBHandle *handle
 *     Cert database on which OCSP checking should stop using a default
 *     responder.
 * RETURN:
 *   Returns SECFailure if an error occurred; SECSuccess otherwise.
 *   Errors very unlikely (like random memory corruption...).
 */
SECStatus
CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle)
{
    CERTStatusConfig *statusConfig;
    ocspCheckingContext *statusContext;
    CERTCertificate *tmpCert;

    if (handle == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    statusConfig = CERT_GetStatusConfig(handle);
    if (statusConfig == NULL)
        return SECSuccess;

    statusContext = ocsp_GetCheckingContext(handle);
    PORT_Assert(statusContext != NULL);
    if (statusContext == NULL)
        return SECFailure;

    tmpCert = statusContext->defaultResponderCert;
    if (tmpCert) {
        statusContext->defaultResponderCert = NULL;
        CERT_DestroyCertificate(tmpCert);
        /* we don't allow a mix of cache entries from different responders */
        CERT_ClearOCSPCache();
    }

    /*
     * Finally, record the fact.
     */
    statusContext->useDefaultResponder = PR_FALSE;
    return SECSuccess;
}

SECStatus
CERT_ForcePostMethodForOCSP(PRBool forcePost)
{
    if (!OCSP_Global.monitor) {
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
        return SECFailure;
    }

    PR_EnterMonitor(OCSP_Global.monitor);
    OCSP_Global.forcePost = forcePost;
    PR_ExitMonitor(OCSP_Global.monitor);

    return SECSuccess;
}

SECStatus
CERT_GetOCSPResponseStatus(CERTOCSPResponse *response)
{
    PORT_Assert(response);
    if (response->statusValue == ocspResponse_successful)
        return SECSuccess;

    switch (response->statusValue) {
        case ocspResponse_malformedRequest:
            PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);
            break;
        case ocspResponse_internalError:
            PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
            break;
        case ocspResponse_tryLater:
            PORT_SetError(SEC_ERROR_OCSP_TRY_SERVER_LATER);
            break;
        case ocspResponse_sigRequired:
            /* XXX We *should* retry with a signature, if possible. */
            PORT_SetError(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG);
            break;
        case ocspResponse_unauthorized:
            PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST);
            break;
        case ocspResponse_unused:
        default:
            PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS);
            break;
    }
    return SECFailure;
}
