/* 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/. */
#include "nspr.h"
#include "secerr.h"
#include "secport.h"
#include "seccomon.h"
#include "secoid.h"
#include "genname.h"
#include "keyhi.h"
#include "cert.h"
#include "certdb.h"
#include "certi.h"
#include "cryptohi.h"

#ifndef NSS_DISABLE_LIBPKIX
#include "pkix.h"
#include "pkix_pl_cert.h"
#else
#include "nss.h"
#endif /* NSS_DISABLE_LIBPKIX */

#include "nsspki.h"
#include "pkitm.h"
#include "pkim.h"
#include "pki3hack.h"
#include "base.h"
#include "keyi.h"

/*
 * Check the validity times of a certificate
 */
SECStatus
CERT_CertTimesValid(CERTCertificate *c)
{
    SECCertTimeValidity valid = CERT_CheckCertValidTimes(c, PR_Now(), PR_TRUE);
    return (valid == secCertTimeValid) ? SECSuccess : SECFailure;
}

SECStatus
checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicKey *key)
{
    SECStatus rv;
    SECOidTag sigAlg;
    SECOidTag curve;
    PRUint32 policyFlags = 0;
    PRInt32 minLen, len;

    sigAlg = SECOID_GetAlgorithmTag(sigAlgorithm);

    switch (sigAlg) {
        case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
        case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
        case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
        case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
        case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
            if (key->keyType != ecKey) {
                PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
                return SECFailure;
            }

            curve = SECKEY_GetECCOid(&key->u.ec.DEREncodedParams);
            if (curve != 0) {
                if (NSS_GetAlgorithmPolicy(curve, &policyFlags) == SECFailure ||
                    !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
                    PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
                    return SECFailure;
                } else {
                    return SECSuccess;
                }
            } else {
                PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
                return SECFailure;
            }
            return SECSuccess;

        case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: {
            PORTCheapArenaPool tmpArena;
            SECOidTag hashAlg;
            SECOidTag maskHashAlg;

            PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
            rv = sec_DecodeRSAPSSParams(&tmpArena.arena,
                                        &sigAlgorithm->parameters,
                                        &hashAlg, &maskHashAlg, NULL);
            PORT_DestroyCheapArena(&tmpArena);
            if (rv != SECSuccess) {
                return SECFailure;
            }

            if (NSS_GetAlgorithmPolicy(hashAlg, &policyFlags) == SECSuccess &&
                !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
                PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
                return SECFailure;
            }
            if (NSS_GetAlgorithmPolicy(maskHashAlg, &policyFlags) == SECSuccess &&
                !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
                PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
                return SECFailure;
            }
        }
        /* fall through to RSA key checking */
        case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
        case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
        case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
            if (key->keyType != rsaKey && key->keyType != rsaPssKey) {
                PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
                return SECFailure;
            }

            len = 8 * key->u.rsa.modulus.len;

            rv = NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minLen);
            if (rv != SECSuccess) {
                return SECFailure;
            }

            if (len < minLen) {
                return SECFailure;
            }

            return SECSuccess;
        case SEC_OID_ANSIX9_DSA_SIGNATURE:
        case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
        case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
        case SEC_OID_SDN702_DSA_SIGNATURE:
        case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
        case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
            if (key->keyType != dsaKey) {
                PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
                return SECFailure;
            }

            len = 8 * key->u.dsa.params.prime.len;

            rv = NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minLen);
            if (rv != SECSuccess) {
                return SECFailure;
            }

            if (len < minLen) {
                return SECFailure;
            }

            return SECSuccess;
        default:
            return SECSuccess;
    }
}

/*
 * verify the signature of a signed data object with the given DER publickey
 */
SECStatus
CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd,
                                   SECKEYPublicKey *pubKey,
                                   void *wincx)
{
    SECStatus rv;
    SECItem sig;
    SECOidTag hashAlg = SEC_OID_UNKNOWN;

    if (!pubKey || !sd) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        return SECFailure;
    }
    /* check the signature */
    sig = sd->signature;
    /* convert sig->len from bit counts to byte count. */
    DER_ConvertBitString(&sig);

    rv = VFY_VerifyDataWithAlgorithmID(sd->data.data, sd->data.len, pubKey,
                                       &sig, &sd->signatureAlgorithm, &hashAlg, wincx);
    if (rv == SECSuccess) {
        /* Are we honoring signatures for this algorithm?  */
        PRUint32 policyFlags = 0;
        rv = checkKeyParams(&sd->signatureAlgorithm, pubKey);
        if (rv != SECSuccess) {
            PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
            return SECFailure;
        }

        rv = NSS_GetAlgorithmPolicy(hashAlg, &policyFlags);
        if (rv == SECSuccess &&
            !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
            PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
            return SECFailure;
        }
    }
    return rv;
}

/*
 * verify the signature of a signed data object with the given DER publickey
 */
SECStatus
CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd,
                                       CERTSubjectPublicKeyInfo *pubKeyInfo,
                                       void *wincx)
{
    SECKEYPublicKey *pubKey;
    SECStatus rv = SECFailure;

    /* get cert's public key */
    pubKey = SECKEY_ExtractPublicKey(pubKeyInfo);
    if (pubKey) {
        rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx);
        SECKEY_DestroyPublicKey(pubKey);
    }
    return rv;
}

/*
 * verify the signature of a signed data object with the given certificate
 */
SECStatus
CERT_VerifySignedData(CERTSignedData *sd, CERTCertificate *cert,
                      PRTime t, void *wincx)
{
    SECKEYPublicKey *pubKey = 0;
    SECStatus rv = SECFailure;
    SECCertTimeValidity validity;

    /* check the certificate's validity */
    validity = CERT_CheckCertValidTimes(cert, t, PR_FALSE);
    if (validity != secCertTimeValid) {
        return rv;
    }

    /* get cert's public key */
    pubKey = CERT_ExtractPublicKey(cert);
    if (pubKey) {
        rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx);
        SECKEY_DestroyPublicKey(pubKey);
    }
    return rv;
}

SECStatus
SEC_CheckCRL(CERTCertDBHandle *handle, CERTCertificate *cert,
             CERTCertificate *caCert, PRTime t, void *wincx)
{
    return CERT_CheckCRL(cert, caCert, NULL, t, wincx);
}

/*
 * Find the issuer of a cert.  Use the authorityKeyID if it exists.
 */
CERTCertificate *
CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime, SECCertUsage usage)
{
    NSSCertificate *me;
    NSSTime *nssTime;
    NSSTrustDomain *td;
    NSSCryptoContext *cc;
    NSSCertificate *chain[3];
    NSSUsage nssUsage;
    PRStatus status;

    me = STAN_GetNSSCertificate(cert);
    if (!me) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }
    nssTime = NSSTime_SetPRTime(NULL, validTime);
    nssUsage.anyUsage = PR_FALSE;
    nssUsage.nss3usage = usage;
    nssUsage.nss3lookingForCA = PR_TRUE;
    memset(chain, 0, 3 * sizeof(NSSCertificate *));
    td = STAN_GetDefaultTrustDomain();
    cc = STAN_GetDefaultCryptoContext();
    (void)NSSCertificate_BuildChain(me, nssTime, &nssUsage, NULL,
                                    chain, 2, NULL, &status, td, cc);
    nss_ZFreeIf(nssTime);
    if (status == PR_SUCCESS) {
        PORT_Assert(me == chain[0]);
        /* if it's a root, the chain will only have one cert */
        if (!chain[1]) {
            /* already has a reference from the call to BuildChain */
            return cert;
        }
        NSSCertificate_Destroy(chain[0]);         /* the first cert in the chain */
        return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */
    }
    if (chain[0]) {
        PORT_Assert(me == chain[0]);
        NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */
    }
    PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
    return NULL;
}

/*
 * return required trust flags for various cert usages for CAs
 */
SECStatus
CERT_TrustFlagsForCACertUsage(SECCertUsage usage,
                              unsigned int *retFlags,
                              SECTrustType *retTrustType)
{
    unsigned int requiredFlags;
    SECTrustType trustType;

    switch (usage) {
        case certUsageSSLClient:
            requiredFlags = CERTDB_TRUSTED_CLIENT_CA;
            trustType = trustSSL;
            break;
        case certUsageSSLServer:
        case certUsageSSLCA:
            requiredFlags = CERTDB_TRUSTED_CA;
            trustType = trustSSL;
            break;
        case certUsageIPsec:
            requiredFlags = CERTDB_TRUSTED_CA;
            trustType = trustSSL;
            break;
        case certUsageSSLServerWithStepUp:
            requiredFlags = CERTDB_TRUSTED_CA | CERTDB_GOVT_APPROVED_CA;
            trustType = trustSSL;
            break;
        case certUsageEmailSigner:
        case certUsageEmailRecipient:
            requiredFlags = CERTDB_TRUSTED_CA;
            trustType = trustEmail;
            break;
        case certUsageObjectSigner:
            requiredFlags = CERTDB_TRUSTED_CA;
            trustType = trustObjectSigning;
            break;
        case certUsageVerifyCA:
        case certUsageAnyCA:
        case certUsageStatusResponder:
            requiredFlags = CERTDB_TRUSTED_CA;
            trustType = trustTypeNone;
            break;
        default:
            PORT_Assert(0);
            goto loser;
    }
    if (retFlags != NULL) {
        *retFlags = requiredFlags;
    }
    if (retTrustType != NULL) {
        *retTrustType = trustType;
    }

    return (SECSuccess);
loser:
    return (SECFailure);
}

void
cert_AddToVerifyLog(CERTVerifyLog *log, CERTCertificate *cert, long error,
                    unsigned int depth, void *arg)
{
    CERTVerifyLogNode *node, *tnode;

    PORT_Assert(log != NULL);

    node = (CERTVerifyLogNode *)PORT_ArenaAlloc(log->arena,
                                                sizeof(CERTVerifyLogNode));
    if (node != NULL) {
        node->cert = CERT_DupCertificate(cert);
        node->error = error;
        node->depth = depth;
        node->arg = arg;

        if (log->tail == NULL) {
            /* empty list */
            log->head = log->tail = node;
            node->prev = NULL;
            node->next = NULL;
        } else if (depth >= log->tail->depth) {
            /* add to tail */
            node->prev = log->tail;
            log->tail->next = node;
            log->tail = node;
            node->next = NULL;
        } else if (depth < log->head->depth) {
            /* add at head */
            node->prev = NULL;
            node->next = log->head;
            log->head->prev = node;
            log->head = node;
        } else {
            /* add in middle */
            tnode = log->tail;
            while (tnode != NULL) {
                if (depth >= tnode->depth) {
                    /* insert after tnode */
                    node->prev = tnode;
                    node->next = tnode->next;
                    tnode->next->prev = node;
                    tnode->next = node;
                    break;
                }

                tnode = tnode->prev;
            }
        }

        log->count++;
    }
    return;
}

#define EXIT_IF_NOT_LOGGING(log) \
    if (log == NULL) {           \
        goto loser;              \
    }

#define LOG_ERROR_OR_EXIT(log, cert, depth, arg)               \
    if (log != NULL) {                                         \
        cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \
                            (void *)(PRWord)arg);              \
    } else {                                                   \
        goto loser;                                            \
    }

#define LOG_ERROR(log, cert, depth, arg)                       \
    if (log != NULL) {                                         \
        cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \
                            (void *)(PRWord)arg);              \
    }

/* /C=CN/O=WoSign CA Limited/CN=CA \xE6\xB2\x83\xE9\x80\x9A\xE6\xA0\xB9\xE8\xAF\x81\xE4\xB9\xA6
 * Using a consistent naming convention, this would actually be called
 * 'CA沃通根证书DN', but since GCC 6.2.1 apparently can't handle UTF-8
 * identifiers, this will have to do.
 */
static const unsigned char CAWoSignRootDN[72] = {
    0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
    0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
    0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
    0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03,
    0x0C, 0x12, 0x43, 0x41, 0x20, 0xE6, 0xB2, 0x83, 0xE9, 0x80, 0x9A, 0xE6, 0xA0,
    0xB9, 0xE8, 0xAF, 0x81, 0xE4, 0xB9, 0xA6,
};

/* /C=CN/O=WoSign CA Limited/CN=CA WoSign ECC Root */
static const unsigned char CAWoSignECCRootDN[72] = {
    0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
    0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
    0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
    0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03,
    0x13, 0x12, 0x43, 0x41, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45,
    0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74,
};

/* /C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign */
static const unsigned char CertificationAuthorityofWoSignDN[87] = {
    0x30, 0x55, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
    0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
    0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
    0x69, 0x74, 0x65, 0x64, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03,
    0x13, 0x21, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
    0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20,
    0x6F, 0x66, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E,
};

/* /C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign G2 */
static const unsigned char CertificationAuthorityofWoSignG2DN[90] = {
    0x30, 0x58, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
    0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
    0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
    0x69, 0x74, 0x65, 0x64, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03,
    0x13, 0x24, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
    0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20,
    0x6F, 0x66, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, 0x32,
};

/* /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority */
static const unsigned char StartComCertificationAuthorityDN[127] = {
    0x30, 0x7D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
    0x49, 0x4C, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D,
    0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x4C, 0x74, 0x64, 0x2E,
    0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x22, 0x53, 0x65,
    0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6C, 0x20,
    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53,
    0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55,
    0x04, 0x03, 0x13, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20,
    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E,
    0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79,
};

/* /C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 */
static const unsigned char StartComCertificationAuthorityG2DN[85] = {
    0x30, 0x53, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
    0x49, 0x4C, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D,
    0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x4C, 0x74, 0x64, 0x2E,
    0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x23, 0x53, 0x74,
    0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
    0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F,
    0x72, 0x69, 0x74, 0x79, 0x20, 0x47, 0x32,
};

struct DataAndLength {
    const unsigned char *data;
    PRUint32 len;
};

static const struct DataAndLength StartComAndWoSignDNs[] = {
    { CAWoSignRootDN,
      sizeof(CAWoSignRootDN) },
    { CAWoSignECCRootDN,
      sizeof(CAWoSignECCRootDN) },
    { CertificationAuthorityofWoSignDN,
      sizeof(CertificationAuthorityofWoSignDN) },
    { CertificationAuthorityofWoSignG2DN,
      sizeof(CertificationAuthorityofWoSignG2DN) },
    { StartComCertificationAuthorityDN,
      sizeof(StartComCertificationAuthorityDN) },
    { StartComCertificationAuthorityG2DN,
      sizeof(StartComCertificationAuthorityG2DN) },
};

static PRBool
CertIsStartComOrWoSign(const CERTCertificate *cert)
{
    int i;
    const struct DataAndLength *dn = StartComAndWoSignDNs;

    for (i = 0; i < sizeof(StartComAndWoSignDNs) / sizeof(struct DataAndLength); ++i, dn++) {
        if (cert->derSubject.len == dn->len &&
            memcmp(cert->derSubject.data, dn->data, dn->len) == 0) {
            return PR_TRUE;
        }
    }
    return PR_FALSE;
}

SECStatus
isIssuerCertAllowedAtCertIssuanceTime(CERTCertificate *issuerCert,
                                      CERTCertificate *referenceCert)
{
    if (!issuerCert || !referenceCert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (CertIsStartComOrWoSign(issuerCert)) {
        /* PRTime is microseconds since the epoch, whereas JS time is milliseconds.
         * (new Date("2016-10-21T00:00:00Z")).getTime() * 1000
         */
        static const PRTime OCTOBER_21_2016 = 1477008000000000;

        PRTime notBefore, notAfter;
        SECStatus rv;

        rv = CERT_GetCertTimes(referenceCert, &notBefore, &notAfter);
        if (rv != SECSuccess)
            return rv;

        if (notBefore > OCTOBER_21_2016) {
            return SECFailure;
        }
    }

    return SECSuccess;
}

static SECStatus
cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
                        PRBool checkSig, PRBool *sigerror,
                        SECCertUsage certUsage, PRTime t, void *wincx,
                        CERTVerifyLog *log, PRBool *revoked)
{
    SECTrustType trustType;
    CERTBasicConstraints basicConstraint;
    CERTCertificate *issuerCert = NULL;
    CERTCertificate *subjectCert = NULL;
    CERTCertificate *badCert = NULL;
    PRBool isca;
    SECStatus rv;
    SECStatus rvFinal = SECSuccess;
    int count;
    int currentPathLen = 0;
    int pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT;
    unsigned int caCertType;
    unsigned int requiredCAKeyUsage;
    unsigned int requiredFlags;
    PLArenaPool *arena = NULL;
    CERTGeneralName *namesList = NULL;
    CERTCertificate **certsList = NULL;
    int certsListLen = 16;
    int namesCount = 0;
    PRBool subjectCertIsSelfIssued;
    CERTCertTrust issuerTrust;

    if (revoked) {
        *revoked = PR_FALSE;
    }

    if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE,
                                         &requiredCAKeyUsage,
                                         &caCertType) !=
        SECSuccess) {
        PORT_Assert(0);
        EXIT_IF_NOT_LOGGING(log);
        requiredCAKeyUsage = 0;
        caCertType = 0;
    }

    switch (certUsage) {
        case certUsageSSLClient:
        case certUsageSSLServer:
        case certUsageIPsec:
        case certUsageSSLCA:
        case certUsageSSLServerWithStepUp:
        case certUsageEmailSigner:
        case certUsageEmailRecipient:
        case certUsageObjectSigner:
        case certUsageVerifyCA:
        case certUsageAnyCA:
        case certUsageStatusResponder:
            if (CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags,
                                              &trustType) != SECSuccess) {
                PORT_Assert(0);
                EXIT_IF_NOT_LOGGING(log);
                /* XXX continuing with requiredFlags = 0 seems wrong.  It'll
                 * cause the following test to be true incorrectly:
                 *   flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType);
                 *   if (( flags & requiredFlags ) == requiredFlags) {
                 *       rv = rvFinal;
                 *       goto done;
                 *   }
                 * There are three other instances of this problem.
                 */
                requiredFlags = 0;
                trustType = trustSSL;
            }
            break;
        default:
            PORT_Assert(0);
            EXIT_IF_NOT_LOGGING(log);
            requiredFlags = 0;
            trustType = trustSSL; /* This used to be 0, but we need something
                                   * that matches the enumeration type.
                                   */
            caCertType = 0;
    }

    subjectCert = CERT_DupCertificate(cert);
    if (subjectCert == NULL) {
        goto loser;
    }

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }

    certsList = PORT_ZNewArray(CERTCertificate *, certsListLen);
    if (certsList == NULL)
        goto loser;

    /* RFC 3280 says that the name constraints will apply to the names
    ** in the leaf (EE) cert, whether it is self issued or not, so
    ** we pretend that it is not.
    */
    subjectCertIsSelfIssued = PR_FALSE;
    for (count = 0; count < CERT_MAX_CERT_CHAIN; count++) {
        PRBool validCAOverride = PR_FALSE;

        /* Construct a list of names for the current and all previous
         * certifcates (except leaf (EE) certs, root CAs, and self-issued
         * intermediate CAs) to be verified against the name constraints
         * extension of the issuer certificate.
         */
        if (subjectCertIsSelfIssued == PR_FALSE) {
            CERTGeneralName *subjectNameList;
            int subjectNameListLen;
            int i;
            PRBool getSubjectCN = (!count &&
                                   (certUsage == certUsageSSLServer || certUsage == certUsageIPsec));
            subjectNameList =
                CERT_GetConstrainedCertificateNames(subjectCert, arena,
                                                    getSubjectCN);
            if (!subjectNameList)
                goto loser;
            subjectNameListLen = CERT_GetNamesLength(subjectNameList);
            if (!subjectNameListLen)
                goto loser;
            if (certsListLen <= namesCount + subjectNameListLen) {
                CERTCertificate **tmpCertsList;
                certsListLen = (namesCount + subjectNameListLen) * 2;
                tmpCertsList =
                    (CERTCertificate **)PORT_Realloc(certsList,
                                                     certsListLen *
                                                         sizeof(CERTCertificate *));
                if (tmpCertsList == NULL) {
                    goto loser;
                }
                certsList = tmpCertsList;
            }
            for (i = 0; i < subjectNameListLen; i++) {
                certsList[namesCount + i] = subjectCert;
            }
            namesCount += subjectNameListLen;
            namesList = cert_CombineNamesLists(namesList, subjectNameList);
        }

        /* check if the cert has an unsupported critical extension */
        if (subjectCert->options.bits.hasUnsupportedCriticalExt) {
            PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
            LOG_ERROR_OR_EXIT(log, subjectCert, count, 0);
        }

        /* find the certificate of the issuer */
        issuerCert = CERT_FindCertIssuer(subjectCert, t, certUsage);
        if (!issuerCert) {
            PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
            LOG_ERROR(log, subjectCert, count, 0);
            goto loser;
        }

        /* verify the signature on the cert */
        if (checkSig) {
            rv = CERT_VerifySignedData(&subjectCert->signatureWrap,
                                       issuerCert, t, wincx);

            if (rv != SECSuccess) {
                if (sigerror) {
                    *sigerror = PR_TRUE;
                }
                if (PORT_GetError() == SEC_ERROR_EXPIRED_CERTIFICATE) {
                    PORT_SetError(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE);
                    LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0);
                } else {
                    if (PORT_GetError() !=
                        SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED) {
                        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
                    }
                    LOG_ERROR_OR_EXIT(log, subjectCert, count, 0);
                }
            }
        }

        /* If the basicConstraint extension is included in an immediate CA
         * certificate, make sure that the isCA flag is on.  If the
         * pathLenConstraint component exists, it must be greater than the
         * number of CA certificates we have seen so far.  If the extension
         * is omitted, we will assume that this is a CA certificate with
         * an unlimited pathLenConstraint (since it already passes the
         * netscape-cert-type extension checking).
         */

        rv = CERT_FindBasicConstraintExten(issuerCert, &basicConstraint);
        if (rv != SECSuccess) {
            if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) {
                LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0);
            }
            pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT;
            /* no basic constraints found, we aren't (yet) a CA. */
            isca = PR_FALSE;
        } else {
            if (basicConstraint.isCA == PR_FALSE) {
                PORT_SetError(SEC_ERROR_CA_CERT_INVALID);
                LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0);
            }
            pathLengthLimit = basicConstraint.pathLenConstraint;
            isca = PR_TRUE;
        }
        /* make sure that the path len constraint is properly set.*/
        if (pathLengthLimit >= 0 && currentPathLen > pathLengthLimit) {
            PORT_SetError(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID);
            LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, pathLengthLimit);
        }

        /* make sure that the entire chain is within the name space of the
         * current issuer certificate.
         */
        rv = CERT_CompareNameSpace(issuerCert, namesList, certsList,
                                   arena, &badCert);
        if (rv != SECSuccess || badCert != NULL) {
            PORT_SetError(SEC_ERROR_CERT_NOT_IN_NAME_SPACE);
            LOG_ERROR_OR_EXIT(log, badCert, count + 1, 0);
            goto loser;
        }

        rv = isIssuerCertAllowedAtCertIssuanceTime(issuerCert, cert);
        if (rv != SECSuccess) {
            PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
            LOG_ERROR(log, issuerCert, count + 1, 0);
            goto loser;
        }

        /* XXX - the error logging may need to go down into CRL stuff at some
         * point
         */
        /* check revoked list (issuer) */
        rv = SEC_CheckCRL(handle, subjectCert, issuerCert, t, wincx);
        if (rv == SECFailure) {
            if (revoked) {
                *revoked = PR_TRUE;
            }
            LOG_ERROR_OR_EXIT(log, subjectCert, count, 0);
        } else if (rv == SECWouldBlock) {
            /* We found something fishy, so we intend to issue an
             * error to the user, but the user may wish to continue
             * processing, in which case we better make sure nothing
             * worse has happened... so keep cranking the loop */
            rvFinal = SECFailure;
            if (revoked) {
                *revoked = PR_TRUE;
            }
            LOG_ERROR(log, subjectCert, count, 0);
        }

        if (CERT_GetCertTrust(issuerCert, &issuerTrust) == SECSuccess) {
            /* we have some trust info, but this does NOT imply that this
             * cert is actually trusted for any purpose.  The cert may be
             * explicitly UNtrusted.  We won't know until we examine the
             * trust bits.
             */
            unsigned int flags;

            if (certUsage != certUsageAnyCA &&
                certUsage != certUsageStatusResponder) {

                /*
                 * XXX This choice of trustType seems arbitrary.
                 */
                if (certUsage == certUsageVerifyCA) {
                    if (subjectCert->nsCertType & NS_CERT_TYPE_EMAIL_CA) {
                        trustType = trustEmail;
                    } else if (subjectCert->nsCertType & NS_CERT_TYPE_SSL_CA) {
                        trustType = trustSSL;
                    } else {
                        trustType = trustObjectSigning;
                    }
                }

                flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType);
                if ((flags & requiredFlags) == requiredFlags) {
                    /* we found a trusted one, so return */
                    rv = rvFinal;
                    goto done;
                }
                if (flags & CERTDB_VALID_CA) {
                    validCAOverride = PR_TRUE;
                }
                /* is it explicitly distrusted? */
                if ((flags & CERTDB_TERMINAL_RECORD) &&
                    ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0)) {
                    /* untrusted -- the cert is explicitly untrusted, not
                     * just that it doesn't chain to a trusted cert */
                    PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
                    LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, flags);
                }
            } else {
                /* Check if we have any valid trust when cheching for
                 * certUsageAnyCA or certUsageStatusResponder. */
                for (trustType = trustSSL; trustType < trustTypeNone;
                     trustType++) {
                    flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType);
                    if ((flags & requiredFlags) == requiredFlags) {
                        rv = rvFinal;
                        goto done;
                    }
                    if (flags & CERTDB_VALID_CA)
                        validCAOverride = PR_TRUE;
                }
                /* We have 2 separate loops because we want any single trust
                 * bit to allow this usage to return trusted. Only if none of
                 * the trust bits are on do we check to see if the cert is
                 * untrusted */
                for (trustType = trustSSL; trustType < trustTypeNone;
                     trustType++) {
                    flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType);
                    /* is it explicitly distrusted? */
                    if ((flags & CERTDB_TERMINAL_RECORD) &&
                        ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0)) {
                        /* untrusted -- the cert is explicitly untrusted, not
                         * just that it doesn't chain to a trusted cert */
                        PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
                        LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, flags);
                    }
                }
            }
        }

        if (!validCAOverride) {
            /*
             * Make sure that if this is an intermediate CA in the chain that
             * it was given permission by its signer to be a CA.
             */
            /*
             * if basicConstraints says it is a ca, then we check the
             * nsCertType.  If the nsCertType has any CA bits set, then
             * it must have the right one.
             */
            if (!isca || (issuerCert->nsCertType & NS_CERT_TYPE_CA)) {
                isca = (issuerCert->nsCertType & caCertType) ? PR_TRUE : PR_FALSE;
            }

            if (!isca) {
                PORT_SetError(SEC_ERROR_CA_CERT_INVALID);
                LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, 0);
            }

            /* make sure key usage allows cert signing */
            if (CERT_CheckKeyUsage(issuerCert, requiredCAKeyUsage) != SECSuccess) {
                PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
                LOG_ERROR_OR_EXIT(log, issuerCert, count + 1, requiredCAKeyUsage);
            }
        }

        /* make sure that the issuer is not self signed.  If it is, then
         * stop here to prevent looping.
         */
        if (issuerCert->isRoot) {
            PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
            LOG_ERROR(log, issuerCert, count + 1, 0);
            goto loser;
        }
        /* The issuer cert will be the subject cert in the next loop.
         * A cert is self-issued if its subject and issuer are equal and
         * both are of non-zero length.
         */
        subjectCertIsSelfIssued = (PRBool)
                                      SECITEM_ItemsAreEqual(&issuerCert->derIssuer,
                                                            &issuerCert->derSubject) &&
                                  issuerCert->derSubject.len >
                                      0;
        if (subjectCertIsSelfIssued == PR_FALSE) {
            /* RFC 3280 says only non-self-issued intermediate CA certs
             * count in path length.
             */
            ++currentPathLen;
        }

        CERT_DestroyCertificate(subjectCert);
        subjectCert = issuerCert;
        issuerCert = NULL;
    }

    PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
    LOG_ERROR(log, subjectCert, count, 0);
loser:
    rv = SECFailure;
done:
    if (certsList != NULL) {
        PORT_Free(certsList);
    }
    if (issuerCert) {
        CERT_DestroyCertificate(issuerCert);
    }

    if (subjectCert) {
        CERT_DestroyCertificate(subjectCert);
    }

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

SECStatus
cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert,
                     PRBool checkSig, PRBool *sigerror,
                     SECCertUsage certUsage, PRTime t, void *wincx,
                     CERTVerifyLog *log, PRBool *revoked)
{
    if (CERT_GetUsePKIXForValidation()) {
        return cert_VerifyCertChainPkix(cert, checkSig, certUsage, t,
                                        wincx, log, sigerror, revoked);
    }
    return cert_VerifyCertChainOld(handle, cert, checkSig, sigerror,
                                   certUsage, t, wincx, log, revoked);
}

SECStatus
CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert,
                     PRBool checkSig, SECCertUsage certUsage, PRTime t,
                     void *wincx, CERTVerifyLog *log)
{
    return cert_VerifyCertChain(handle, cert, checkSig, NULL, certUsage, t,
                                wincx, log, NULL);
}

/*
 * verify that a CA can sign a certificate with the requested usage.
 */
SECStatus
CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
                          PRBool checkSig, SECCertUsage certUsage, PRTime t,
                          void *wincx, CERTVerifyLog *log)
{
    SECTrustType trustType;
    CERTBasicConstraints basicConstraint;
    PRBool isca;
    PRBool validCAOverride = PR_FALSE;
    SECStatus rv;
    SECStatus rvFinal = SECSuccess;
    unsigned int flags;
    unsigned int caCertType;
    unsigned int requiredCAKeyUsage;
    unsigned int requiredFlags;
    CERTCertificate *issuerCert;
    CERTCertTrust certTrust;

    if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE,
                                         &requiredCAKeyUsage,
                                         &caCertType) != SECSuccess) {
        PORT_Assert(0);
        EXIT_IF_NOT_LOGGING(log);
        requiredCAKeyUsage = 0;
        caCertType = 0;
    }

    switch (certUsage) {
        case certUsageSSLClient:
        case certUsageSSLServer:
        case certUsageIPsec:
        case certUsageSSLCA:
        case certUsageSSLServerWithStepUp:
        case certUsageEmailSigner:
        case certUsageEmailRecipient:
        case certUsageObjectSigner:
        case certUsageVerifyCA:
        case certUsageStatusResponder:
            if (CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags,
                                              &trustType) != SECSuccess) {
                PORT_Assert(0);
                EXIT_IF_NOT_LOGGING(log);
                requiredFlags = 0;
                trustType = trustSSL;
            }
            break;
        default:
            PORT_Assert(0);
            EXIT_IF_NOT_LOGGING(log);
            requiredFlags = 0;
            trustType = trustSSL; /* This used to be 0, but we need something
                                   * that matches the enumeration type.
                                   */
            caCertType = 0;
    }

    /* If the basicConstraint extension is included in an intermmediate CA
     * certificate, make sure that the isCA flag is on.  If the
     * pathLenConstraint component exists, it must be greater than the
     * number of CA certificates we have seen so far.  If the extension
     * is omitted, we will assume that this is a CA certificate with
     * an unlimited pathLenConstraint (since it already passes the
     * netscape-cert-type extension checking).
     */

    rv = CERT_FindBasicConstraintExten(cert, &basicConstraint);
    if (rv != SECSuccess) {
        if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) {
            LOG_ERROR_OR_EXIT(log, cert, 0, 0);
        }
        /* no basic constraints found, we aren't (yet) a CA. */
        isca = PR_FALSE;
    } else {
        if (basicConstraint.isCA == PR_FALSE) {
            PORT_SetError(SEC_ERROR_CA_CERT_INVALID);
            LOG_ERROR_OR_EXIT(log, cert, 0, 0);
        }

        /* can't check path length if we don't know the previous path */
        isca = PR_TRUE;
    }

    if (CERT_GetCertTrust(cert, &certTrust) == SECSuccess) {
        /* we have some trust info, but this does NOT imply that this
         * cert is actually trusted for any purpose.  The cert may be
         * explicitly UNtrusted.  We won't know until we examine the
         * trust bits.
         */
        if (certUsage == certUsageStatusResponder) {
            /* Check the special case of certUsageStatusResponder */
            issuerCert = CERT_FindCertIssuer(cert, t, certUsage);
            if (issuerCert) {
                if (SEC_CheckCRL(handle, cert, issuerCert, t, wincx) !=
                    SECSuccess) {
                    PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
                    CERT_DestroyCertificate(issuerCert);
                    goto loser;
                }
                CERT_DestroyCertificate(issuerCert);
            }
            /* XXX We have NOT determined that this cert is trusted.
             * For years, NSS has treated this as trusted,
             * but it seems incorrect.
             */
            rv = rvFinal;
            goto done;
        }

        /*
         * check the trust params of the issuer
         */
        flags = SEC_GET_TRUST_FLAGS(&certTrust, trustType);
        if ((flags & requiredFlags) == requiredFlags) {
            /* we found a trusted one, so return */
            rv = rvFinal;
            goto done;
        }
        if (flags & CERTDB_VALID_CA) {
            validCAOverride = PR_TRUE;
        }
        /* is it explicitly distrusted? */
        if ((flags & CERTDB_TERMINAL_RECORD) &&
            ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0)) {
            /* untrusted -- the cert is explicitly untrusted, not
             * just that it doesn't chain to a trusted cert */
            PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
            LOG_ERROR_OR_EXIT(log, cert, 0, flags);
        }
    }
    if (!validCAOverride) {
        /*
         * Make sure that if this is an intermediate CA in the chain that
         * it was given permission by its signer to be a CA.
         */
        /*
         * if basicConstraints says it is a ca, then we check the
         * nsCertType.  If the nsCertType has any CA bits set, then
         * it must have the right one.
         */
        if (!isca || (cert->nsCertType & NS_CERT_TYPE_CA)) {
            isca = (cert->nsCertType & caCertType) ? PR_TRUE : PR_FALSE;
        }

        if (!isca) {
            PORT_SetError(SEC_ERROR_CA_CERT_INVALID);
            LOG_ERROR_OR_EXIT(log, cert, 0, 0);
        }

        /* make sure key usage allows cert signing */
        if (CERT_CheckKeyUsage(cert, requiredCAKeyUsage) != SECSuccess) {
            PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
            LOG_ERROR_OR_EXIT(log, cert, 0, requiredCAKeyUsage);
        }
    }
    /* make sure that the issuer is not self signed.  If it is, then
     * stop here to prevent looping.
     */
    if (cert->isRoot) {
        PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
        LOG_ERROR(log, cert, 0, 0);
        goto loser;
    }

    return CERT_VerifyCertChain(handle, cert, checkSig, certUsage, t,
                                wincx, log);
loser:
    rv = SECFailure;
done:
    return rv;
}

#define NEXT_USAGE() \
    {                \
        i *= 2;      \
        certUsage++; \
        continue;    \
    }

#define VALID_USAGE() \
    {                 \
        NEXT_USAGE(); \
    }

#define INVALID_USAGE()                 \
    {                                   \
        if (returnedUsages) {           \
            *returnedUsages &= (~i);    \
        }                               \
        if (PR_TRUE == requiredUsage) { \
            valid = SECFailure;         \
        }                               \
        NEXT_USAGE();                   \
    }

/*
 * check the leaf cert against trust and usage.
 *   returns success if the cert is not distrusted. If the cert is
 *       trusted, then the trusted bool will be true.
 *   returns failure if the cert is distrusted. If failure, flags
 *       will return the flag bits that indicated distrust.
 */
SECStatus
cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
                    unsigned int *failedFlags, PRBool *trusted)
{
    unsigned int flags;
    CERTCertTrust trust;

    *failedFlags = 0;
    *trusted = PR_FALSE;

    /* check trust flags to see if this cert is directly trusted */
    if (CERT_GetCertTrust(cert, &trust) == SECSuccess) {
        switch (certUsage) {
            case certUsageSSLClient:
            case certUsageSSLServer:
            case certUsageIPsec:
                flags = trust.sslFlags;

                /* is the cert directly trusted or not trusted ? */
                if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
                            * authoritative */
                    if (flags & CERTDB_TRUSTED) {     /* trust this cert */
                        *trusted = PR_TRUE;
                        return SECSuccess;
                    } else { /* don't trust this cert */
                        *failedFlags = flags;
                        return SECFailure;
                    }
                }
                break;
            case certUsageSSLServerWithStepUp:
                /* XXX - step up certs can't be directly trusted, only distrust */
                flags = trust.sslFlags;
                if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
                                                       * authoritative */
                    if ((flags & CERTDB_TRUSTED) == 0) {
                        /* don't trust this cert */
                        *failedFlags = flags;
                        return SECFailure;
                    }
                }
                break;
            case certUsageSSLCA:
                flags = trust.sslFlags;
                if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
                                                       * authoritative */
                    if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) {
                        /* don't trust this cert */
                        *failedFlags = flags;
                        return SECFailure;
                    }
                }
                break;
            case certUsageEmailSigner:
            case certUsageEmailRecipient:
                flags = trust.emailFlags;
                if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
                                                       * authoritative */
                    if (flags & CERTDB_TRUSTED) {     /* trust this cert */
                        *trusted = PR_TRUE;
                        return SECSuccess;
                    } else { /* don't trust this cert */
                        *failedFlags = flags;
                        return SECFailure;
                    }
                }

                break;
            case certUsageObjectSigner:
                flags = trust.objectSigningFlags;

                if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
                                                       * authoritative */
                    if (flags & CERTDB_TRUSTED) {     /* trust this cert */
                        *trusted = PR_TRUE;
                        return SECSuccess;
                    } else { /* don't trust this cert */
                        *failedFlags = flags;
                        return SECFailure;
                    }
                }
                break;
            case certUsageVerifyCA:
            case certUsageStatusResponder:
                flags = trust.sslFlags;
                /* is the cert directly trusted or not trusted ? */
                if ((flags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) ==
                    (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) {
                    *trusted = PR_TRUE;
                    return SECSuccess;
                }
                flags = trust.emailFlags;
                /* is the cert directly trusted or not trusted ? */
                if ((flags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) ==
                    (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) {
                    *trusted = PR_TRUE;
                    return SECSuccess;
                }
                flags = trust.objectSigningFlags;
                /* is the cert directly trusted or not trusted ? */
                if ((flags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) ==
                    (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) {
                    *trusted = PR_TRUE;
                    return SECSuccess;
                }
            /* fall through to test distrust */
            case certUsageAnyCA:
            case certUsageUserCertImport:
                /* do we distrust these certs explicitly */
                flags = trust.sslFlags;
                if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
                            * authoritative */
                    if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) {
                        *failedFlags = flags;
                        return SECFailure;
                    }
                }
                flags = trust.emailFlags;
                if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
                            * authoritative */
                    if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) {
                        *failedFlags = flags;
                        return SECFailure;
                    }
                }
            /* fall through */
            case certUsageProtectedObjectSigner:
                flags = trust.objectSigningFlags;
                if (flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
                                                       * authoritative */
                    if ((flags & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA)) == 0) {
                        *failedFlags = flags;
                        return SECFailure;
                    }
                }
                break;
        }
    }
    return SECSuccess;
}

/*
 * verify a certificate by checking if it's valid and that we
 * trust the issuer.
 *
 * certificateUsage contains a bitfield of all cert usages that are
 * required for verification to succeed
 *
 * a bitfield of cert usages is returned in *returnedUsages
 * if requiredUsages is non-zero, the returned bitmap is only
 * for those required usages, otherwise it is for all usages
 *
 */
SECStatus
CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
                       PRBool checkSig, SECCertificateUsage requiredUsages, PRTime t,
                       void *wincx, CERTVerifyLog *log, SECCertificateUsage *returnedUsages)
{
    SECStatus rv;
    SECStatus valid;
    unsigned int requiredKeyUsage;
    unsigned int requiredCertType;
    unsigned int flags;
    unsigned int certType;
    PRBool allowOverride;
    SECCertTimeValidity validity;
    CERTStatusConfig *statusConfig;
    PRInt32 i;
    SECCertUsage certUsage = 0;
    PRBool checkedOCSP = PR_FALSE;
    PRBool checkAllUsages = PR_FALSE;
    PRBool revoked = PR_FALSE;
    PRBool sigerror = PR_FALSE;
    PRBool trusted = PR_FALSE;

    if (!requiredUsages) {
        /* there are no required usages, so the user probably wants to
           get status for all usages */
        checkAllUsages = PR_TRUE;
    }

    if (returnedUsages) {
        *returnedUsages = 0;
    } else {
        /* we don't have a place to return status for all usages,
           so we can skip checks for usages that aren't required */
        checkAllUsages = PR_FALSE;
    }
    valid = SECSuccess; /* start off assuming cert is valid */

    /* make sure that the cert is valid at time t */
    allowOverride = (PRBool)((requiredUsages & certificateUsageSSLServer) ||
                             (requiredUsages & certificateUsageSSLServerWithStepUp) ||
                             (requiredUsages & certificateUsageIPsec));
    validity = CERT_CheckCertValidTimes(cert, t, allowOverride);
    if (validity != secCertTimeValid) {
        valid = SECFailure;
        LOG_ERROR_OR_EXIT(log, cert, 0, validity);
    }

    /* check key usage and netscape cert type */
    cert_GetCertType(cert);
    certType = cert->nsCertType;

    for (i = 1; i <= certificateUsageHighest &&
                (SECSuccess == valid || returnedUsages || log);) {
        PRBool typeAndEKUAllowed = PR_TRUE;
        PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE;
        if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) {
            NEXT_USAGE();
        }
        if (returnedUsages) {
            *returnedUsages |= i; /* start off assuming this usage is valid */
        }
        switch (certUsage) {
            case certUsageSSLClient:
            case certUsageSSLServer:
            case certUsageSSLServerWithStepUp:
            case certUsageSSLCA:
            case certUsageEmailSigner:
            case certUsageEmailRecipient:
            case certUsageObjectSigner:
            case certUsageStatusResponder:
            case certUsageIPsec:
                rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE,
                                                      &requiredKeyUsage,
                                                      &requiredCertType);
                if (rv != SECSuccess) {
                    PORT_Assert(0);
                    /* EXIT_IF_NOT_LOGGING(log); XXX ??? */
                    requiredKeyUsage = 0;
                    requiredCertType = 0;
                    INVALID_USAGE();
                }
                break;

            case certUsageAnyCA:
            case certUsageProtectedObjectSigner:
            case certUsageUserCertImport:
            case certUsageVerifyCA:
                /* these usages cannot be verified */
                NEXT_USAGE();

            default:
                PORT_Assert(0);
                requiredKeyUsage = 0;
                requiredCertType = 0;
                INVALID_USAGE();
        }
        if (CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess) {
            if (PR_TRUE == requiredUsage) {
                PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
            }
            LOG_ERROR(log, cert, 0, requiredKeyUsage);
            INVALID_USAGE();
        }
        if (certUsage != certUsageIPsec) {
            if (!(certType & requiredCertType)) {
                typeAndEKUAllowed = PR_FALSE;
            }
        } else {
            PRBool isCritical;
            PRBool allowed = cert_EKUAllowsIPsecIKE(cert, &isCritical);
            /* If the extension isn't critical, we allow any EKU value. */
            if (isCritical && !allowed) {
                typeAndEKUAllowed = PR_FALSE;
            }
        }
        if (!typeAndEKUAllowed) {
            if (PR_TRUE == requiredUsage) {
                PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE);
            }
            LOG_ERROR(log, cert, 0, requiredCertType);
            INVALID_USAGE();
        }

        rv = cert_CheckLeafTrust(cert, certUsage, &flags, &trusted);
        if (rv == SECFailure) {
            if (PR_TRUE == requiredUsage) {
                PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
            }
            LOG_ERROR(log, cert, 0, flags);
            INVALID_USAGE();
        } else if (trusted) {
            VALID_USAGE();
        }

        if (PR_TRUE == revoked || PR_TRUE == sigerror) {
            INVALID_USAGE();
        }

        rv = cert_VerifyCertChain(handle, cert,
                                  checkSig, &sigerror,
                                  certUsage, t, wincx, log,
                                  &revoked);

        if (rv != SECSuccess) {
            /* EXIT_IF_NOT_LOGGING(log); XXX ???? */
            INVALID_USAGE();
        }

        /*
         * Check OCSP revocation status, but only if the cert we are checking
         * is not a status responder itself. We only do this in the case
         * where we checked the cert chain (above); explicit trust "wins"
         * (avoids status checking, just as it avoids CRL checking) by
         * bypassing this code.
         */

        if (PR_FALSE == checkedOCSP) {
            checkedOCSP = PR_TRUE; /* only check OCSP once */
            statusConfig = CERT_GetStatusConfig(handle);
            if (requiredUsages != certificateUsageStatusResponder &&
                statusConfig != NULL) {
                if (statusConfig->statusChecker != NULL) {
                    rv = (*statusConfig->statusChecker)(handle, cert,
                                                        t, wincx);
                    if (rv != SECSuccess) {
                        LOG_ERROR(log, cert, 0, 0);
                        revoked = PR_TRUE;
                        INVALID_USAGE();
                    }
                }
            }
        }

        NEXT_USAGE();
    }

loser:
    return (valid);
}

SECStatus
CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert,
                PRBool checkSig, SECCertUsage certUsage, PRTime t,
                void *wincx, CERTVerifyLog *log)
{
    return cert_VerifyCertWithFlags(handle, cert, checkSig, certUsage, t,
                                    CERT_VERIFYCERT_USE_DEFAULTS, wincx, log);
}

SECStatus
cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
                         PRBool checkSig, SECCertUsage certUsage, PRTime t,
                         PRUint32 flags, void *wincx, CERTVerifyLog *log)
{
    SECStatus rv;
    unsigned int requiredKeyUsage;
    unsigned int requiredCertType;
    unsigned int failedFlags;
    unsigned int certType;
    PRBool trusted;
    PRBool allowOverride;
    SECCertTimeValidity validity;
    CERTStatusConfig *statusConfig;

#ifdef notdef
    /* check if this cert is in the Evil list */
    rv = CERT_CheckForEvilCert(cert);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
        LOG_ERROR_OR_EXIT(log, cert, 0, 0);
    }
#endif

    /* make sure that the cert is valid at time t */
    allowOverride = (PRBool)((certUsage == certUsageSSLServer) ||
                             (certUsage == certUsageSSLServerWithStepUp) ||
                             (certUsage == certUsageIPsec));
    validity = CERT_CheckCertValidTimes(cert, t, allowOverride);
    if (validity != secCertTimeValid) {
        LOG_ERROR_OR_EXIT(log, cert, 0, validity);
    }

    /* check key usage and netscape cert type */
    cert_GetCertType(cert);
    certType = cert->nsCertType;
    switch (certUsage) {
        case certUsageSSLClient:
        case certUsageSSLServer:
        case certUsageSSLServerWithStepUp:
        case certUsageIPsec:
        case certUsageSSLCA:
        case certUsageEmailSigner:
        case certUsageEmailRecipient:
        case certUsageObjectSigner:
        case certUsageStatusResponder:
            rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE,
                                                  &requiredKeyUsage,
                                                  &requiredCertType);
            if (rv != SECSuccess) {
                PORT_Assert(0);
                EXIT_IF_NOT_LOGGING(log);
                requiredKeyUsage = 0;
                requiredCertType = 0;
            }
            break;
        case certUsageVerifyCA:
        case certUsageAnyCA:
            requiredKeyUsage = KU_KEY_CERT_SIGN;
            requiredCertType = NS_CERT_TYPE_CA;
            if (!(certType & NS_CERT_TYPE_CA)) {
                certType |= NS_CERT_TYPE_CA;
            }
            break;
        default:
            PORT_Assert(0);
            EXIT_IF_NOT_LOGGING(log);
            requiredKeyUsage = 0;
            requiredCertType = 0;
    }
    if (CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess) {
        PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
        LOG_ERROR_OR_EXIT(log, cert, 0, requiredKeyUsage);
    }
    if (!(certType & requiredCertType)) {
        PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE);
        LOG_ERROR_OR_EXIT(log, cert, 0, requiredCertType);
    }

    rv = cert_CheckLeafTrust(cert, certUsage, &failedFlags, &trusted);
    if (rv == SECFailure) {
        PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
        LOG_ERROR_OR_EXIT(log, cert, 0, failedFlags);
    } else if (trusted) {
        goto done;
    }

    rv = CERT_VerifyCertChain(handle, cert, checkSig, certUsage,
                              t, wincx, log);
    if (rv != SECSuccess) {
        EXIT_IF_NOT_LOGGING(log);
    }

    /*
     * Check revocation status, but only if the cert we are checking is not a
     * status responder itself and the caller did not ask us to skip the check.
     * We only do this in the case where we checked the cert chain (above);
     * explicit trust "wins" (avoids status checking, just as it avoids CRL
     * checking, which is all done inside VerifyCertChain) by bypassing this
     * code.
     */
    if (!(flags & CERT_VERIFYCERT_SKIP_OCSP) &&
        certUsage != certUsageStatusResponder) {
        statusConfig = CERT_GetStatusConfig(handle);
        if (statusConfig && statusConfig->statusChecker) {
            rv = (*statusConfig->statusChecker)(handle, cert,
                                                t, wincx);
            if (rv != SECSuccess) {
                LOG_ERROR_OR_EXIT(log, cert, 0, 0);
            }
        }
    }

done:
    if (log && log->head) {
        return SECFailure;
    }
    return (SECSuccess);

loser:
    rv = SECFailure;

    return (rv);
}

/*
 * verify a certificate by checking if its valid and that we
 * trust the issuer.  Verify time against now.
 */
SECStatus
CERT_VerifyCertificateNow(CERTCertDBHandle *handle, CERTCertificate *cert,
                          PRBool checkSig, SECCertificateUsage requiredUsages,
                          void *wincx, SECCertificateUsage *returnedUsages)
{
    return (CERT_VerifyCertificate(handle, cert, checkSig,
                                   requiredUsages, PR_Now(), wincx, NULL, returnedUsages));
}

/* obsolete, do not use for new code */
SECStatus
CERT_VerifyCertNow(CERTCertDBHandle *handle, CERTCertificate *cert,
                   PRBool checkSig, SECCertUsage certUsage, void *wincx)
{
    return (CERT_VerifyCert(handle, cert, checkSig,
                            certUsage, PR_Now(), wincx, NULL));
}

/* [ FROM pcertdb.c ] */
/*
 * Supported usage values and types:
 *  certUsageSSLClient
 *  certUsageSSLServer
 *  certUsageSSLServerWithStepUp
 *  certUsageIPsec
 *  certUsageEmailSigner
 *  certUsageEmailRecipient
 *  certUsageObjectSigner
 */

CERTCertificate *
CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName,
                      CERTCertOwner owner, SECCertUsage usage,
                      PRBool preferTrusted, PRTime validTime, PRBool validOnly)
{
    CERTCertList *certList = NULL;
    CERTCertificate *cert = NULL;
    CERTCertTrust certTrust;
    unsigned int requiredTrustFlags;
    SECTrustType requiredTrustType;
    unsigned int flags;

    PRBool lookingForCA = PR_FALSE;
    SECStatus rv;
    CERTCertListNode *node;
    CERTCertificate *saveUntrustedCA = NULL;

    /* if preferTrusted is set, must be a CA cert */
    PORT_Assert(!(preferTrusted && (owner != certOwnerCA)));

    if (owner == certOwnerCA) {
        lookingForCA = PR_TRUE;
        if (preferTrusted) {
            rv = CERT_TrustFlagsForCACertUsage(usage, &requiredTrustFlags,
                                               &requiredTrustType);
            if (rv != SECSuccess) {
                goto loser;
            }
            requiredTrustFlags |= CERTDB_VALID_CA;
        }
    }

    certList = CERT_CreateSubjectCertList(NULL, handle, derName, validTime,
                                          validOnly);
    if (certList != NULL) {
        rv = CERT_FilterCertListByUsage(certList, usage, lookingForCA);
        if (rv != SECSuccess) {
            goto loser;
        }

        node = CERT_LIST_HEAD(certList);

        while (!CERT_LIST_END(node, certList)) {
            cert = node->cert;

            /* looking for a trusted CA cert */
            if ((owner == certOwnerCA) && preferTrusted &&
                (requiredTrustType != trustTypeNone)) {

                if (CERT_GetCertTrust(cert, &certTrust) != SECSuccess) {
                    flags = 0;
                } else {
                    flags = SEC_GET_TRUST_FLAGS(&certTrust, requiredTrustType);
                }

                if ((flags & requiredTrustFlags) != requiredTrustFlags) {
                    /* cert is not trusted */
                    /* if this is the first cert to get this far, then save
                     * it, so we can use it if we can't find a trusted one
                     */
                    if (saveUntrustedCA == NULL) {
                        saveUntrustedCA = cert;
                    }
                    goto endloop;
                }
            }
            /* if we got this far, then this cert meets all criteria */
            break;

        endloop:
            node = CERT_LIST_NEXT(node);
            cert = NULL;
        }

        /* use the saved one if we have it */
        if (cert == NULL) {
            cert = saveUntrustedCA;
        }

        /* if we found one then bump the ref count before freeing the list */
        if (cert != NULL) {
            /* bump the ref count */
            cert = CERT_DupCertificate(cert);
        }

        CERT_DestroyCertList(certList);
    }

    return (cert);

loser:
    if (certList != NULL) {
        CERT_DestroyCertList(certList);
    }

    return (NULL);
}

/* [ From certdb.c ] */
/*
 * Filter a list of certificates, removing those certs that do not have
 * one of the named CA certs somewhere in their cert chain.
 *
 *  "certList" - the list of certificates to filter
 *  "nCANames" - number of CA names
 *  "caNames" - array of CA names in string(rfc 1485) form
 *  "usage" - what use the certs are for, this is used when
 *      selecting CA certs
 */
SECStatus
CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames,
                             char **caNames, SECCertUsage usage)
{
    CERTCertificate *issuerCert = NULL;
    CERTCertificate *subjectCert;
    CERTCertListNode *node, *freenode;
    CERTCertificate *cert;
    int n;
    char **names;
    PRBool found;
    PRTime time;

    if (nCANames <= 0) {
        return (SECSuccess);
    }

    time = PR_Now();

    node = CERT_LIST_HEAD(certList);

    while (!CERT_LIST_END(node, certList)) {
        cert = node->cert;

        subjectCert = CERT_DupCertificate(cert);

        /* traverse the CA certs for this cert */
        found = PR_FALSE;
        while (subjectCert != NULL) {
            n = nCANames;
            names = caNames;

            if (subjectCert->issuerName != NULL) {
                while (n > 0) {
                    if (PORT_Strcmp(*names, subjectCert->issuerName) == 0) {
                        found = PR_TRUE;
                        break;
                    }

                    n--;
                    names++;
                }
            }

            if (found) {
                break;
            }

            issuerCert = CERT_FindCertIssuer(subjectCert, time, usage);
            if (issuerCert == subjectCert) {
                CERT_DestroyCertificate(issuerCert);
                issuerCert = NULL;
                break;
            }
            CERT_DestroyCertificate(subjectCert);
            subjectCert = issuerCert;
        }
        CERT_DestroyCertificate(subjectCert);
        if (!found) {
            /* CA was not found, so remove this cert from the list */
            freenode = node;
            node = CERT_LIST_NEXT(node);
            CERT_RemoveCertListNode(freenode);
        } else {
            /* CA was found, so leave it in the list */
            node = CERT_LIST_NEXT(node);
        }
    }

    return (SECSuccess);
}

/*
 * Given a certificate, return a string containing the nickname, and possibly
 * one of the validity strings, based on the current validity state of the
 * certificate.
 *
 * "arena" - arena to allocate returned string from.  If NULL, then heap
 *  is used.
 * "cert" - the cert to get nickname from
 * "expiredString" - the string to append to the nickname if the cert is
 *      expired.
 * "notYetGoodString" - the string to append to the nickname if the cert is
 *      not yet good.
 */
char *
CERT_GetCertNicknameWithValidity(PLArenaPool *arena, CERTCertificate *cert,
                                 char *expiredString, char *notYetGoodString)
{
    SECCertTimeValidity validity;
    char *nickname = NULL, *tmpstr = NULL;

    validity = CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE);

    /* if the cert is good, then just use the nickname directly */
    if (validity == secCertTimeValid) {
        if (arena == NULL) {
            nickname = PORT_Strdup(cert->nickname);
        } else {
            nickname = PORT_ArenaStrdup(arena, cert->nickname);
        }

        if (nickname == NULL) {
            goto loser;
        }
    } else {

        /* if the cert is not valid, then tack one of the strings on the
         * end
         */
        if (validity == secCertTimeExpired) {
            tmpstr = PR_smprintf("%s%s", cert->nickname,
                                 expiredString);
        } else if (validity == secCertTimeNotValidYet) {
            /* not yet valid */
            tmpstr = PR_smprintf("%s%s", cert->nickname,
                                 notYetGoodString);
        } else {
            /* undetermined */
            tmpstr = PR_smprintf("%s",
                                 "(NULL) (Validity Unknown)");
        }

        if (tmpstr == NULL) {
            goto loser;
        }

        if (arena) {
            /* copy the string into the arena and free the malloc'd one */
            nickname = PORT_ArenaStrdup(arena, tmpstr);
            PORT_Free(tmpstr);
        } else {
            nickname = tmpstr;
        }
        if (nickname == NULL) {
            goto loser;
        }
    }
    return (nickname);

loser:
    return (NULL);
}

/*
 * Collect the nicknames from all certs in a CertList.  If the cert is not
 * valid, append a string to that nickname.
 *
 * "certList" - the list of certificates
 * "expiredString" - the string to append to the nickname of any expired cert
 * "notYetGoodString" - the string to append to the nickname of any cert
 *      that is not yet valid
 */
CERTCertNicknames *
CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString,
                                 char *notYetGoodString)
{
    CERTCertNicknames *names;
    PLArenaPool *arena;
    CERTCertListNode *node;
    char **nn;

    /* allocate an arena */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        return (NULL);
    }

    /* allocate the structure */
    names = PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames));
    if (names == NULL) {
        goto loser;
    }

    /* init the structure */
    names->arena = arena;
    names->head = NULL;
    names->numnicknames = 0;
    names->nicknames = NULL;
    names->totallen = 0;

    /* count the certs in the list */
    node = CERT_LIST_HEAD(certList);
    while (!CERT_LIST_END(node, certList)) {
        names->numnicknames++;
        node = CERT_LIST_NEXT(node);
    }

    /* allocate nicknames array */
    names->nicknames = PORT_ArenaAlloc(arena,
                                       sizeof(char *) * names->numnicknames);
    if (names->nicknames == NULL) {
        goto loser;
    }

    /* just in case printf can't deal with null strings */
    if (expiredString == NULL) {
        expiredString = "";
    }

    if (notYetGoodString == NULL) {
        notYetGoodString = "";
    }

    /* traverse the list of certs and collect the nicknames */
    nn = names->nicknames;
    node = CERT_LIST_HEAD(certList);
    while (!CERT_LIST_END(node, certList)) {
        *nn = CERT_GetCertNicknameWithValidity(arena, node->cert,
                                               expiredString,
                                               notYetGoodString);
        if (*nn == NULL) {
            goto loser;
        }

        names->totallen += PORT_Strlen(*nn);

        nn++;
        node = CERT_LIST_NEXT(node);
    }

    return (names);

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

/*
 * Extract the nickname from a nickmake string that may have either
 * expiredString or notYetGoodString appended.
 *
 * Args:
 *  "namestring" - the string containing the nickname, and possibly
 *      one of the validity label strings
 *  "expiredString" - the expired validity label string
 *  "notYetGoodString" - the not yet good validity label string
 *
 * Returns the raw nickname
 */
char *
CERT_ExtractNicknameString(char *namestring, char *expiredString,
                           char *notYetGoodString)
{
    int explen, nyglen, namelen;
    int retlen;
    char *retstr;

    namelen = PORT_Strlen(namestring);
    explen = PORT_Strlen(expiredString);
    nyglen = PORT_Strlen(notYetGoodString);

    if (namelen > explen) {
        if (PORT_Strcmp(expiredString, &namestring[namelen - explen]) == 0) {
            retlen = namelen - explen;
            retstr = (char *)PORT_Alloc(retlen + 1);
            if (retstr == NULL) {
                goto loser;
            }

            PORT_Memcpy(retstr, namestring, retlen);
            retstr[retlen] = '\0';
            goto done;
        }
    }

    if (namelen > nyglen) {
        if (PORT_Strcmp(notYetGoodString, &namestring[namelen - nyglen]) == 0) {
            retlen = namelen - nyglen;
            retstr = (char *)PORT_Alloc(retlen + 1);
            if (retstr == NULL) {
                goto loser;
            }

            PORT_Memcpy(retstr, namestring, retlen);
            retstr[retlen] = '\0';
            goto done;
        }
    }

    /* if name string is shorter than either invalid string, then it must
     * be a raw nickname
     */
    retstr = PORT_Strdup(namestring);

done:
    return (retstr);

loser:
    return (NULL);
}

CERTCertList *
CERT_GetCertChainFromCert(CERTCertificate *cert, PRTime time, SECCertUsage usage)
{
    CERTCertList *chain = NULL;
    int count = 0;

    if (NULL == cert) {
        return NULL;
    }

    cert = CERT_DupCertificate(cert);
    if (NULL == cert) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    chain = CERT_NewCertList();
    if (NULL == chain) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    while (cert != NULL && ++count <= CERT_MAX_CERT_CHAIN) {
        if (SECSuccess != CERT_AddCertToListTail(chain, cert)) {
            /* return partial chain */
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            return chain;
        }

        if (cert->isRoot) {
            /* return complete chain */
            return chain;
        }

        cert = CERT_FindCertIssuer(cert, time, usage);
    }

    /* return partial chain */
    PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
    return chain;
}
