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

/*
 * Certificate handling code
 */

#include "nssilock.h"
#include "prmon.h"
#include "prtime.h"
#include "cert.h"
#include "certi.h"
#include "secder.h"
#include "secoid.h"
#include "secasn1.h"
#include "genname.h"
#include "keyhi.h"
#include "secitem.h"
#include "certdb.h"
#include "prprf.h"
#include "sechash.h"
#include "prlong.h"
#include "certxutl.h"
#include "portreg.h"
#include "secerr.h"
#include "sslerr.h"
#include "pk11func.h"
#include "xconst.h" /* for  CERT_DecodeAltNameExtension */

#include "pki.h"
#include "pki3hack.h"

SEC_ASN1_MKSUB(CERT_TimeChoiceTemplate)
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
SEC_ASN1_MKSUB(SEC_BitStringTemplate)
SEC_ASN1_MKSUB(SEC_IntegerTemplate)
SEC_ASN1_MKSUB(SEC_SkipTemplate)

/*
 * Certificate database handling code
 */

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

const SEC_ASN1Template CERT_SequenceOfCertExtensionTemplate[] = {
    { SEC_ASN1_SEQUENCE_OF, 0, CERT_CertExtensionTemplate }
};

const SEC_ASN1Template CERT_TimeChoiceTemplate[] = {
    { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) },
    { SEC_ASN1_UTC_TIME, 0, 0, siUTCTime },
    { SEC_ASN1_GENERALIZED_TIME, 0, 0, siGeneralizedTime },
    { 0 }
};

const SEC_ASN1Template CERT_ValidityTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTValidity) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CERTValidity, notBefore),
      SEC_ASN1_SUB(CERT_TimeChoiceTemplate), 0 },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CERTValidity, notAfter),
      SEC_ASN1_SUB(CERT_TimeChoiceTemplate), 0 },
    { 0 }
};

const SEC_ASN1Template CERT_CertificateTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertificate) },
    { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
          SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, /* XXX DER_DEFAULT */
      offsetof(CERTCertificate, version),
      SEC_ASN1_SUB(SEC_IntegerTemplate) },
    { SEC_ASN1_INTEGER, offsetof(CERTCertificate, serialNumber) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CERTCertificate, signature),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_SAVE, offsetof(CERTCertificate, derIssuer) },
    { SEC_ASN1_INLINE, offsetof(CERTCertificate, issuer), CERT_NameTemplate },
    { SEC_ASN1_INLINE, offsetof(CERTCertificate, validity),
      CERT_ValidityTemplate },
    { SEC_ASN1_SAVE, offsetof(CERTCertificate, derSubject) },
    { SEC_ASN1_INLINE, offsetof(CERTCertificate, subject), CERT_NameTemplate },
    { SEC_ASN1_SAVE, offsetof(CERTCertificate, derPublicKey) },
    { SEC_ASN1_INLINE, offsetof(CERTCertificate, subjectPublicKeyInfo),
      CERT_SubjectPublicKeyInfoTemplate },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
      offsetof(CERTCertificate, issuerID),
      SEC_ASN1_SUB(SEC_BitStringTemplate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
      offsetof(CERTCertificate, subjectID),
      SEC_ASN1_SUB(SEC_BitStringTemplate) },
    { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
          SEC_ASN1_CONTEXT_SPECIFIC | 3,
      offsetof(CERTCertificate, extensions),
      CERT_SequenceOfCertExtensionTemplate },
    { 0 }
};

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

/*
 * Find the subjectName in a DER encoded certificate
 */
const SEC_ASN1Template SEC_CertSubjectTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) },
    { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
          SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */
    { SEC_ASN1_SKIP },                     /* serial number */
    { SEC_ASN1_SKIP },                     /* signature algorithm */
    { SEC_ASN1_SKIP },                     /* issuer */
    { SEC_ASN1_SKIP },                     /* validity */
    { SEC_ASN1_ANY, 0, NULL },             /* subject */
    { SEC_ASN1_SKIP_REST },
    { 0 }
};

/*
 * Find the issuerName in a DER encoded certificate
 */
const SEC_ASN1Template SEC_CertIssuerTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) },
    { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
          SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */
    { SEC_ASN1_SKIP },                     /* serial number */
    { SEC_ASN1_SKIP },                     /* signature algorithm */
    { SEC_ASN1_ANY, 0, NULL },             /* issuer */
    { SEC_ASN1_SKIP_REST },
    { 0 }
};
/*
 * Find the subjectName in a DER encoded certificate
 */
const SEC_ASN1Template SEC_CertSerialNumberTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) },
    { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
          SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */
    { SEC_ASN1_ANY, 0, NULL },             /* serial number */
    { SEC_ASN1_SKIP_REST },
    { 0 }
};

/*
 * Find the issuer and serialNumber in a DER encoded certificate.
 * This data is used as the database lookup key since its the unique
 * identifier of a certificate.
 */
const SEC_ASN1Template CERT_CertKeyTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertKey) },
    { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
          SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */
    { SEC_ASN1_INTEGER, offsetof(CERTCertKey, serialNumber) },
    { SEC_ASN1_SKIP }, /* signature algorithm */
    { SEC_ASN1_ANY, offsetof(CERTCertKey, derIssuer) },
    { SEC_ASN1_SKIP_REST },
    { 0 }
};

SEC_ASN1_CHOOSER_IMPLEMENT(CERT_TimeChoiceTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SignedCertificateTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SequenceOfCertExtensionTemplate)

SECStatus
CERT_KeyFromIssuerAndSN(PLArenaPool *arena, SECItem *issuer, SECItem *sn,
                        SECItem *key)
{
    key->len = sn->len + issuer->len;

    if ((sn->data == NULL) || (issuer->data == NULL)) {
        goto loser;
    }

    key->data = (unsigned char *)PORT_ArenaAlloc(arena, key->len);
    if (!key->data) {
        goto loser;
    }

    /* copy the serialNumber */
    PORT_Memcpy(key->data, sn->data, sn->len);

    /* copy the issuer */
    PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);

    return (SECSuccess);

loser:
    return (SECFailure);
}

/*
 * Extract the subject name from a DER certificate
 */
SECStatus
CERT_NameFromDERCert(SECItem *derCert, SECItem *derName)
{
    int rv;
    PLArenaPool *arena;
    CERTSignedData sd;
    void *tmpptr;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        return (SECFailure);
    }

    PORT_Memset(&sd, 0, sizeof(CERTSignedData));
    rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);

    if (rv) {
        goto loser;
    }

    PORT_Memset(derName, 0, sizeof(SECItem));
    rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSubjectTemplate,
                                &sd.data);

    if (rv) {
        goto loser;
    }

    tmpptr = derName->data;
    derName->data = (unsigned char *)PORT_Alloc(derName->len);
    if (derName->data == NULL) {
        goto loser;
    }

    PORT_Memcpy(derName->data, tmpptr, derName->len);

    PORT_FreeArena(arena, PR_FALSE);
    return (SECSuccess);

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

SECStatus
CERT_IssuerNameFromDERCert(SECItem *derCert, SECItem *derName)
{
    int rv;
    PLArenaPool *arena;
    CERTSignedData sd;
    void *tmpptr;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        return (SECFailure);
    }

    PORT_Memset(&sd, 0, sizeof(CERTSignedData));
    rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);

    if (rv) {
        goto loser;
    }

    PORT_Memset(derName, 0, sizeof(SECItem));
    rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertIssuerTemplate,
                                &sd.data);

    if (rv) {
        goto loser;
    }

    tmpptr = derName->data;
    derName->data = (unsigned char *)PORT_Alloc(derName->len);
    if (derName->data == NULL) {
        goto loser;
    }

    PORT_Memcpy(derName->data, tmpptr, derName->len);

    PORT_FreeArena(arena, PR_FALSE);
    return (SECSuccess);

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

SECStatus
CERT_SerialNumberFromDERCert(SECItem *derCert, SECItem *derName)
{
    int rv;
    PLArenaPool *arena;
    CERTSignedData sd;
    void *tmpptr;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        return (SECFailure);
    }

    PORT_Memset(&sd, 0, sizeof(CERTSignedData));
    rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);

    if (rv) {
        goto loser;
    }

    PORT_Memset(derName, 0, sizeof(SECItem));
    rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSerialNumberTemplate,
                                &sd.data);

    if (rv) {
        goto loser;
    }

    tmpptr = derName->data;
    derName->data = (unsigned char *)PORT_Alloc(derName->len);
    if (derName->data == NULL) {
        goto loser;
    }

    PORT_Memcpy(derName->data, tmpptr, derName->len);

    PORT_FreeArena(arena, PR_FALSE);
    return (SECSuccess);

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

/*
 * Generate a database key, based on serial number and issuer, from a
 * DER certificate.
 */
SECStatus
CERT_KeyFromDERCert(PLArenaPool *reqArena, SECItem *derCert, SECItem *key)
{
    int rv;
    CERTSignedData sd;
    CERTCertKey certkey;

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

    PORT_Memset(&sd, 0, sizeof(CERTSignedData));
    rv =
        SEC_QuickDERDecodeItem(reqArena, &sd, CERT_SignedDataTemplate, derCert);

    if (rv) {
        goto loser;
    }

    PORT_Memset(&certkey, 0, sizeof(CERTCertKey));
    rv = SEC_QuickDERDecodeItem(reqArena, &certkey, CERT_CertKeyTemplate,
                                &sd.data);

    if (rv) {
        goto loser;
    }

    return (CERT_KeyFromIssuerAndSN(reqArena, &certkey.derIssuer,
                                    &certkey.serialNumber, key));
loser:
    return (SECFailure);
}

/*
 * fill in keyUsage field of the cert based on the cert extension
 * if the extension is not critical, then we allow all uses
 */
static SECStatus
GetKeyUsage(CERTCertificate *cert)
{
    SECStatus rv;
    SECItem tmpitem;

    rv = CERT_FindKeyUsageExtension(cert, &tmpitem);
    if (rv == SECSuccess) {
        /* remember the actual value of the extension */
        cert->rawKeyUsage = tmpitem.data[0];
        cert->keyUsagePresent = PR_TRUE;
        cert->keyUsage = tmpitem.data[0];

        PORT_Free(tmpitem.data);
        tmpitem.data = NULL;
    } else {
        /* if the extension is not present, then we allow all uses */
        cert->keyUsage = KU_ALL;
        cert->rawKeyUsage = KU_ALL;
        cert->keyUsagePresent = PR_FALSE;
    }

    if (CERT_GovtApprovedBitSet(cert)) {
        cert->keyUsage |= KU_NS_GOVT_APPROVED;
        cert->rawKeyUsage |= KU_NS_GOVT_APPROVED;
    }

    return (SECSuccess);
}

static SECStatus
findOIDinOIDSeqByTagNum(CERTOidSequence *seq, SECOidTag tagnum)
{
    SECItem **oids;
    SECItem *oid;
    SECStatus rv = SECFailure;

    if (seq != NULL) {
        oids = seq->oids;
        while (oids != NULL && *oids != NULL) {
            oid = *oids;
            if (SECOID_FindOIDTag(oid) == tagnum) {
                rv = SECSuccess;
                break;
            }
            oids++;
        }
    }
    return rv;
}

/*
 * fill in nsCertType field of the cert based on the cert extension
 */
SECStatus
cert_GetCertType(CERTCertificate *cert)
{
    PRUint32 nsCertType;

    if (cert->nsCertType) {
        /* once set, no need to recalculate */
        return SECSuccess;
    }
    nsCertType = cert_ComputeCertType(cert);

    /* Assert that it is safe to cast &cert->nsCertType to "PRInt32 *" */
    PORT_Assert(sizeof(cert->nsCertType) == sizeof(PRInt32));
    PR_ATOMIC_SET((PRInt32 *)&cert->nsCertType, nsCertType);
    return SECSuccess;
}

PRUint32
cert_ComputeCertType(CERTCertificate *cert)
{
    SECStatus rv;
    SECItem tmpitem;
    SECItem encodedExtKeyUsage;
    CERTOidSequence *extKeyUsage = NULL;
    PRBool basicConstraintPresent = PR_FALSE;
    CERTBasicConstraints basicConstraint;
    PRUint32 nsCertType = 0;

    tmpitem.data = NULL;
    CERT_FindNSCertTypeExtension(cert, &tmpitem);
    encodedExtKeyUsage.data = NULL;
    rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE,
                                &encodedExtKeyUsage);
    if (rv == SECSuccess) {
        extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage);
    }
    rv = CERT_FindBasicConstraintExten(cert, &basicConstraint);
    if (rv == SECSuccess) {
        basicConstraintPresent = PR_TRUE;
    }
    if (tmpitem.data != NULL || extKeyUsage != NULL) {
        if (tmpitem.data == NULL) {
            nsCertType = 0;
        } else {
            nsCertType = tmpitem.data[0];
        }

        /* free tmpitem data pointer to avoid memory leak */
        PORT_Free(tmpitem.data);
        tmpitem.data = NULL;

        /*
         * for this release, we will allow SSL certs with an email address
         * to be used for email
         */
        if ((nsCertType & NS_CERT_TYPE_SSL_CLIENT) && cert->emailAddr &&
            cert->emailAddr[0]) {
            nsCertType |= NS_CERT_TYPE_EMAIL;
        }
        /*
         * for this release, we will allow SSL intermediate CAs to be
         * email intermediate CAs too.
         */
        if (nsCertType & NS_CERT_TYPE_SSL_CA) {
            nsCertType |= NS_CERT_TYPE_EMAIL_CA;
        }
        /*
         * allow a cert with the extended key usage of EMail Protect
         * to be used for email or as an email CA, if basic constraints
         * indicates that it is a CA.
         */
        if (findOIDinOIDSeqByTagNum(extKeyUsage,
                                    SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT) ==
            SECSuccess) {
            if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) {
                nsCertType |= NS_CERT_TYPE_EMAIL_CA;
            } else {
                nsCertType |= NS_CERT_TYPE_EMAIL;
            }
        }
        if (findOIDinOIDSeqByTagNum(
                extKeyUsage, SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) == SECSuccess) {
            if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) {
                nsCertType |= NS_CERT_TYPE_SSL_CA;
            } else {
                nsCertType |= NS_CERT_TYPE_SSL_SERVER;
            }
        }
        /*
         * Treat certs with step-up OID as also having SSL server type.
         * COMODO needs this behaviour until June 2020.  See Bug 737802.
         */
        if (findOIDinOIDSeqByTagNum(extKeyUsage,
                                    SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) ==
            SECSuccess) {
            if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) {
                nsCertType |= NS_CERT_TYPE_SSL_CA;
            } else {
                nsCertType |= NS_CERT_TYPE_SSL_SERVER;
            }
        }
        if (findOIDinOIDSeqByTagNum(
                extKeyUsage, SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) == SECSuccess) {
            if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) {
                nsCertType |= NS_CERT_TYPE_SSL_CA;
            } else {
                nsCertType |= NS_CERT_TYPE_SSL_CLIENT;
            }
        }
        if (findOIDinOIDSeqByTagNum(
                extKeyUsage, SEC_OID_EXT_KEY_USAGE_CODE_SIGN) == SECSuccess) {
            if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) {
                nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
            } else {
                nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING;
            }
        }
        if (findOIDinOIDSeqByTagNum(
                extKeyUsage, SEC_OID_EXT_KEY_USAGE_TIME_STAMP) == SECSuccess) {
            nsCertType |= EXT_KEY_USAGE_TIME_STAMP;
        }
        if (findOIDinOIDSeqByTagNum(extKeyUsage, SEC_OID_OCSP_RESPONDER) ==
            SECSuccess) {
            nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
        }
    } else {
        /* If no NS Cert Type extension and no EKU extension, then */
        nsCertType = 0;
        if (CERT_IsCACert(cert, &nsCertType))
            nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
        /* if the basic constraint extension says the cert is a CA, then
           allow SSL CA and EMAIL CA and Status Responder */
        if (basicConstraintPresent && basicConstraint.isCA) {
            nsCertType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
                           EXT_KEY_USAGE_STATUS_RESPONDER);
        }
        /* allow any ssl or email (no ca or object signing. */
        nsCertType |= NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER |
                      NS_CERT_TYPE_EMAIL;
    }

    if (encodedExtKeyUsage.data != NULL) {
        PORT_Free(encodedExtKeyUsage.data);
    }
    if (extKeyUsage != NULL) {
        CERT_DestroyOidSequence(extKeyUsage);
    }
    return nsCertType;
}

/*
 * cert_GetKeyID() - extract or generate the subjectKeyID from a certificate
 */
SECStatus
cert_GetKeyID(CERTCertificate *cert)
{
    SECItem tmpitem;
    SECStatus rv;

    cert->subjectKeyID.len = 0;

    /* see of the cert has a key identifier extension */
    rv = CERT_FindSubjectKeyIDExtension(cert, &tmpitem);
    if (rv == SECSuccess) {
        cert->subjectKeyID.data =
            (unsigned char *)PORT_ArenaAlloc(cert->arena, tmpitem.len);
        if (cert->subjectKeyID.data != NULL) {
            PORT_Memcpy(cert->subjectKeyID.data, tmpitem.data, tmpitem.len);
            cert->subjectKeyID.len = tmpitem.len;
            cert->keyIDGenerated = PR_FALSE;
        }

        PORT_Free(tmpitem.data);
    }

    /* if the cert doesn't have a key identifier extension, then generate one*/
    if (cert->subjectKeyID.len == 0) {
        /*
         * pkix says that if the subjectKeyID is not present, then we should
         * use the SHA-1 hash of the DER-encoded publicKeyInfo from the cert
         */
        cert->subjectKeyID.data =
            (unsigned char *)PORT_ArenaAlloc(cert->arena, SHA1_LENGTH);
        if (cert->subjectKeyID.data != NULL) {
            rv = PK11_HashBuf(SEC_OID_SHA1, cert->subjectKeyID.data,
                              cert->derPublicKey.data, cert->derPublicKey.len);
            if (rv == SECSuccess) {
                cert->subjectKeyID.len = SHA1_LENGTH;
            }
        }
    }

    if (cert->subjectKeyID.len == 0) {
        return (SECFailure);
    }
    return (SECSuccess);
}

static PRBool
cert_IsRootCert(CERTCertificate *cert)
{
    SECStatus rv;
    SECItem tmpitem;

    /* cache the authKeyID extension, if present */
    cert->authKeyID = CERT_FindAuthKeyIDExten(cert->arena, cert);

    /* it MUST be self-issued to be a root */
    if (cert->derIssuer.len == 0 ||
        !SECITEM_ItemsAreEqual(&cert->derIssuer, &cert->derSubject)) {
        return PR_FALSE;
    }

    /* check the authKeyID extension */
    if (cert->authKeyID) {
        /* authority key identifier is present */
        if (cert->authKeyID->keyID.len > 0) {
            /* the keyIdentifier field is set, look for subjectKeyID */
            rv = CERT_FindSubjectKeyIDExtension(cert, &tmpitem);
            if (rv == SECSuccess) {
                PRBool match;
                /* also present, they MUST match for it to be a root */
                match =
                    SECITEM_ItemsAreEqual(&cert->authKeyID->keyID, &tmpitem);
                PORT_Free(tmpitem.data);
                if (!match)
                    return PR_FALSE; /* else fall through */
            } else {
                /* the subject key ID is required when AKI is present */
                return PR_FALSE;
            }
        }
        if (cert->authKeyID->authCertIssuer) {
            SECItem *caName;
            caName = (SECItem *)CERT_GetGeneralNameByType(
                cert->authKeyID->authCertIssuer, certDirectoryName, PR_TRUE);
            if (caName) {
                if (!SECITEM_ItemsAreEqual(&cert->derIssuer, caName)) {
                    return PR_FALSE;
                } /* else fall through */
            }     /* else ??? could not get general name as directory name? */
        }
        if (cert->authKeyID->authCertSerialNumber.len > 0) {
            if (!SECITEM_ItemsAreEqual(
                    &cert->serialNumber,
                    &cert->authKeyID->authCertSerialNumber)) {
                return PR_FALSE;
            } /* else fall through */
        }
        /* all of the AKI fields that were present passed the test */
        return PR_TRUE;
    }
    /* else the AKI was not present, so this is a root */
    return PR_TRUE;
}

/*
 * take a DER certificate and decode it into a certificate structure
 */
CERTCertificate *
CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
                          char *nickname)
{
    CERTCertificate *cert;
    PLArenaPool *arena;
    void *data;
    int rv;
    int len;
    char *tmpname;

    /* make a new arena */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        return 0;
    }

    /* allocate the certificate structure */
    cert = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));

    if (!cert) {
        goto loser;
    }

    cert->arena = arena;

    if (copyDER) {
        /* copy the DER data for the cert into this arena */
        data = (void *)PORT_ArenaAlloc(arena, derSignedCert->len);
        if (!data) {
            goto loser;
        }
        cert->derCert.data = (unsigned char *)data;
        cert->derCert.len = derSignedCert->len;
        PORT_Memcpy(data, derSignedCert->data, derSignedCert->len);
    } else {
        /* point to passed in DER data */
        cert->derCert = *derSignedCert;
    }

    /* decode the certificate info */
    rv = SEC_QuickDERDecodeItem(arena, cert, SEC_SignedCertificateTemplate,
                                &cert->derCert);

    if (rv) {
        goto loser;
    }

    if (cert_HasUnknownCriticalExten(cert->extensions) == PR_TRUE) {
        cert->options.bits.hasUnsupportedCriticalExt = PR_TRUE;
    }

    /* generate and save the database key for the cert */
    rv = CERT_KeyFromIssuerAndSN(arena, &cert->derIssuer, &cert->serialNumber,
                                 &cert->certKey);
    if (rv) {
        goto loser;
    }

    /* set the nickname */
    if (nickname == NULL) {
        cert->nickname = NULL;
    } else {
        /* copy and install the nickname */
        len = PORT_Strlen(nickname) + 1;
        cert->nickname = (char *)PORT_ArenaAlloc(arena, len);
        if (cert->nickname == NULL) {
            goto loser;
        }

        PORT_Memcpy(cert->nickname, nickname, len);
    }

    /* set the email address */
    cert->emailAddr = cert_GetCertificateEmailAddresses(cert);

    /* initialize the subjectKeyID */
    rv = cert_GetKeyID(cert);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* initialize keyUsage */
    rv = GetKeyUsage(cert);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* determine if this is a root cert */
    cert->isRoot = cert_IsRootCert(cert);

    /* initialize the certType */
    rv = cert_GetCertType(cert);
    if (rv != SECSuccess) {
        goto loser;
    }

    tmpname = CERT_NameToAscii(&cert->subject);
    if (tmpname != NULL) {
        cert->subjectName = PORT_ArenaStrdup(cert->arena, tmpname);
        PORT_Free(tmpname);
    }

    tmpname = CERT_NameToAscii(&cert->issuer);
    if (tmpname != NULL) {
        cert->issuerName = PORT_ArenaStrdup(cert->arena, tmpname);
        PORT_Free(tmpname);
    }

    cert->referenceCount = 1;
    cert->slot = NULL;
    cert->pkcs11ID = CK_INVALID_HANDLE;
    cert->dbnickname = NULL;

    return (cert);

loser:

    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (0);
}

CERTCertificate *
__CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
                            char *nickname)
{
    return CERT_DecodeDERCertificate(derSignedCert, copyDER, nickname);
}

CERTValidity *
CERT_CreateValidity(PRTime notBefore, PRTime notAfter)
{
    CERTValidity *v;
    int rv;
    PLArenaPool *arena;

    if (notBefore > notAfter) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        return (0);
    }

    v = (CERTValidity *)PORT_ArenaZAlloc(arena, sizeof(CERTValidity));
    if (v) {
        v->arena = arena;
        rv = DER_EncodeTimeChoice(arena, &v->notBefore, notBefore);
        if (rv)
            goto loser;
        rv = DER_EncodeTimeChoice(arena, &v->notAfter, notAfter);
        if (rv)
            goto loser;
    }
    return v;

loser:
    CERT_DestroyValidity(v);
    return 0;
}

SECStatus
CERT_CopyValidity(PLArenaPool *arena, CERTValidity *to, CERTValidity *from)
{
    SECStatus rv;

    CERT_DestroyValidity(to);
    to->arena = arena;

    rv = SECITEM_CopyItem(arena, &to->notBefore, &from->notBefore);
    if (rv)
        return rv;
    rv = SECITEM_CopyItem(arena, &to->notAfter, &from->notAfter);
    return rv;
}

void
CERT_DestroyValidity(CERTValidity *v)
{
    if (v && v->arena) {
        PORT_FreeArena(v->arena, PR_FALSE);
    }
    return;
}

/*
** Amount of time that a certifiate is allowed good before it is actually
** good. This is used for pending certificates, ones that are about to be
** valid. The slop is designed to allow for some variance in the clocks
** of the machine checking the certificate.
*/
#define PENDING_SLOP (24L * 60L * 60L)     /* seconds per day */
static PRInt32 pendingSlop = PENDING_SLOP; /* seconds */

PRInt32
CERT_GetSlopTime(void)
{
    return pendingSlop; /* seconds */
}

SECStatus CERT_SetSlopTime(PRInt32 slop) /* seconds */
{
    if (slop < 0)
        return SECFailure;
    pendingSlop = slop;
    return SECSuccess;
}

SECStatus
CERT_GetCertTimes(const CERTCertificate *c, PRTime *notBefore, PRTime *notAfter)
{
    SECStatus rv;

    if (!c || !notBefore || !notAfter) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* convert DER not-before time */
    rv = DER_DecodeTimeChoice(notBefore, &c->validity.notBefore);
    if (rv) {
        return (SECFailure);
    }

    /* convert DER not-after time */
    rv = DER_DecodeTimeChoice(notAfter, &c->validity.notAfter);
    if (rv) {
        return (SECFailure);
    }

    return (SECSuccess);
}

/*
 * Check the validity times of a certificate
 */
SECCertTimeValidity
CERT_CheckCertValidTimes(const CERTCertificate *c, PRTime t,
                         PRBool allowOverride)
{
    PRTime notBefore, notAfter, llPendingSlop, tmp1;
    SECStatus rv;

    if (!c) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return (secCertTimeUndetermined);
    }
    /* if cert is already marked OK, then don't bother to check */
    if (allowOverride && c->timeOK) {
        return (secCertTimeValid);
    }

    rv = CERT_GetCertTimes(c, &notBefore, &notAfter);

    if (rv) {
        return (secCertTimeExpired); /*XXX is this the right thing to do here?*/
    }

    LL_I2L(llPendingSlop, pendingSlop);
    /* convert to micro seconds */
    LL_UI2L(tmp1, PR_USEC_PER_SEC);
    LL_MUL(llPendingSlop, llPendingSlop, tmp1);
    LL_SUB(notBefore, notBefore, llPendingSlop);
    if (LL_CMP(t, <, notBefore)) {
        PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE);
        return (secCertTimeNotValidYet);
    }
    if (LL_CMP(t, >, notAfter)) {
        PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE);
        return (secCertTimeExpired);
    }

    return (secCertTimeValid);
}

SECStatus
SEC_GetCrlTimes(CERTCrl *date, PRTime *notBefore, PRTime *notAfter)
{
    int rv;

    /* convert DER not-before time */
    rv = DER_DecodeTimeChoice(notBefore, &date->lastUpdate);
    if (rv) {
        return (SECFailure);
    }

    /* convert DER not-after time */
    if (date->nextUpdate.data) {
        rv = DER_DecodeTimeChoice(notAfter, &date->nextUpdate);
        if (rv) {
            return (SECFailure);
        }
    } else {
        LL_I2L(*notAfter, 0L);
    }
    return (SECSuccess);
}

/* These routines should probably be combined with the cert
 * routines using an common extraction routine.
 */
SECCertTimeValidity
SEC_CheckCrlTimes(CERTCrl *crl, PRTime t)
{
    PRTime notBefore, notAfter, llPendingSlop, tmp1;
    SECStatus rv;

    if (!crl) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return (secCertTimeUndetermined);
    }

    rv = SEC_GetCrlTimes(crl, &notBefore, &notAfter);

    if (rv) {
        return (secCertTimeExpired);
    }

    LL_I2L(llPendingSlop, pendingSlop);
    /* convert to micro seconds */
    LL_I2L(tmp1, PR_USEC_PER_SEC);
    LL_MUL(llPendingSlop, llPendingSlop, tmp1);
    LL_SUB(notBefore, notBefore, llPendingSlop);
    if (LL_CMP(t, <, notBefore)) {
        PORT_SetError(SEC_ERROR_CRL_EXPIRED);
        return (secCertTimeNotValidYet);
    }

    /* If next update is omitted and the test for notBefore passes, then
       we assume that the crl is up to date.
     */
    if (LL_IS_ZERO(notAfter)) {
        return (secCertTimeValid);
    }

    if (LL_CMP(t, >, notAfter)) {
        PORT_SetError(SEC_ERROR_CRL_EXPIRED);
        return (secCertTimeExpired);
    }

    return (secCertTimeValid);
}

PRBool
SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old)
{
    PRTime newNotBefore, newNotAfter;
    PRTime oldNotBefore, oldNotAfter;
    SECStatus rv;

    /* problems with the new CRL? reject it */
    rv = SEC_GetCrlTimes(inNew, &newNotBefore, &newNotAfter);
    if (rv)
        return PR_FALSE;

    /* problems with the old CRL? replace it */
    rv = SEC_GetCrlTimes(old, &oldNotBefore, &oldNotAfter);
    if (rv)
        return PR_TRUE;

    /* Question: what about the notAfter's? */
    return ((PRBool)LL_CMP(oldNotBefore, <, newNotBefore));
}

/*
 * return required key usage and cert type based on cert usage
 */
SECStatus
CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage, PRBool ca,
                                 unsigned int *retKeyUsage,
                                 unsigned int *retCertType)
{
    unsigned int requiredKeyUsage = 0;
    unsigned int requiredCertType = 0;

    if (ca) {
        switch (usage) {
            case certUsageSSLServerWithStepUp:
                requiredKeyUsage = KU_NS_GOVT_APPROVED | KU_KEY_CERT_SIGN;
                requiredCertType = NS_CERT_TYPE_SSL_CA;
                break;
            case certUsageSSLClient:
                requiredKeyUsage = KU_KEY_CERT_SIGN;
                requiredCertType = NS_CERT_TYPE_SSL_CA;
                break;
            case certUsageSSLServer:
                requiredKeyUsage = KU_KEY_CERT_SIGN;
                requiredCertType = NS_CERT_TYPE_SSL_CA;
                break;
            case certUsageSSLCA:
                requiredKeyUsage = KU_KEY_CERT_SIGN;
                requiredCertType = NS_CERT_TYPE_SSL_CA;
                break;
            case certUsageEmailSigner:
                requiredKeyUsage = KU_KEY_CERT_SIGN;
                requiredCertType = NS_CERT_TYPE_EMAIL_CA;
                break;
            case certUsageEmailRecipient:
                requiredKeyUsage = KU_KEY_CERT_SIGN;
                requiredCertType = NS_CERT_TYPE_EMAIL_CA;
                break;
            case certUsageObjectSigner:
                requiredKeyUsage = KU_KEY_CERT_SIGN;
                requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA;
                break;
            case certUsageAnyCA:
            case certUsageVerifyCA:
            case certUsageStatusResponder:
                requiredKeyUsage = KU_KEY_CERT_SIGN;
                requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA |
                                   NS_CERT_TYPE_EMAIL_CA | NS_CERT_TYPE_SSL_CA;
                break;
            default:
                PORT_Assert(0);
                goto loser;
        }
    } else {
        switch (usage) {
            case certUsageSSLClient:
                /*
                 * RFC 5280 lists digitalSignature and keyAgreement for
                 * id-kp-clientAuth.  NSS does not support the *_fixed_dh and
                 * *_fixed_ecdh client certificate types.
                 */
                requiredKeyUsage = KU_DIGITAL_SIGNATURE;
                requiredCertType = NS_CERT_TYPE_SSL_CLIENT;
                break;
            case certUsageSSLServer:
                requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT;
                requiredCertType = NS_CERT_TYPE_SSL_SERVER;
                break;
            case certUsageSSLServerWithStepUp:
                requiredKeyUsage =
                    KU_KEY_AGREEMENT_OR_ENCIPHERMENT | KU_NS_GOVT_APPROVED;
                requiredCertType = NS_CERT_TYPE_SSL_SERVER;
                break;
            case certUsageSSLCA:
                requiredKeyUsage = KU_KEY_CERT_SIGN;
                requiredCertType = NS_CERT_TYPE_SSL_CA;
                break;
            case certUsageEmailSigner:
                requiredKeyUsage = KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION;
                requiredCertType = NS_CERT_TYPE_EMAIL;
                break;
            case certUsageEmailRecipient:
                requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT;
                requiredCertType = NS_CERT_TYPE_EMAIL;
                break;
            case certUsageObjectSigner:
                /* RFC 5280 lists only digitalSignature for id-kp-codeSigning.
                 */
                requiredKeyUsage = KU_DIGITAL_SIGNATURE;
                requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING;
                break;
            case certUsageStatusResponder:
                requiredKeyUsage = KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION;
                requiredCertType = EXT_KEY_USAGE_STATUS_RESPONDER;
                break;
            default:
                PORT_Assert(0);
                goto loser;
        }
    }

    if (retKeyUsage != NULL) {
        *retKeyUsage = requiredKeyUsage;
    }
    if (retCertType != NULL) {
        *retCertType = requiredCertType;
    }

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

/*
 * check the key usage of a cert against a set of required values
 */
SECStatus
CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage)
{
    if (!cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    /* choose between key agreement or key encipherment based on key
     * type in cert
     */
    if (requiredUsage & KU_KEY_AGREEMENT_OR_ENCIPHERMENT) {
        KeyType keyType = CERT_GetCertKeyType(&cert->subjectPublicKeyInfo);
        /* turn off the special bit */
        requiredUsage &= (~KU_KEY_AGREEMENT_OR_ENCIPHERMENT);

        switch (keyType) {
            case rsaKey:
                requiredUsage |= KU_KEY_ENCIPHERMENT;
                break;
            case dsaKey:
                requiredUsage |= KU_DIGITAL_SIGNATURE;
                break;
            case dhKey:
                requiredUsage |= KU_KEY_AGREEMENT;
                break;
            case ecKey:
                /* Accept either signature or agreement. */
                if (!(cert->keyUsage &
                      (KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)))
                    goto loser;
                break;
            default:
                goto loser;
        }
    }

    /* Allow either digital signature or non-repudiation */
    if (requiredUsage & KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION) {
        /* turn off the special bit */
        requiredUsage &= (~KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION);

        if (!(cert->keyUsage & (KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)))
            goto loser;
    }

    if ((cert->keyUsage & requiredUsage) == requiredUsage)
        return SECSuccess;

loser:
    PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
    return SECFailure;
}

CERTCertificate *
CERT_DupCertificate(CERTCertificate *c)
{
    if (c) {
        NSSCertificate *tmp = STAN_GetNSSCertificate(c);
        nssCertificate_AddRef(tmp);
    }
    return c;
}

/*
 * Allow use of default cert database, so that apps(such as mozilla) don't
 * have to pass the handle all over the place.
 */
static CERTCertDBHandle *default_cert_db_handle = 0;

void
CERT_SetDefaultCertDB(CERTCertDBHandle *handle)
{
    default_cert_db_handle = handle;

    return;
}

CERTCertDBHandle *
CERT_GetDefaultCertDB(void)
{
    return (default_cert_db_handle);
}

/* XXX this would probably be okay/better as an xp routine? */
static void
sec_lower_string(char *s)
{
    if (s == NULL) {
        return;
    }

    while (*s) {
        *s = PORT_Tolower(*s);
        s++;
    }

    return;
}

static PRBool
cert_IsIPAddr(const char *hn)
{
    PRBool isIPaddr = PR_FALSE;
    PRNetAddr netAddr;
    isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr));
    return isIPaddr;
}

/*
** Add a domain name to the list of names that the user has explicitly
** allowed (despite cert name mismatches) for use with a server cert.
*/
SECStatus
CERT_AddOKDomainName(CERTCertificate *cert, const char *hn)
{
    CERTOKDomainName *domainOK;
    int newNameLen;

    if (!hn || !(newNameLen = strlen(hn))) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    domainOK = (CERTOKDomainName *)PORT_ArenaZAlloc(
        cert->arena, (sizeof *domainOK) + newNameLen);
    if (!domainOK)
        return SECFailure; /* error code is already set. */

    PORT_Strcpy(domainOK->name, hn);
    sec_lower_string(domainOK->name);

    /* put at head of list. */
    domainOK->next = cert->domainOK;
    cert->domainOK = domainOK;
    return SECSuccess;
}

/* returns SECSuccess if hn matches pattern cn,
** returns SECFailure with SSL_ERROR_BAD_CERT_DOMAIN if no match,
** returns SECFailure with some other error code if another error occurs.
**
** This function may modify string cn, so caller must pass a modifiable copy.
*/
static SECStatus
cert_TestHostName(char *cn, const char *hn)
{
    static int useShellExp = -1;

    if (useShellExp < 0) {
        useShellExp = (NULL != PR_GetEnvSecure("NSS_USE_SHEXP_IN_CERT_NAME"));
    }
    if (useShellExp) {
        /* Backward compatible code, uses Shell Expressions (SHEXP). */
        int regvalid = PORT_RegExpValid(cn);
        if (regvalid != NON_SXP) {
            SECStatus rv;
            /* cn is a regular expression, try to match the shexp */
            int match = PORT_RegExpCaseSearch(hn, cn);

            if (match == 0) {
                rv = SECSuccess;
            } else {
                PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
                rv = SECFailure;
            }
            return rv;
        }
    } else {
        /* New approach conforms to RFC 6125. */
        char *wildcard = PORT_Strchr(cn, '*');
        char *firstcndot = PORT_Strchr(cn, '.');
        char *secondcndot =
            firstcndot ? PORT_Strchr(firstcndot + 1, '.') : NULL;
        char *firsthndot = PORT_Strchr(hn, '.');

        /* For a cn pattern to be considered valid, the wildcard character...
         * - may occur only in a DNS name with at least 3 components, and
         * - may occur only as last character in the first component, and
         * - may be preceded by additional characters, and
         * - must not be preceded by an IDNA ACE prefix (xn--)
         */
        if (wildcard && secondcndot && secondcndot[1] && firsthndot &&
            firstcndot - wildcard == 1           /* wildcard is last char in first component */
            && secondcndot - firstcndot > 1      /* second component is non-empty */
            && PORT_Strrchr(cn, '*') == wildcard /* only one wildcard in cn */
            && !PORT_Strncasecmp(cn, hn, wildcard - cn) &&
            !PORT_Strcasecmp(firstcndot, firsthndot)
            /* If hn starts with xn--, then cn must start with wildcard */
            && (PORT_Strncasecmp(hn, "xn--", 4) || wildcard == cn)) {
            /* valid wildcard pattern match */
            return SECSuccess;
        }
    }
    /* String cn has no wildcard or shell expression.
     * Compare entire string hn with cert name.
     */
    if (PORT_Strcasecmp(hn, cn) == 0) {
        return SECSuccess;
    }

    PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
    return SECFailure;
}

SECStatus
cert_VerifySubjectAltName(const CERTCertificate *cert, const char *hn)
{
    PLArenaPool *arena = NULL;
    CERTGeneralName *nameList = NULL;
    CERTGeneralName *current;
    char *cn;
    int cnBufLen;
    int DNSextCount = 0;
    int IPextCount = 0;
    PRBool isIPaddr = PR_FALSE;
    SECStatus rv = SECFailure;
    SECItem subAltName;
    PRNetAddr netAddr;
    char cnbuf[128];

    subAltName.data = NULL;
    cn = cnbuf;
    cnBufLen = sizeof cnbuf;

    rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
                                &subAltName);
    if (rv != SECSuccess) {
        goto fail;
    }
    isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr));
    rv = SECFailure;
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena)
        goto fail;

    nameList = current = CERT_DecodeAltNameExtension(arena, &subAltName);
    if (!current)
        goto fail;

    do {
        switch (current->type) {
            case certDNSName:
                if (!isIPaddr) {
                    /* DNS name current->name.other.data is not null terminated.
                    ** so must copy it.
                    */
                    int cnLen = current->name.other.len;
                    rv = CERT_RFC1485_EscapeAndQuote(
                        cn, cnBufLen, (char *)current->name.other.data, cnLen);
                    if (rv != SECSuccess &&
                        PORT_GetError() == SEC_ERROR_OUTPUT_LEN) {
                        cnBufLen =
                            cnLen * 3 + 3; /* big enough for worst case */
                        cn = (char *)PORT_ArenaAlloc(arena, cnBufLen);
                        if (!cn)
                            goto fail;
                        rv = CERT_RFC1485_EscapeAndQuote(
                            cn, cnBufLen, (char *)current->name.other.data,
                            cnLen);
                    }
                    if (rv == SECSuccess)
                        rv = cert_TestHostName(cn, hn);
                    if (rv == SECSuccess)
                        goto finish;
                }
                DNSextCount++;
                break;
            case certIPAddress:
                if (isIPaddr) {
                    int match = 0;
                    PRIPv6Addr v6Addr;
                    if (current->name.other.len == 4 && /* IP v4 address */
                        netAddr.inet.family == PR_AF_INET) {
                        match = !memcmp(&netAddr.inet.ip,
                                        current->name.other.data, 4);
                    } else if (current->name.other.len ==
                                   16 && /* IP v6 address */
                               netAddr.ipv6.family == PR_AF_INET6) {
                        match = !memcmp(&netAddr.ipv6.ip,
                                        current->name.other.data, 16);
                    } else if (current->name.other.len ==
                                   16 && /* IP v6 address */
                               netAddr.inet.family == PR_AF_INET) {
                        /* convert netAddr to ipv6, then compare. */
                        /* ipv4 must be in Network Byte Order on input. */
                        PR_ConvertIPv4AddrToIPv6(netAddr.inet.ip, &v6Addr);
                        match = !memcmp(&v6Addr, current->name.other.data, 16);
                    } else if (current->name.other.len == 4 && /* IP v4 address */
                               netAddr.inet.family == PR_AF_INET6) {
                        /* convert netAddr to ipv6, then compare. */
                        PRUint32 ipv4 = (current->name.other.data[0] << 24) |
                                        (current->name.other.data[1] << 16) |
                                        (current->name.other.data[2] << 8) |
                                        current->name.other.data[3];
                        /* ipv4 must be in Network Byte Order on input. */
                        PR_ConvertIPv4AddrToIPv6(PR_htonl(ipv4), &v6Addr);
                        match = !memcmp(&netAddr.ipv6.ip, &v6Addr, 16);
                    }
                    if (match) {
                        rv = SECSuccess;
                        goto finish;
                    }
                }
                IPextCount++;
                break;
            default:
                break;
        }
        current = CERT_GetNextGeneralName(current);
    } while (current != nameList);

fail:

    if (!(isIPaddr ? IPextCount : DNSextCount)) {
        /* no relevant value in the extension was found. */
        PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
    } else {
        PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
    }
    rv = SECFailure;

finish:

    /* Don't free nameList, it's part of the arena. */
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    if (subAltName.data) {
        SECITEM_FreeItem(&subAltName, PR_FALSE);
    }

    return rv;
}

/*
 * If found:
 *   - subAltName contains the extension (caller must free)
 *   - return value is the decoded namelist (allocated off arena)
 * if not found, or if failure to decode:
 *   - return value is NULL
 */
CERTGeneralName *
cert_GetSubjectAltNameList(const CERTCertificate *cert, PLArenaPool *arena)
{
    CERTGeneralName *nameList = NULL;
    SECStatus rv = SECFailure;
    SECItem subAltName;

    if (!cert || !arena)
        return NULL;

    subAltName.data = NULL;

    rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
                                &subAltName);
    if (rv != SECSuccess)
        return NULL;

    nameList = CERT_DecodeAltNameExtension(arena, &subAltName);
    SECITEM_FreeItem(&subAltName, PR_FALSE);
    return nameList;
}

PRUint32
cert_CountDNSPatterns(CERTGeneralName *firstName)
{
    CERTGeneralName *current;
    PRUint32 count = 0;

    if (!firstName)
        return 0;

    current = firstName;
    do {
        switch (current->type) {
            case certDNSName:
            case certIPAddress:
                ++count;
                break;
            default:
                break;
        }
        current = CERT_GetNextGeneralName(current);
    } while (current != firstName);

    return count;
}

#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif

/* will fill nickNames,
 * will allocate all data from nickNames->arena,
 * numberOfGeneralNames should have been obtained from cert_CountDNSPatterns,
 * will ensure the numberOfGeneralNames matches the number of output entries.
 */
SECStatus
cert_GetDNSPatternsFromGeneralNames(CERTGeneralName *firstName,
                                    PRUint32 numberOfGeneralNames,
                                    CERTCertNicknames *nickNames)
{
    CERTGeneralName *currentInput;
    char **currentOutput;

    if (!firstName || !nickNames || !numberOfGeneralNames)
        return SECFailure;

    nickNames->numnicknames = numberOfGeneralNames;
    nickNames->nicknames = PORT_ArenaAlloc(
        nickNames->arena, sizeof(char *) * numberOfGeneralNames);
    if (!nickNames->nicknames)
        return SECFailure;

    currentInput = firstName;
    currentOutput = nickNames->nicknames;
    do {
        char *cn = NULL;
        char ipbuf[INET6_ADDRSTRLEN];
        PRNetAddr addr;

        if (numberOfGeneralNames < 1) {
            /* internal consistency error */
            return SECFailure;
        }

        switch (currentInput->type) {
            case certDNSName:
                /* DNS name currentInput->name.other.data is not null
                *terminated.
                ** so must copy it.
                */
                cn = (char *)PORT_ArenaAlloc(nickNames->arena,
                                             currentInput->name.other.len + 1);
                if (!cn)
                    return SECFailure;
                PORT_Memcpy(cn, currentInput->name.other.data,
                            currentInput->name.other.len);
                cn[currentInput->name.other.len] = 0;
                break;
            case certIPAddress:
                if (currentInput->name.other.len == 4) {
                    addr.inet.family = PR_AF_INET;
                    memcpy(&addr.inet.ip, currentInput->name.other.data,
                           currentInput->name.other.len);
                } else if (currentInput->name.other.len == 16) {
                    addr.ipv6.family = PR_AF_INET6;
                    memcpy(&addr.ipv6.ip, currentInput->name.other.data,
                           currentInput->name.other.len);
                }
                if (PR_NetAddrToString(&addr, ipbuf, sizeof(ipbuf)) ==
                    PR_FAILURE)
                    return SECFailure;
                cn = PORT_ArenaStrdup(nickNames->arena, ipbuf);
                if (!cn)
                    return SECFailure;
                break;
            default:
                break;
        }
        if (cn) {
            *currentOutput = cn;
            nickNames->totallen += PORT_Strlen(cn);
            ++currentOutput;
            --numberOfGeneralNames;
        }
        currentInput = CERT_GetNextGeneralName(currentInput);
    } while (currentInput != firstName);

    return (numberOfGeneralNames == 0) ? SECSuccess : SECFailure;
}

/*
 * Collect all valid DNS names from the given cert.
 * The output arena will reference some temporaray data,
 * but this saves us from dealing with two arenas.
 * The caller may free all data by freeing CERTCertNicknames->arena.
 */
CERTCertNicknames *
CERT_GetValidDNSPatternsFromCert(CERTCertificate *cert)
{
    CERTGeneralName *generalNames;
    CERTCertNicknames *nickNames;
    PLArenaPool *arena;
    char *singleName;

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

    nickNames = PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames));
    if (!nickNames) {
        PORT_FreeArena(arena, PR_FALSE);
        return NULL;
    }

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

    generalNames = cert_GetSubjectAltNameList(cert, arena);
    if (generalNames) {
        SECStatus rv_getnames = SECFailure;
        PRUint32 numNames = cert_CountDNSPatterns(generalNames);

        if (numNames) {
            rv_getnames = cert_GetDNSPatternsFromGeneralNames(
                generalNames, numNames, nickNames);
        }

        /* if there were names, we'll exit now, either with success or failure
         */
        if (numNames) {
            if (rv_getnames == SECSuccess) {
                return nickNames;
            }

            /* failure to produce output */
            PORT_FreeArena(arena, PR_FALSE);
            return NULL;
        }
    }

    /* no SAN extension or no names found in extension */
    singleName = CERT_GetCommonName(&cert->subject);
    if (singleName) {
        nickNames->numnicknames = 1;
        nickNames->nicknames = PORT_ArenaAlloc(arena, sizeof(char *));
        if (nickNames->nicknames) {
            *nickNames->nicknames = PORT_ArenaStrdup(arena, singleName);
        }
        PORT_Free(singleName);

        /* Did we allocate both the buffer of pointers and the string? */
        if (nickNames->nicknames && *nickNames->nicknames) {
            return nickNames;
        }
    }

    PORT_FreeArena(arena, PR_FALSE);
    return NULL;
}

/* Make sure that the name of the host we are connecting to matches the
 * name that is incoded in the common-name component of the certificate
 * that they are using.
 */
SECStatus
CERT_VerifyCertName(const CERTCertificate *cert, const char *hn)
{
    char *cn;
    SECStatus rv;
    CERTOKDomainName *domainOK;

    if (!hn || !strlen(hn)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* if the name is one that the user has already approved, it's OK. */
    for (domainOK = cert->domainOK; domainOK; domainOK = domainOK->next) {
        if (0 == PORT_Strcasecmp(hn, domainOK->name)) {
            return SECSuccess;
        }
    }

    /* Per RFC 2818, if the SubjectAltName extension is present, it must
    ** be used as the cert's identity.
    */
    rv = cert_VerifySubjectAltName(cert, hn);
    if (rv == SECSuccess || PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND)
        return rv;

    cn = CERT_GetCommonName(&cert->subject);
    if (cn) {
        PRBool isIPaddr = cert_IsIPAddr(hn);
        if (isIPaddr) {
            if (PORT_Strcasecmp(hn, cn) == 0) {
                rv = SECSuccess;
            } else {
                PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
                rv = SECFailure;
            }
        } else {
            rv = cert_TestHostName(cn, hn);
        }
        PORT_Free(cn);
    } else
        PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
    return rv;
}

PRBool
CERT_CompareCerts(const CERTCertificate *c1, const CERTCertificate *c2)
{
    SECComparison comp;

    comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert);
    if (comp == SECEqual) { /* certs are the same */
        return (PR_TRUE);
    } else {
        return (PR_FALSE);
    }
}

static SECStatus
StringsEqual(char *s1, char *s2)
{
    if ((s1 == NULL) || (s2 == NULL)) {
        if (s1 != s2) { /* only one is null */
            return (SECFailure);
        }
        return (SECSuccess); /* both are null */
    }

    if (PORT_Strcmp(s1, s2) != 0) {
        return (SECFailure); /* not equal */
    }

    return (SECSuccess); /* strings are equal */
}

PRBool
CERT_CompareCertsForRedirection(CERTCertificate *c1, CERTCertificate *c2)
{
    SECComparison comp;
    char *c1str, *c2str;
    SECStatus eq;

    comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert);
    if (comp == SECEqual) { /* certs are the same */
        return (PR_TRUE);
    }

    /* check if they are issued by the same CA */
    comp = SECITEM_CompareItem(&c1->derIssuer, &c2->derIssuer);
    if (comp != SECEqual) { /* different issuer */
        return (PR_FALSE);
    }

    /* check country name */
    c1str = CERT_GetCountryName(&c1->subject);
    c2str = CERT_GetCountryName(&c2->subject);
    eq = StringsEqual(c1str, c2str);
    PORT_Free(c1str);
    PORT_Free(c2str);
    if (eq != SECSuccess) {
        return (PR_FALSE);
    }

    /* check locality name */
    c1str = CERT_GetLocalityName(&c1->subject);
    c2str = CERT_GetLocalityName(&c2->subject);
    eq = StringsEqual(c1str, c2str);
    PORT_Free(c1str);
    PORT_Free(c2str);
    if (eq != SECSuccess) {
        return (PR_FALSE);
    }

    /* check state name */
    c1str = CERT_GetStateName(&c1->subject);
    c2str = CERT_GetStateName(&c2->subject);
    eq = StringsEqual(c1str, c2str);
    PORT_Free(c1str);
    PORT_Free(c2str);
    if (eq != SECSuccess) {
        return (PR_FALSE);
    }

    /* check org name */
    c1str = CERT_GetOrgName(&c1->subject);
    c2str = CERT_GetOrgName(&c2->subject);
    eq = StringsEqual(c1str, c2str);
    PORT_Free(c1str);
    PORT_Free(c2str);
    if (eq != SECSuccess) {
        return (PR_FALSE);
    }

#ifdef NOTDEF
    /* check orgUnit name */
    /*
     * We need to revisit this and decide which fields should be allowed to be
     * different
     */
    c1str = CERT_GetOrgUnitName(&c1->subject);
    c2str = CERT_GetOrgUnitName(&c2->subject);
    eq = StringsEqual(c1str, c2str);
    PORT_Free(c1str);
    PORT_Free(c2str);
    if (eq != SECSuccess) {
        return (PR_FALSE);
    }
#endif

    return (PR_TRUE); /* all fields but common name are the same */
}

/* CERT_CertChainFromCert and CERT_DestroyCertificateList moved
   to certhigh.c */

CERTIssuerAndSN *
CERT_GetCertIssuerAndSN(PLArenaPool *arena, CERTCertificate *cert)
{
    CERTIssuerAndSN *result;
    SECStatus rv;

    if (arena == NULL) {
        arena = cert->arena;
    }

    result = (CERTIssuerAndSN *)PORT_ArenaZAlloc(arena, sizeof(*result));
    if (result == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    rv = SECITEM_CopyItem(arena, &result->derIssuer, &cert->derIssuer);
    if (rv != SECSuccess)
        return NULL;

    rv = CERT_CopyName(arena, &result->issuer, &cert->issuer);
    if (rv != SECSuccess)
        return NULL;

    rv = SECITEM_CopyItem(arena, &result->serialNumber, &cert->serialNumber);
    if (rv != SECSuccess)
        return NULL;

    return result;
}

char *
CERT_MakeCANickname(CERTCertificate *cert)
{
    char *firstname = NULL;
    char *org = NULL;
    char *nickname = NULL;
    int count;
    CERTCertificate *dummycert;

    firstname = CERT_GetCommonName(&cert->subject);
    if (firstname == NULL) {
        firstname = CERT_GetOrgUnitName(&cert->subject);
    }

    org = CERT_GetOrgName(&cert->issuer);
    if (org == NULL) {
        org = CERT_GetDomainComponentName(&cert->issuer);
        if (org == NULL) {
            if (firstname) {
                org = firstname;
                firstname = NULL;
            } else {
                org = PORT_Strdup("Unknown CA");
            }
        }
    }

    /* can only fail if PORT_Strdup fails, in which case
     * we're having memory problems. */
    if (org == NULL) {
        goto done;
    }

    count = 1;
    while (1) {

        if (firstname) {
            if (count == 1) {
                nickname = PR_smprintf("%s - %s", firstname, org);
            } else {
                nickname = PR_smprintf("%s - %s #%d", firstname, org, count);
            }
        } else {
            if (count == 1) {
                nickname = PR_smprintf("%s", org);
            } else {
                nickname = PR_smprintf("%s #%d", org, count);
            }
        }
        if (nickname == NULL) {
            goto done;
        }

        /* look up the nickname to make sure it isn't in use already */
        dummycert = CERT_FindCertByNickname(cert->dbhandle, nickname);

        if (dummycert == NULL) {
            goto done;
        }

        /* found a cert, destroy it and loop */
        CERT_DestroyCertificate(dummycert);

        /* free the nickname */
        PORT_Free(nickname);

        count++;
    }

done:
    if (firstname) {
        PORT_Free(firstname);
    }
    if (org) {
        PORT_Free(org);
    }

    return (nickname);
}

/* CERT_Import_CAChain moved to certhigh.c */

void
CERT_DestroyCrl(CERTSignedCrl *crl)
{
    SEC_DestroyCrl(crl);
}

static int
cert_Version(CERTCertificate *cert)
{
    int version = 0;
    if (cert && cert->version.data && cert->version.len) {
        version = DER_GetInteger(&cert->version);
        if (version < 0)
            version = 0;
    }
    return version;
}

static unsigned int
cert_ComputeTrustOverrides(CERTCertificate *cert, unsigned int cType)
{
    CERTCertTrust trust;
    SECStatus rv = SECFailure;

    rv = CERT_GetCertTrust(cert, &trust);

    if (rv == SECSuccess &&
        (trust.sslFlags | trust.emailFlags | trust.objectSigningFlags)) {

        if (trust.sslFlags & (CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED))
            cType |= NS_CERT_TYPE_SSL_SERVER | NS_CERT_TYPE_SSL_CLIENT;
        if (trust.sslFlags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA))
            cType |= NS_CERT_TYPE_SSL_CA;
#if defined(CERTDB_NOT_TRUSTED)
        if (trust.sslFlags & CERTDB_NOT_TRUSTED)
            cType &= ~(NS_CERT_TYPE_SSL_SERVER | NS_CERT_TYPE_SSL_CLIENT |
                       NS_CERT_TYPE_SSL_CA);
#endif
        if (trust.emailFlags & (CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED))
            cType |= NS_CERT_TYPE_EMAIL;
        if (trust.emailFlags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA))
            cType |= NS_CERT_TYPE_EMAIL_CA;
#if defined(CERTDB_NOT_TRUSTED)
        if (trust.emailFlags & CERTDB_NOT_TRUSTED)
            cType &= ~(NS_CERT_TYPE_EMAIL | NS_CERT_TYPE_EMAIL_CA);
#endif
        if (trust.objectSigningFlags &
            (CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED))
            cType |= NS_CERT_TYPE_OBJECT_SIGNING;
        if (trust.objectSigningFlags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA))
            cType |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
#if defined(CERTDB_NOT_TRUSTED)
        if (trust.objectSigningFlags & CERTDB_NOT_TRUSTED)
            cType &=
                ~(NS_CERT_TYPE_OBJECT_SIGNING | NS_CERT_TYPE_OBJECT_SIGNING_CA);
#endif
    }
    return cType;
}

/*
 * Does a cert belong to a CA?  We decide based on perm database trust
 * flags, Netscape Cert Type Extension, and KeyUsage Extension.
 */
PRBool
CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype)
{
    unsigned int cType = cert->nsCertType;
    PRBool ret = PR_FALSE;

    if (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
                 NS_CERT_TYPE_OBJECT_SIGNING_CA)) {
        ret = PR_TRUE;
    } else {
        SECStatus rv;
        CERTBasicConstraints constraints;

        rv = CERT_FindBasicConstraintExten(cert, &constraints);
        if (rv == SECSuccess && constraints.isCA) {
            ret = PR_TRUE;
            cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
        }
    }

    /* finally check if it's an X.509 v1 root CA */
    if (!ret &&
        (cert->isRoot && cert_Version(cert) < SEC_CERTIFICATE_VERSION_3)) {
        ret = PR_TRUE;
        cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
    }
    /* Now apply trust overrides, if any */
    cType = cert_ComputeTrustOverrides(cert, cType);
    ret = (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
                    NS_CERT_TYPE_OBJECT_SIGNING_CA))
              ? PR_TRUE
              : PR_FALSE;

    if (rettype != NULL) {
        *rettype = cType;
    }
    return ret;
}

PRBool
CERT_IsCADERCert(SECItem *derCert, unsigned int *type)
{
    CERTCertificate *cert;
    PRBool isCA;

    /* This is okay -- only looks at extensions */
    cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
    if (cert == NULL)
        return PR_FALSE;

    isCA = CERT_IsCACert(cert, type);
    CERT_DestroyCertificate(cert);
    return isCA;
}

PRBool
CERT_IsRootDERCert(SECItem *derCert)
{
    CERTCertificate *cert;
    PRBool isRoot;

    /* This is okay -- only looks at extensions */
    cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
    if (cert == NULL)
        return PR_FALSE;

    isRoot = cert->isRoot;
    CERT_DestroyCertificate(cert);
    return isRoot;
}

CERTCompareValidityStatus
CERT_CompareValidityTimes(CERTValidity *val_a, CERTValidity *val_b)
{
    PRTime notBeforeA, notBeforeB, notAfterA, notAfterB;

    if (!val_a || !val_b) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return certValidityUndetermined;
    }

    if (SECSuccess != DER_DecodeTimeChoice(&notBeforeA, &val_a->notBefore) ||
        SECSuccess != DER_DecodeTimeChoice(&notBeforeB, &val_b->notBefore) ||
        SECSuccess != DER_DecodeTimeChoice(&notAfterA, &val_a->notAfter) ||
        SECSuccess != DER_DecodeTimeChoice(&notAfterB, &val_b->notAfter)) {
        return certValidityUndetermined;
    }

    /* sanity check */
    if (LL_CMP(notBeforeA, >, notAfterA) || LL_CMP(notBeforeB, >, notAfterB)) {
        PORT_SetError(SEC_ERROR_INVALID_TIME);
        return certValidityUndetermined;
    }

    if (LL_CMP(notAfterA, !=, notAfterB)) {
        /* one cert validity goes farther into the future, select it */
        return LL_CMP(notAfterA, <, notAfterB) ? certValidityChooseB
                                               : certValidityChooseA;
    }
    /* the two certs have the same expiration date */
    PORT_Assert(LL_CMP(notAfterA, ==, notAfterB));
    /* do they also have the same start date ? */
    if (LL_CMP(notBeforeA, ==, notBeforeB)) {
        return certValidityEqual;
    }
    /* choose cert with the later start date */
    return LL_CMP(notBeforeA, <, notBeforeB) ? certValidityChooseB
                                             : certValidityChooseA;
}

/*
 * is certa newer than certb?  If one is expired, pick the other one.
 */
PRBool
CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb)
{
    PRTime notBeforeA, notAfterA, notBeforeB, notAfterB, now;
    SECStatus rv;
    PRBool newerbefore, newerafter;

    rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
    if (rv != SECSuccess) {
        return (PR_FALSE);
    }

    rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
    if (rv != SECSuccess) {
        return (PR_TRUE);
    }

    newerbefore = PR_FALSE;
    if (LL_CMP(notBeforeA, >, notBeforeB)) {
        newerbefore = PR_TRUE;
    }

    newerafter = PR_FALSE;
    if (LL_CMP(notAfterA, >, notAfterB)) {
        newerafter = PR_TRUE;
    }

    if (newerbefore && newerafter) {
        return (PR_TRUE);
    }

    if ((!newerbefore) && (!newerafter)) {
        return (PR_FALSE);
    }

    /* get current time */
    now = PR_Now();

    if (newerbefore) {
        /* cert A was issued after cert B, but expires sooner */
        /* if A is expired, then pick B */
        if (LL_CMP(notAfterA, <, now)) {
            return (PR_FALSE);
        }
        return (PR_TRUE);
    } else {
        /* cert B was issued after cert A, but expires sooner */
        /* if B is expired, then pick A */
        if (LL_CMP(notAfterB, <, now)) {
            return (PR_TRUE);
        }
        return (PR_FALSE);
    }
}

void
CERT_DestroyCertArray(CERTCertificate **certs, unsigned int ncerts)
{
    unsigned int i;

    if (certs) {
        for (i = 0; i < ncerts; i++) {
            if (certs[i]) {
                CERT_DestroyCertificate(certs[i]);
            }
        }

        PORT_Free(certs);
    }

    return;
}

char *
CERT_FixupEmailAddr(const char *emailAddr)
{
    char *retaddr;
    char *str;

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

    /* copy the string */
    str = retaddr = PORT_Strdup(emailAddr);
    if (str == NULL) {
        return (NULL);
    }

    /* make it lower case */
    while (*str) {
        *str = tolower(*str);
        str++;
    }

    return (retaddr);
}

/*
 * NOTE - don't allow encode of govt-approved or invisible bits
 */
SECStatus
CERT_DecodeTrustString(CERTCertTrust *trust, const char *trusts)
{
    unsigned int i;
    unsigned int *pflags;

    if (!trust) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    trust->sslFlags = 0;
    trust->emailFlags = 0;
    trust->objectSigningFlags = 0;
    if (!trusts) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    pflags = &trust->sslFlags;

    for (i = 0; i < PORT_Strlen(trusts); i++) {
        switch (trusts[i]) {
            case 'p':
                *pflags = *pflags | CERTDB_TERMINAL_RECORD;
                break;

            case 'P':
                *pflags = *pflags | CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD;
                break;

            case 'w':
                *pflags = *pflags | CERTDB_SEND_WARN;
                break;

            case 'c':
                *pflags = *pflags | CERTDB_VALID_CA;
                break;

            case 'T':
                *pflags = *pflags | CERTDB_TRUSTED_CLIENT_CA | CERTDB_VALID_CA;
                break;

            case 'C':
                *pflags = *pflags | CERTDB_TRUSTED_CA | CERTDB_VALID_CA;
                break;

            case 'u':
                *pflags = *pflags | CERTDB_USER;
                break;

            case 'i':
                *pflags = *pflags | CERTDB_INVISIBLE_CA;
                break;
            case 'g':
                *pflags = *pflags | CERTDB_GOVT_APPROVED_CA;
                break;

            case ',':
                if (pflags == &trust->sslFlags) {
                    pflags = &trust->emailFlags;
                } else {
                    pflags = &trust->objectSigningFlags;
                }
                break;
            default:
                PORT_SetError(SEC_ERROR_INVALID_ARGS);
                return SECFailure;
        }
    }

    return SECSuccess;
}

static void
EncodeFlags(char *trusts, unsigned int flags)
{
    if (flags & CERTDB_VALID_CA)
        if (!(flags & CERTDB_TRUSTED_CA) && !(flags & CERTDB_TRUSTED_CLIENT_CA))
            PORT_Strcat(trusts, "c");
    if (flags & CERTDB_TERMINAL_RECORD)
        if (!(flags & CERTDB_TRUSTED))
            PORT_Strcat(trusts, "p");
    if (flags & CERTDB_TRUSTED_CA)
        PORT_Strcat(trusts, "C");
    if (flags & CERTDB_TRUSTED_CLIENT_CA)
        PORT_Strcat(trusts, "T");
    if (flags & CERTDB_TRUSTED)
        PORT_Strcat(trusts, "P");
    if (flags & CERTDB_USER)
        PORT_Strcat(trusts, "u");
    if (flags & CERTDB_SEND_WARN)
        PORT_Strcat(trusts, "w");
    if (flags & CERTDB_INVISIBLE_CA)
        PORT_Strcat(trusts, "I");
    if (flags & CERTDB_GOVT_APPROVED_CA)
        PORT_Strcat(trusts, "G");
    return;
}

char *
CERT_EncodeTrustString(CERTCertTrust *trust)
{
    char tmpTrustSSL[32];
    char tmpTrustEmail[32];
    char tmpTrustSigning[32];
    char *retstr = NULL;

    if (trust) {
        tmpTrustSSL[0] = '\0';
        tmpTrustEmail[0] = '\0';
        tmpTrustSigning[0] = '\0';

        EncodeFlags(tmpTrustSSL, trust->sslFlags);
        EncodeFlags(tmpTrustEmail, trust->emailFlags);
        EncodeFlags(tmpTrustSigning, trust->objectSigningFlags);

        retstr = PR_smprintf("%s,%s,%s", tmpTrustSSL, tmpTrustEmail,
                             tmpTrustSigning);
    }

    return (retstr);
}

SECStatus
CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage,
                 unsigned int ncerts, SECItem **derCerts,
                 CERTCertificate ***retCerts, PRBool keepCerts, PRBool caOnly,
                 char *nickname)
{
    unsigned int i;
    CERTCertificate **certs = NULL;
    unsigned int fcerts = 0;

    if (ncerts) {
        certs = PORT_ZNewArray(CERTCertificate *, ncerts);
        if (certs == NULL) {
            return (SECFailure);
        }

        /* decode all of the certs into the temporary DB */
        for (i = 0, fcerts = 0; i < ncerts; i++) {
            certs[fcerts] = CERT_NewTempCertificate(certdb, derCerts[i], NULL,
                                                    PR_FALSE, PR_TRUE);
            if (certs[fcerts]) {
                SECItem subjKeyID = { siBuffer, NULL, 0 };
                if (CERT_FindSubjectKeyIDExtension(certs[fcerts], &subjKeyID) ==
                    SECSuccess) {
                    if (subjKeyID.data) {
                        cert_AddSubjectKeyIDMapping(&subjKeyID, certs[fcerts]);
                    }
                    SECITEM_FreeItem(&subjKeyID, PR_FALSE);
                }
                fcerts++;
            }
        }

        if (keepCerts) {
            for (i = 0; i < fcerts; i++) {
                char *canickname = NULL;
                PRBool isCA;

                SECKEY_UpdateCertPQG(certs[i]);

                isCA = CERT_IsCACert(certs[i], NULL);
                if (isCA) {
                    canickname = CERT_MakeCANickname(certs[i]);
                }

                if (isCA && (fcerts > 1)) {
                    /* if we are importing only a single cert and specifying
                     * a nickname, we want to use that nickname if it a CA,
                     * otherwise if there are more than one cert, we don't
                     * know which cert it belongs to. But we still may try
                     * the individual canickname from the cert itself.
                     */
                    /* Bug 1192442 - propagate errors from these calls. */
                    (void)CERT_AddTempCertToPerm(certs[i], canickname, NULL);
                } else {
                    (void)CERT_AddTempCertToPerm(
                        certs[i], nickname ? nickname : canickname, NULL);
                }

                PORT_Free(canickname);
                /* don't care if it fails - keep going */
            }
        }
    }

    if (retCerts) {
        *retCerts = certs;
    } else {
        if (certs) {
            CERT_DestroyCertArray(certs, fcerts);
        }
    }

    return (fcerts || !ncerts) ? SECSuccess : SECFailure;
}

/*
 * a real list of certificates - need to convert CERTCertificateList
 * stuff and ASN 1 encoder/decoder over to using this...
 */
CERTCertList *
CERT_NewCertList(void)
{
    PLArenaPool *arena = NULL;
    CERTCertList *ret = NULL;

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

    ret = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
    if (ret == NULL) {
        goto loser;
    }

    ret->arena = arena;

    PR_INIT_CLIST(&ret->list);

    return (ret);

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

    return (NULL);
}

void
CERT_DestroyCertList(CERTCertList *certs)
{
    PRCList *node;

    while (!PR_CLIST_IS_EMPTY(&certs->list)) {
        node = PR_LIST_HEAD(&certs->list);
        CERT_DestroyCertificate(((CERTCertListNode *)node)->cert);
        PR_REMOVE_LINK(node);
    }

    PORT_FreeArena(certs->arena, PR_FALSE);

    return;
}

void
CERT_RemoveCertListNode(CERTCertListNode *node)
{
    CERT_DestroyCertificate(node->cert);
    PR_REMOVE_LINK(&node->links);
    return;
}

SECStatus
CERT_AddCertToListTailWithData(CERTCertList *certs, CERTCertificate *cert,
                               void *appData)
{
    CERTCertListNode *node;

    node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
                                                sizeof(CERTCertListNode));
    if (node == NULL) {
        goto loser;
    }

    PR_INSERT_BEFORE(&node->links, &certs->list);
    /* certs->count++; */
    node->cert = cert;
    node->appData = appData;
    return (SECSuccess);

loser:
    return (SECFailure);
}

SECStatus
CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert)
{
    return CERT_AddCertToListTailWithData(certs, cert, NULL);
}

SECStatus
CERT_AddCertToListHeadWithData(CERTCertList *certs, CERTCertificate *cert,
                               void *appData)
{
    CERTCertListNode *node;
    CERTCertListNode *head;

    head = CERT_LIST_HEAD(certs);

    if (head == NULL)
        return CERT_AddCertToListTail(certs, cert);

    node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
                                                sizeof(CERTCertListNode));
    if (node == NULL) {
        goto loser;
    }

    PR_INSERT_BEFORE(&node->links, &head->links);
    /* certs->count++; */
    node->cert = cert;
    node->appData = appData;
    return (SECSuccess);

loser:
    return (SECFailure);
}

SECStatus
CERT_AddCertToListHead(CERTCertList *certs, CERTCertificate *cert)
{
    return CERT_AddCertToListHeadWithData(certs, cert, NULL);
}

/*
 * Sort callback function to determine if cert a is newer than cert b.
 * Not valid certs are considered older than valid certs.
 */
PRBool
CERT_SortCBValidity(CERTCertificate *certa, CERTCertificate *certb, void *arg)
{
    PRTime sorttime;
    PRTime notBeforeA, notAfterA, notBeforeB, notAfterB;
    SECStatus rv;
    PRBool newerbefore, newerafter;
    PRBool aNotValid = PR_FALSE, bNotValid = PR_FALSE;

    sorttime = *(PRTime *)arg;

    rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
    if (rv != SECSuccess) {
        return (PR_FALSE);
    }

    rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
    if (rv != SECSuccess) {
        return (PR_TRUE);
    }
    newerbefore = PR_FALSE;
    if (LL_CMP(notBeforeA, >, notBeforeB)) {
        newerbefore = PR_TRUE;
    }
    newerafter = PR_FALSE;
    if (LL_CMP(notAfterA, >, notAfterB)) {
        newerafter = PR_TRUE;
    }

    /* check if A is valid at sorttime */
    if (CERT_CheckCertValidTimes(certa, sorttime, PR_FALSE) !=
        secCertTimeValid) {
        aNotValid = PR_TRUE;
    }

    /* check if B is valid at sorttime */
    if (CERT_CheckCertValidTimes(certb, sorttime, PR_FALSE) !=
        secCertTimeValid) {
        bNotValid = PR_TRUE;
    }

    /* a is valid, b is not */
    if (bNotValid && (!aNotValid)) {
        return (PR_TRUE);
    }

    /* b is valid, a is not */
    if (aNotValid && (!bNotValid)) {
        return (PR_FALSE);
    }

    /* a and b are either valid or not valid */
    if (newerbefore && newerafter) {
        return (PR_TRUE);
    }

    if ((!newerbefore) && (!newerafter)) {
        return (PR_FALSE);
    }

    if (newerbefore) {
        /* cert A was issued after cert B, but expires sooner */
        return (PR_TRUE);
    } else {
        /* cert B was issued after cert A, but expires sooner */
        return (PR_FALSE);
    }
}

SECStatus
CERT_AddCertToListSorted(CERTCertList *certs, CERTCertificate *cert,
                         CERTSortCallback f, void *arg)
{
    CERTCertListNode *node;
    CERTCertListNode *head;
    PRBool ret;

    node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
                                                sizeof(CERTCertListNode));
    if (node == NULL) {
        goto loser;
    }

    head = CERT_LIST_HEAD(certs);

    while (!CERT_LIST_END(head, certs)) {

        /* if cert is already in the list, then don't add it again */
        if (cert == head->cert) {
            /*XXX*/
            /* don't keep a reference */
            CERT_DestroyCertificate(cert);
            goto done;
        }

        ret = (*f)(cert, head->cert, arg);
        /* if sort function succeeds, then insert before current node */
        if (ret) {
            PR_INSERT_BEFORE(&node->links, &head->links);
            goto done;
        }

        head = CERT_LIST_NEXT(head);
    }
    /* if we get to the end, then just insert it at the tail */
    PR_INSERT_BEFORE(&node->links, &certs->list);

done:
    /* certs->count++; */
    node->cert = cert;
    return (SECSuccess);

loser:
    return (SECFailure);
}

/* This routine is here because pcertdb.c still has a call to it.
 * The SMIME profile code in pcertdb.c should be split into high (find
 * the email cert) and low (store the profile) code.  At that point, we
 * can move this to certhigh.c where it belongs.
 *
 * remove certs from a list that don't have keyUsage and certType
 * that match the given usage.
 */
SECStatus
CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage,
                           PRBool ca)
{
    unsigned int requiredKeyUsage;
    unsigned int requiredCertType;
    CERTCertListNode *node, *savenode;
    SECStatus rv;

    if (certList == NULL)
        goto loser;

    rv = CERT_KeyUsageAndTypeForCertUsage(usage, ca, &requiredKeyUsage,
                                          &requiredCertType);
    if (rv != SECSuccess) {
        goto loser;
    }

    node = CERT_LIST_HEAD(certList);

    while (!CERT_LIST_END(node, certList)) {

        PRBool bad = (PRBool)(!node->cert);

        /* bad key usage ? */
        if (!bad &&
            CERT_CheckKeyUsage(node->cert, requiredKeyUsage) != SECSuccess) {
            bad = PR_TRUE;
        }
        /* bad cert type ? */
        if (!bad) {
            unsigned int certType = 0;
            if (ca) {
                /* This function returns a more comprehensive cert type that
                 * takes trust flags into consideration.  Should probably
                 * fix the cert decoding code to do this.
                 */
                (void)CERT_IsCACert(node->cert, &certType);
            } else {
                certType = node->cert->nsCertType;
            }
            if (!(certType & requiredCertType)) {
                bad = PR_TRUE;
            }
        }

        if (bad) {
            /* remove the node if it is bad */
            savenode = CERT_LIST_NEXT(node);
            CERT_RemoveCertListNode(node);
            node = savenode;
        } else {
            node = CERT_LIST_NEXT(node);
        }
    }
    return (SECSuccess);

loser:
    return (SECFailure);
}

PRBool
CERT_IsUserCert(CERTCertificate *cert)
{
    CERTCertTrust trust;
    SECStatus rv = SECFailure;

    rv = CERT_GetCertTrust(cert, &trust);
    if (rv == SECSuccess &&
        ((trust.sslFlags & CERTDB_USER) || (trust.emailFlags & CERTDB_USER) ||
         (trust.objectSigningFlags & CERTDB_USER))) {
        return PR_TRUE;
    } else {
        return PR_FALSE;
    }
}

SECStatus
CERT_FilterCertListForUserCerts(CERTCertList *certList)
{
    CERTCertListNode *node, *freenode;
    CERTCertificate *cert;

    if (!certList) {
        return SECFailure;
    }

    node = CERT_LIST_HEAD(certList);

    while (!CERT_LIST_END(node, certList)) {
        cert = node->cert;
        if (PR_TRUE != CERT_IsUserCert(cert)) {
            /* Not a User Cert, so remove this cert from the list */
            freenode = node;
            node = CERT_LIST_NEXT(node);
            CERT_RemoveCertListNode(freenode);
        } else {
            /* Is a User cert, so leave it in the list */
            node = CERT_LIST_NEXT(node);
        }
    }

    return (SECSuccess);
}

static PZLock *certRefCountLock = NULL;

/*
 * Acquire the cert reference count lock
 * There is currently one global lock for all certs, but I'm putting a cert
 * arg here so that it will be easy to make it per-cert in the future if
 * that turns out to be necessary.
 */
void
CERT_LockCertRefCount(CERTCertificate *cert)
{
    PORT_Assert(certRefCountLock != NULL);
    PZ_Lock(certRefCountLock);
    return;
}

/*
 * Free the cert reference count lock
 */
void
CERT_UnlockCertRefCount(CERTCertificate *cert)
{
    PORT_Assert(certRefCountLock != NULL);

#ifdef DEBUG
    {
        PRStatus prstat = PZ_Unlock(certRefCountLock);
        PORT_Assert(prstat == PR_SUCCESS);
    }
#else
    PZ_Unlock(certRefCountLock);
#endif
}

static PZLock *certTrustLock = NULL;

/*
 * Acquire the cert trust lock
 * There is currently one global lock for all certs, but I'm putting a cert
 * arg here so that it will be easy to make it per-cert in the future if
 * that turns out to be necessary.
 */
void
CERT_LockCertTrust(const CERTCertificate *cert)
{
    PORT_Assert(certTrustLock != NULL);
    PZ_Lock(certTrustLock);
    return;
}

SECStatus
cert_InitLocks(void)
{
    if (certRefCountLock == NULL) {
        certRefCountLock = PZ_NewLock(nssILockRefLock);
        PORT_Assert(certRefCountLock != NULL);
        if (!certRefCountLock) {
            return SECFailure;
        }
    }

    if (certTrustLock == NULL) {
        certTrustLock = PZ_NewLock(nssILockCertDB);
        PORT_Assert(certTrustLock != NULL);
        if (!certTrustLock) {
            PZ_DestroyLock(certRefCountLock);
            certRefCountLock = NULL;
            return SECFailure;
        }
    }

    return SECSuccess;
}

SECStatus
cert_DestroyLocks(void)
{
    SECStatus rv = SECSuccess;

    PORT_Assert(certRefCountLock != NULL);
    if (certRefCountLock) {
        PZ_DestroyLock(certRefCountLock);
        certRefCountLock = NULL;
    } else {
        rv = SECFailure;
    }

    PORT_Assert(certTrustLock != NULL);
    if (certTrustLock) {
        PZ_DestroyLock(certTrustLock);
        certTrustLock = NULL;
    } else {
        rv = SECFailure;
    }
    return rv;
}

/*
 * Free the cert trust lock
 */
void
CERT_UnlockCertTrust(const CERTCertificate *cert)
{
    PORT_Assert(certTrustLock != NULL);

#ifdef DEBUG
    {
        PRStatus prstat = PZ_Unlock(certTrustLock);
        PORT_Assert(prstat == PR_SUCCESS);
    }
#else
    PZ_Unlock(certTrustLock);
#endif
}

/*
 * Get the StatusConfig data for this handle
 */
CERTStatusConfig *
CERT_GetStatusConfig(CERTCertDBHandle *handle)
{
    return handle->statusConfig;
}

/*
 * Set the StatusConfig data for this handle.  There
 * should not be another configuration set.
 */
void
CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *statusConfig)
{
    PORT_Assert(handle->statusConfig == NULL);
    handle->statusConfig = statusConfig;
}

/*
 * Code for dealing with subjKeyID to cert mappings.
 */

static PLHashTable *gSubjKeyIDHash = NULL;
static PRLock *gSubjKeyIDLock = NULL;
static PLHashTable *gSubjKeyIDSlotCheckHash = NULL;
static PRLock *gSubjKeyIDSlotCheckLock = NULL;

static void *
cert_AllocTable(void *pool, PRSize size)
{
    return PORT_Alloc(size);
}

static void
cert_FreeTable(void *pool, void *item)
{
    PORT_Free(item);
}

static PLHashEntry *
cert_AllocEntry(void *pool, const void *key)
{
    return PORT_New(PLHashEntry);
}

static void
cert_FreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
{
    SECITEM_FreeItem((SECItem *)(he->value), PR_TRUE);
    if (flag == HT_FREE_ENTRY) {
        SECITEM_FreeItem((SECItem *)(he->key), PR_TRUE);
        PORT_Free(he);
    }
}

static PLHashAllocOps cert_AllocOps = { cert_AllocTable, cert_FreeTable,
                                        cert_AllocEntry, cert_FreeEntry };

SECStatus
cert_CreateSubjectKeyIDSlotCheckHash(void)
{
    /*
     * This hash is used to remember the series of a slot
     * when we last checked for user certs
     */
    gSubjKeyIDSlotCheckHash =
        PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
                        SECITEM_HashCompare, &cert_AllocOps, NULL);
    if (!gSubjKeyIDSlotCheckHash) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }
    gSubjKeyIDSlotCheckLock = PR_NewLock();
    if (!gSubjKeyIDSlotCheckLock) {
        PL_HashTableDestroy(gSubjKeyIDSlotCheckHash);
        gSubjKeyIDSlotCheckHash = NULL;
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus
cert_CreateSubjectKeyIDHashTable(void)
{
    gSubjKeyIDHash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
                                     SECITEM_HashCompare, &cert_AllocOps, NULL);
    if (!gSubjKeyIDHash) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }
    gSubjKeyIDLock = PR_NewLock();
    if (!gSubjKeyIDLock) {
        PL_HashTableDestroy(gSubjKeyIDHash);
        gSubjKeyIDHash = NULL;
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }
    /* initialize the companion hash (for remembering slot series) */
    if (cert_CreateSubjectKeyIDSlotCheckHash() != SECSuccess) {
        cert_DestroySubjectKeyIDHashTable();
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus
cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert)
{
    SECItem *newKeyID, *oldVal, *newVal;
    SECStatus rv = SECFailure;

    if (!gSubjKeyIDLock) {
        /* If one is created, then both are there.  So only check for one. */
        return SECFailure;
    }

    newVal = SECITEM_DupItem(&cert->derCert);
    if (!newVal) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto done;
    }
    newKeyID = SECITEM_DupItem(subjKeyID);
    if (!newKeyID) {
        SECITEM_FreeItem(newVal, PR_TRUE);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto done;
    }

    PR_Lock(gSubjKeyIDLock);
    /* The hash table implementation does not free up the memory
     * associated with the key of an already existing entry if we add a
     * duplicate, so we would wind up leaking the previously allocated
     * key if we don't remove before adding.
     */
    oldVal = (SECItem *)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID);
    if (oldVal) {
        PL_HashTableRemove(gSubjKeyIDHash, subjKeyID);
    }

    rv = (PL_HashTableAdd(gSubjKeyIDHash, newKeyID, newVal)) ? SECSuccess
                                                             : SECFailure;
    PR_Unlock(gSubjKeyIDLock);
done:
    return rv;
}

SECStatus
cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID)
{
    SECStatus rv;
    if (!gSubjKeyIDLock)
        return SECFailure;

    PR_Lock(gSubjKeyIDLock);
    rv = (PL_HashTableRemove(gSubjKeyIDHash, subjKeyID)) ? SECSuccess
                                                         : SECFailure;
    PR_Unlock(gSubjKeyIDLock);
    return rv;
}

SECStatus
cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series)
{
    SECItem *oldSeries, *newSlotid, *newSeries;
    SECStatus rv = SECFailure;

    if (!gSubjKeyIDSlotCheckLock) {
        return rv;
    }

    newSlotid = SECITEM_DupItem(slotid);
    newSeries = SECITEM_AllocItem(NULL, NULL, sizeof(int));
    if (!newSlotid || !newSeries) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    PORT_Memcpy(newSeries->data, &series, sizeof(int));

    PR_Lock(gSubjKeyIDSlotCheckLock);
    oldSeries = (SECItem *)PL_HashTableLookup(gSubjKeyIDSlotCheckHash, slotid);
    if (oldSeries) {
        /*
         * make sure we don't leak the key of an existing entry
         * (similar to cert_AddSubjectKeyIDMapping, see comment there)
         */
        PL_HashTableRemove(gSubjKeyIDSlotCheckHash, slotid);
    }
    rv = (PL_HashTableAdd(gSubjKeyIDSlotCheckHash, newSlotid, newSeries))
             ? SECSuccess
             : SECFailure;
    PR_Unlock(gSubjKeyIDSlotCheckLock);
    if (rv == SECSuccess) {
        return rv;
    }

loser:
    if (newSlotid) {
        SECITEM_FreeItem(newSlotid, PR_TRUE);
    }
    if (newSeries) {
        SECITEM_FreeItem(newSeries, PR_TRUE);
    }
    return rv;
}

int
cert_SubjectKeyIDSlotCheckSeries(SECItem *slotid)
{
    SECItem *seriesItem = NULL;
    int series;

    if (!gSubjKeyIDSlotCheckLock) {
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
        return -1;
    }

    PR_Lock(gSubjKeyIDSlotCheckLock);
    seriesItem = (SECItem *)PL_HashTableLookup(gSubjKeyIDSlotCheckHash, slotid);
    PR_Unlock(gSubjKeyIDSlotCheckLock);
    /* getting a null series just means we haven't registered one yet,
     * just return 0 */
    if (seriesItem == NULL) {
        return 0;
    }
    /* if we got a series back, assert if it's not the proper length. */
    PORT_Assert(seriesItem->len == sizeof(int));
    if (seriesItem->len != sizeof(int)) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return -1;
    }
    PORT_Memcpy(&series, seriesItem->data, sizeof(int));
    return series;
}

SECStatus
cert_DestroySubjectKeyIDSlotCheckHash(void)
{
    if (gSubjKeyIDSlotCheckHash) {
        PR_Lock(gSubjKeyIDSlotCheckLock);
        PL_HashTableDestroy(gSubjKeyIDSlotCheckHash);
        gSubjKeyIDSlotCheckHash = NULL;
        PR_Unlock(gSubjKeyIDSlotCheckLock);
        PR_DestroyLock(gSubjKeyIDSlotCheckLock);
        gSubjKeyIDSlotCheckLock = NULL;
    }
    return SECSuccess;
}

SECStatus
cert_DestroySubjectKeyIDHashTable(void)
{
    if (gSubjKeyIDHash) {
        PR_Lock(gSubjKeyIDLock);
        PL_HashTableDestroy(gSubjKeyIDHash);
        gSubjKeyIDHash = NULL;
        PR_Unlock(gSubjKeyIDLock);
        PR_DestroyLock(gSubjKeyIDLock);
        gSubjKeyIDLock = NULL;
    }
    cert_DestroySubjectKeyIDSlotCheckHash();
    return SECSuccess;
}

SECItem *
cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID)
{
    SECItem *val;

    if (!gSubjKeyIDLock)
        return NULL;

    PR_Lock(gSubjKeyIDLock);
    val = (SECItem *)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID);
    if (val) {
        val = SECITEM_DupItem(val);
    }
    PR_Unlock(gSubjKeyIDLock);
    return val;
}

CERTCertificate *
CERT_FindCertBySubjectKeyID(CERTCertDBHandle *handle, SECItem *subjKeyID)
{
    CERTCertificate *cert = NULL;
    SECItem *derCert;

    derCert = cert_FindDERCertBySubjectKeyID(subjKeyID);
    if (derCert) {
        cert = CERT_FindCertByDERCert(handle, derCert);
        SECITEM_FreeItem(derCert, PR_TRUE);
    }
    return cert;
}
