/* 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;
}

static 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 sigAlg;
    SECOidTag encAlg;
    SECOidTag hashAlg;
    PRUint32 policyFlags;

    if (!pubKey || !sd) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        return SECFailure;
    }

    /* Can we use this algorithm for signature verification?  */
    sigAlg = SECOID_GetAlgorithmTag(&sd->signatureAlgorithm);
    rv = sec_DecodeSigAlg(pubKey, sigAlg,
                          &sd->signatureAlgorithm.parameters,
                          &encAlg, &hashAlg);
    if (rv != SECSuccess) {
        return SECFailure; /* error is set */
    }
    rv = NSS_GetAlgorithmPolicy(encAlg, &policyFlags);
    if (rv == SECSuccess &&
        !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
        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;
    }
    rv = checkKeyParams(&sd->signatureAlgorithm, pubKey);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
        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) {
        return SECFailure; /* error is set */
    }

    /* for some algorithms, hash algorithm is only known after verification */
    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 SECSuccess;
}

/*
 * 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 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 (!(certType & requiredCertType)) {
            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;
}
