/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "prtime.h"

#include "cert.h"
#include "certi.h"
#include "certdb.h"
#include "secitem.h"
#include "secder.h"

/* Call to PK11_FreeSlot below */

#include "secasn1.h"
#include "secerr.h"
#include "nssilock.h"
#include "prmon.h"
#include "base64.h"
#include "sechash.h"
#include "plhash.h"
#include "pk11func.h" /* sigh */

#include "nsspki.h"
#include "pki.h"
#include "pkim.h"
#include "pki3hack.h"
#include "ckhelper.h"
#include "base.h"
#include "pkistore.h"
#include "dev3hack.h"
#include "dev.h"
#include "secmodi.h"

extern void CERT_MaybeLockCertTempPerm(const CERTCertificate *cert);
extern void CERT_MaybeUnlockCertTempPerm(const CERTCertificate *cert);

PRBool
SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject,
                         CERTCertDBHandle *handle)
{
    CERTCertificate *cert;
    PRBool conflict = PR_FALSE;

    cert = CERT_FindCertByNickname(handle, nickname);

    if (!cert) {
        return conflict;
    }

    conflict = !SECITEM_ItemsAreEqual(derSubject, &cert->derSubject);
    CERT_DestroyCertificate(cert);
    return conflict;
}

SECStatus
SEC_DeletePermCertificate(CERTCertificate *cert)
{
    PRStatus nssrv;
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
    NSSCertificate *c = STAN_GetNSSCertificate(cert);
    CERTCertTrust *certTrust;

    if (c == NULL) {
        /* error code is set */
        return SECFailure;
    }

    certTrust = nssTrust_GetCERTCertTrustForCert(c, cert);
    if (certTrust) {
        NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c);
        if (nssTrust) {
            nssrv = STAN_DeleteCertTrustMatchingSlot(c);
            if (nssrv != PR_SUCCESS) {
                CERT_MapStanError();
            }
            /* This call always returns PR_SUCCESS! */
            (void)nssTrust_Destroy(nssTrust);
        }
    }

    /* get rid of the token instances */
    nssrv = NSSCertificate_DeleteStoredObject(c, NULL);

    /* get rid of the cache entry */
    nssTrustDomain_LockCertCache(td);
    nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
    nssTrustDomain_UnlockCertCache(td);

    return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
}

SECStatus
CERT_GetCertTrust(const CERTCertificate *cert, CERTCertTrust *trust)
{
    SECStatus rv;
    CERT_LockCertTrust(cert);
    if (!cert || cert->trust == NULL) {
        rv = SECFailure;
    } else {
        *trust = *cert->trust;
        rv = SECSuccess;
    }
    CERT_UnlockCertTrust(cert);
    return (rv);
}

extern const NSSError NSS_ERROR_NO_ERROR;
extern const NSSError NSS_ERROR_INTERNAL_ERROR;
extern const NSSError NSS_ERROR_NO_MEMORY;
extern const NSSError NSS_ERROR_INVALID_POINTER;
extern const NSSError NSS_ERROR_INVALID_ARENA;
extern const NSSError NSS_ERROR_INVALID_ARENA_MARK;
extern const NSSError NSS_ERROR_DUPLICATE_POINTER;
extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED;
extern const NSSError NSS_ERROR_TRACKER_NOT_EMPTY;
extern const NSSError NSS_ERROR_TRACKER_NOT_INITIALIZED;
extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
extern const NSSError NSS_ERROR_VALUE_TOO_LARGE;
extern const NSSError NSS_ERROR_UNSUPPORTED_TYPE;
extern const NSSError NSS_ERROR_BUFFER_TOO_SHORT;
extern const NSSError NSS_ERROR_INVALID_ATOB_CONTEXT;
extern const NSSError NSS_ERROR_INVALID_BASE64;
extern const NSSError NSS_ERROR_INVALID_BTOA_CONTEXT;
extern const NSSError NSS_ERROR_INVALID_ITEM;
extern const NSSError NSS_ERROR_INVALID_STRING;
extern const NSSError NSS_ERROR_INVALID_ASN1ENCODER;
extern const NSSError NSS_ERROR_INVALID_ASN1DECODER;
extern const NSSError NSS_ERROR_INVALID_BER;
extern const NSSError NSS_ERROR_INVALID_ATAV;
extern const NSSError NSS_ERROR_INVALID_ARGUMENT;
extern const NSSError NSS_ERROR_INVALID_UTF8;
extern const NSSError NSS_ERROR_INVALID_NSSOID;
extern const NSSError NSS_ERROR_UNKNOWN_ATTRIBUTE;
extern const NSSError NSS_ERROR_NOT_FOUND;
extern const NSSError NSS_ERROR_INVALID_PASSWORD;
extern const NSSError NSS_ERROR_USER_CANCELED;
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
extern const NSSError NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND;
extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE;
extern const NSSError NSS_ERROR_HASH_COLLISION;
extern const NSSError NSS_ERROR_DEVICE_ERROR;
extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;
extern const NSSError NSS_ERROR_BUSY;
extern const NSSError NSS_ERROR_ALREADY_INITIALIZED;
extern const NSSError NSS_ERROR_PKCS11;

/* Look at the stan error stack and map it to NSS 3 errors */
#define STAN_MAP_ERROR(x, y) \
    else if (error == (x)) { secError = y; }

/*
 * map Stan errors into NSS errors
 * This function examines the stan error stack and automatically sets
 * PORT_SetError(); to the appropriate SEC_ERROR value.
 */
void
CERT_MapStanError()
{
    PRInt32 *errorStack;
    NSSError error, prevError;
    int secError;
    int i;

    errorStack = NSS_GetErrorStack();
    if (errorStack == 0) {
        PORT_SetError(0);
        return;
    }
    error = prevError = CKR_GENERAL_ERROR;
    /* get the 'top 2' error codes from the stack */
    for (i = 0; errorStack[i]; i++) {
        prevError = error;
        error = errorStack[i];
    }
    if (error == NSS_ERROR_PKCS11) {
        /* map it */
        secError = PK11_MapError(prevError);
    }
    STAN_MAP_ERROR(NSS_ERROR_NO_ERROR, 0)
    STAN_MAP_ERROR(NSS_ERROR_NO_MEMORY, SEC_ERROR_NO_MEMORY)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_BASE64, SEC_ERROR_BAD_DATA)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_BER, SEC_ERROR_BAD_DER)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ATAV, SEC_ERROR_INVALID_AVA)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_PASSWORD, SEC_ERROR_BAD_PASSWORD)
    STAN_MAP_ERROR(NSS_ERROR_BUSY, SEC_ERROR_BUSY)
    STAN_MAP_ERROR(NSS_ERROR_DEVICE_ERROR, SEC_ERROR_IO)
    STAN_MAP_ERROR(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND,
                   SEC_ERROR_UNKNOWN_ISSUER)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_CERTIFICATE, SEC_ERROR_CERT_NOT_VALID)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_UTF8, SEC_ERROR_BAD_DATA)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_NSSOID, SEC_ERROR_BAD_DATA)

    /* these are library failure for lack of a better error code */
    STAN_MAP_ERROR(NSS_ERROR_NOT_FOUND, SEC_ERROR_LIBRARY_FAILURE)
    STAN_MAP_ERROR(NSS_ERROR_CERTIFICATE_IN_CACHE, SEC_ERROR_LIBRARY_FAILURE)
    STAN_MAP_ERROR(NSS_ERROR_MAXIMUM_FOUND, SEC_ERROR_LIBRARY_FAILURE)
    STAN_MAP_ERROR(NSS_ERROR_USER_CANCELED, SEC_ERROR_LIBRARY_FAILURE)
    STAN_MAP_ERROR(NSS_ERROR_TRACKER_NOT_INITIALIZED, SEC_ERROR_LIBRARY_FAILURE)
    STAN_MAP_ERROR(NSS_ERROR_ALREADY_INITIALIZED, SEC_ERROR_LIBRARY_FAILURE)
    STAN_MAP_ERROR(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD,
                   SEC_ERROR_LIBRARY_FAILURE)
    STAN_MAP_ERROR(NSS_ERROR_HASH_COLLISION, SEC_ERROR_LIBRARY_FAILURE)

    STAN_MAP_ERROR(NSS_ERROR_INTERNAL_ERROR, SEC_ERROR_LIBRARY_FAILURE)

    /* these are all invalid arguments */
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ARGUMENT, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_POINTER, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ARENA, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ARENA_MARK, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_DUPLICATE_POINTER, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_POINTER_NOT_REGISTERED, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_TRACKER_NOT_EMPTY, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_VALUE_TOO_LARGE, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_UNSUPPORTED_TYPE, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_BUFFER_TOO_SHORT, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ATOB_CONTEXT, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_BTOA_CONTEXT, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ITEM, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_STRING, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ASN1ENCODER, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ASN1DECODER, SEC_ERROR_INVALID_ARGS)
    STAN_MAP_ERROR(NSS_ERROR_UNKNOWN_ATTRIBUTE, SEC_ERROR_INVALID_ARGS)
    else { secError = SEC_ERROR_LIBRARY_FAILURE; }
    PORT_SetError(secError);
}

SECStatus
CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert,
                     CERTCertTrust *trust)
{
    SECStatus rv = SECSuccess;
    PRStatus ret;

    ret = STAN_ChangeCertTrust(cert, trust);
    if (ret != PR_SUCCESS) {
        rv = SECFailure;
        CERT_MapStanError();
    }
    return rv;
}

extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;

SECStatus
__CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
                         CERTCertTrust *trust)
{
    NSSUTF8 *stanNick;
    PK11SlotInfo *slot;
    NSSToken *internal;
    NSSCryptoContext *context;
    nssCryptokiObject *permInstance;
    NSSCertificate *c = STAN_GetNSSCertificate(cert);
    nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
    nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
    SECStatus rv;
    PRStatus ret;

    if (c == NULL) {
        CERT_MapStanError();
        return SECFailure;
    }

    context = c->object.cryptoContext;
    if (!context) {
        PORT_SetError(SEC_ERROR_ADDING_CERT);
        return SECFailure; /* wasn't a temp cert */
    }
    stanNick = nssCertificate_GetNickname(c, NULL);
    if (stanNick && nickname && strcmp(nickname, stanNick) != 0) {
        /* different: take the new nickname */
        cert->nickname = NULL;
        nss_ZFreeIf(stanNick);
        stanNick = NULL;
    }
    if (!stanNick && nickname) {
        /* Either there was no nickname yet, or we have a new nickname */
        stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, NULL);
    } /* else: old stanNick is identical to new nickname */
    /* Delete the temp instance */
    nssCertificateStore_Lock(context->certStore, &lockTrace);
    nssCertificateStore_RemoveCertLOCKED(context->certStore, c);
    nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace);
    c->object.cryptoContext = NULL;

    /* if the id has not been set explicitly yet, create one from the public
     * key. */
    if (c->id.data == NULL) {
        SECItem *keyID = pk11_mkcertKeyID(cert);
        if (keyID) {
            nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data);
            SECITEM_FreeItem(keyID, PR_TRUE);
        }
        /* if any of these failed, continue with our null c->id */
    }

    /* Import the perm instance onto the internal token */
    slot = PK11_GetInternalKeySlot();
    internal = PK11Slot_GetNSSToken(slot);
    if (!internal) {
        PK11_FreeSlot(slot);
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return SECFailure;
    }
    permInstance = nssToken_ImportCertificate(
        internal, NULL, NSSCertificateType_PKIX, &c->id, stanNick, &c->encoding,
        &c->issuer, &c->subject, &c->serial, cert->emailAddr, PR_TRUE);
    (void)nssToken_Destroy(internal);
    nss_ZFreeIf(stanNick);
    stanNick = NULL;
    PK11_FreeSlot(slot);
    if (!permInstance) {
        if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) {
            PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL);
        }
        return SECFailure;
    }
    nssPKIObject_AddInstance(&c->object, permInstance);
    nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
    /* reset the CERTCertificate fields */
    CERT_LockCertTempPerm(cert);
    cert->nssCertificate = NULL;
    CERT_UnlockCertTempPerm(cert);
    cert = STAN_GetCERTCertificateOrRelease(c); /* should return same pointer */
    if (!cert) {
        CERT_MapStanError();
        return SECFailure;
    }
    CERT_LockCertTempPerm(cert);
    cert->istemp = PR_FALSE;
    cert->isperm = PR_TRUE;
    CERT_UnlockCertTempPerm(cert);
    if (!trust) {
        return SECSuccess;
    }
    ret = STAN_ChangeCertTrust(cert, trust);
    rv = SECSuccess;
    if (ret != PR_SUCCESS) {
        rv = SECFailure;
        CERT_MapStanError();
    }
    return rv;
}

SECStatus
CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
                       CERTCertTrust *trust)
{
    return __CERT_AddTempCertToPerm(cert, nickname, trust);
}

CERTCertificate *
CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
                        char *nickname, PRBool isperm, PRBool copyDER)
{
    NSSCertificate *c;
    CERTCertificate *cc;
    NSSCertificate *tempCert = NULL;
    nssPKIObject *pkio;
    NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext();
    NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain();
    if (!isperm) {
        NSSDER encoding;
        NSSITEM_FROM_SECITEM(&encoding, derCert);
        /* First, see if it is already a temp cert */
        c = NSSCryptoContext_FindCertificateByEncodedCertificate(gCC,
                                                                 &encoding);
        if (!c && handle) {
            /* Then, see if it is already a perm cert */
            c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle,
                                                                   &encoding);
        }
        if (c) {
            /* actually, that search ends up going by issuer/serial,
             * so it is still possible to return a cert with the same
             * issuer/serial but a different encoding, and we're
             * going to reject that
             */
            if (!nssItem_Equal(&c->encoding, &encoding, NULL)) {
                nssCertificate_Destroy(c);
                PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL);
                cc = NULL;
            } else {
                cc = STAN_GetCERTCertificateOrRelease(c);
                if (cc == NULL) {
                    CERT_MapStanError();
                }
            }
            return cc;
        }
    }
    pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC, nssPKIMonitor);
    if (!pkio) {
        CERT_MapStanError();
        return NULL;
    }
    c = nss_ZNEW(pkio->arena, NSSCertificate);
    if (!c) {
        CERT_MapStanError();
        nssPKIObject_Destroy(pkio);
        return NULL;
    }
    c->object = *pkio;
    if (copyDER) {
        nssItem_Create(c->object.arena, &c->encoding, derCert->len,
                       derCert->data);
    } else {
        NSSITEM_FROM_SECITEM(&c->encoding, derCert);
    }
    /* Forces a decoding of the cert in order to obtain the parts used
     * below
     */
    /* 'c' is not adopted here, if we fail loser frees what has been
     * allocated so far for 'c' */
    cc = STAN_GetCERTCertificate(c);
    if (!cc) {
        CERT_MapStanError();
        goto loser;
    }
    nssItem_Create(c->object.arena, &c->issuer, cc->derIssuer.len,
                   cc->derIssuer.data);
    nssItem_Create(c->object.arena, &c->subject, cc->derSubject.len,
                   cc->derSubject.data);
    /* CERTCertificate stores serial numbers decoded.  I need the DER
    * here.  sigh.
    */
    SECItem derSerial = { 0 };
    CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
    if (!derSerial.data)
        goto loser;
    nssItem_Create(c->object.arena, &c->serial, derSerial.len,
                   derSerial.data);
    PORT_Free(derSerial.data);

    if (nickname) {
        c->object.tempName =
            nssUTF8_Create(c->object.arena, nssStringType_UTF8String,
                           (NSSUTF8 *)nickname, PORT_Strlen(nickname));
    }
    if (cc->emailAddr && cc->emailAddr[0]) {
        c->email = nssUTF8_Create(
            c->object.arena, nssStringType_PrintableString,
            (NSSUTF8 *)cc->emailAddr, PORT_Strlen(cc->emailAddr));
    }

    tempCert = NSSCryptoContext_FindOrImportCertificate(gCC, c);
    if (!tempCert) {
        CERT_MapStanError();
        goto loser;
    }
    /* destroy our copy */
    NSSCertificate_Destroy(c);
    /* and use the stored entry */
    c = tempCert;
    cc = STAN_GetCERTCertificateOrRelease(c);
    if (!cc) {
        /* STAN_GetCERTCertificateOrRelease destroys c on failure. */
        CERT_MapStanError();
        return NULL;
    }

    CERT_LockCertTempPerm(cc);
    cc->istemp = PR_TRUE;
    cc->isperm = PR_FALSE;
    CERT_UnlockCertTempPerm(cc);
    return cc;
loser:
    /* Perhaps this should be nssCertificate_Destroy(c) */
    nssPKIObject_Destroy(&c->object);
    return NULL;
}

/* This symbol is exported for backward compatibility. */
CERTCertificate *
__CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
                          char *nickname, PRBool isperm, PRBool copyDER)
{
    return CERT_NewTempCertificate(handle, derCert, nickname, isperm, copyDER);
}

static CERTCertificate *
common_FindCertByIssuerAndSN(CERTCertDBHandle *handle,
                             CERTIssuerAndSN *issuerAndSN,
                             void *wincx)
{
    PK11SlotInfo *slot;
    CERTCertificate *cert;

    cert = PK11_FindCertByIssuerAndSN(&slot, issuerAndSN, wincx);
    if (cert && slot) {
        PK11_FreeSlot(slot);
    }

    return cert;
}

/* maybe all the wincx's should be some const for internal token login? */
CERTCertificate *
CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle,
                           CERTIssuerAndSN *issuerAndSN)
{
    return common_FindCertByIssuerAndSN(handle, issuerAndSN, NULL);
}

/* maybe all the wincx's should be some const for internal token login? */
CERTCertificate *
CERT_FindCertByIssuerAndSNCX(CERTCertDBHandle *handle,
                             CERTIssuerAndSN *issuerAndSN,
                             void *wincx)
{
    return common_FindCertByIssuerAndSN(handle, issuerAndSN, wincx);
}

static NSSCertificate *
get_best_temp_or_perm(NSSCertificate *ct, NSSCertificate *cp)
{
    NSSUsage usage;
    NSSCertificate *arr[3];
    if (!ct) {
        return nssCertificate_AddRef(cp);
    } else if (!cp) {
        return nssCertificate_AddRef(ct);
    }
    arr[0] = ct;
    arr[1] = cp;
    arr[2] = NULL;
    usage.anyUsage = PR_TRUE;
    return nssCertificateArray_FindBestCertificate(arr, NULL, &usage, NULL);
}

CERTCertificate *
CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name)
{
    NSSCertificate *cp, *ct, *c;
    NSSDER subject;
    NSSUsage usage;
    NSSCryptoContext *cc;
    NSSITEM_FROM_SECITEM(&subject, name);
    usage.anyUsage = PR_TRUE;
    cc = STAN_GetDefaultCryptoContext();
    ct = NSSCryptoContext_FindBestCertificateBySubject(cc, &subject, NULL,
                                                       &usage, NULL);
    cp = NSSTrustDomain_FindBestCertificateBySubject(handle, &subject, NULL,
                                                     &usage, NULL);
    c = get_best_temp_or_perm(ct, cp);
    if (ct) {
        CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
    }
    if (cp) {
        CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(cp));
    }
    return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
}

CERTCertificate *
CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID)
{
    CERTCertList *list;
    CERTCertificate *cert = NULL;
    CERTCertListNode *node;

    list = CERT_CreateSubjectCertList(NULL, handle, name, 0, PR_FALSE);
    if (list == NULL)
        return NULL;

    node = CERT_LIST_HEAD(list);
    while (!CERT_LIST_END(node, list)) {
        if (node->cert &&
            SECITEM_ItemsAreEqual(&node->cert->subjectKeyID, keyID)) {
            cert = CERT_DupCertificate(node->cert);
            goto done;
        }
        node = CERT_LIST_NEXT(node);
    }
    PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);

done:
    CERT_DestroyCertList(list);
    return cert;
}

CERTCertificate *
CERT_FindCertByNickname(CERTCertDBHandle *handle, const char *nickname)
{
    NSSCryptoContext *cc;
    NSSCertificate *c, *ct;
    CERTCertificate *cert;
    NSSUsage usage;
    usage.anyUsage = PR_TRUE;
    cc = STAN_GetDefaultCryptoContext();
    ct = NSSCryptoContext_FindBestCertificateByNickname(cc, nickname, NULL,
                                                        &usage, NULL);
    cert = PK11_FindCertFromNickname(nickname, NULL);
    c = NULL;
    if (cert) {
        c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
        CERT_DestroyCertificate(cert);
        if (ct) {
            CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
        }
    } else {
        c = ct;
    }
    return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
}

CERTCertificate *
CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert)
{
    NSSCryptoContext *cc;
    NSSCertificate *c;
    NSSDER encoding;
    NSSITEM_FROM_SECITEM(&encoding, derCert);
    cc = STAN_GetDefaultCryptoContext();
    c = NSSCryptoContext_FindCertificateByEncodedCertificate(cc, &encoding);
    if (!c) {
        c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle,
                                                               &encoding);
        if (!c)
            return NULL;
    }
    return STAN_GetCERTCertificateOrRelease(c);
}

static CERTCertificate *
common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
                                             const char *name, PRBool anyUsage,
                                             SECCertUsage lookingForUsage,
                                             void *wincx)
{
    NSSCryptoContext *cc;
    NSSCertificate *c, *ct;
    CERTCertificate *cert = NULL;
    NSSUsage usage;
    CERTCertList *certlist;

    if (NULL == name) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    usage.anyUsage = anyUsage;

    if (!anyUsage) {
        usage.nss3lookingForCA = PR_FALSE;
        usage.nss3usage = lookingForUsage;
    }

    cc = STAN_GetDefaultCryptoContext();
    ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name, NULL, &usage,
                                                        NULL);
    if (!ct && PORT_Strchr(name, '@') != NULL) {
        char *lowercaseName = CERT_FixupEmailAddr(name);
        if (lowercaseName) {
            ct = NSSCryptoContext_FindBestCertificateByEmail(
                cc, lowercaseName, NULL, &usage, NULL);
            PORT_Free(lowercaseName);
        }
    }

    if (anyUsage) {
        cert = PK11_FindCertFromNickname(name, wincx);
    } else {
        if (ct) {
            /* Does ct really have the required usage? */
            nssDecodedCert *dc;
            dc = nssCertificate_GetDecoding(ct);
            if (!dc->matchUsage(dc, &usage)) {
                CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
                ct = NULL;
            }
        }

        certlist = PK11_FindCertsFromNickname(name, wincx);
        if (certlist) {
            SECStatus rv =
                CERT_FilterCertListByUsage(certlist, lookingForUsage, PR_FALSE);
            if (SECSuccess == rv && !CERT_LIST_EMPTY(certlist)) {
                cert = CERT_DupCertificate(CERT_LIST_HEAD(certlist)->cert);
            }
            CERT_DestroyCertList(certlist);
        }
    }

    if (cert) {
        c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
        CERT_DestroyCertificate(cert);
        if (ct) {
            CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
        }
    } else {
        c = ct;
    }
    return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
}

CERTCertificate *
CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name)
{
    return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_TRUE,
                                                        0, NULL);
}

CERTCertificate *
CERT_FindCertByNicknameOrEmailAddrCX(CERTCertDBHandle *handle, const char *name,
                                     void *wincx)
{
    return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_TRUE,
                                                        0, wincx);
}

CERTCertificate *
CERT_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
                                           const char *name,
                                           SECCertUsage lookingForUsage)
{
    return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_FALSE,
                                                        lookingForUsage, NULL);
}

CERTCertificate *
CERT_FindCertByNicknameOrEmailAddrForUsageCX(CERTCertDBHandle *handle,
                                             const char *name,
                                             SECCertUsage lookingForUsage,
                                             void *wincx)
{
    return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_FALSE,
                                                        lookingForUsage, wincx);
}

static void
add_to_subject_list(CERTCertList *certList, CERTCertificate *cert,
                    PRBool validOnly, PRTime sorttime)
{
    SECStatus secrv;
    if (!validOnly ||
        CERT_CheckCertValidTimes(cert, sorttime, PR_FALSE) ==
            secCertTimeValid) {
        secrv = CERT_AddCertToListSorted(certList, cert, CERT_SortCBValidity,
                                         (void *)&sorttime);
        if (secrv != SECSuccess) {
            CERT_DestroyCertificate(cert);
        }
    } else {
        CERT_DestroyCertificate(cert);
    }
}

CERTCertList *
CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle,
                           const SECItem *name, PRTime sorttime,
                           PRBool validOnly)
{
    NSSCryptoContext *cc;
    NSSCertificate **tSubjectCerts, **pSubjectCerts;
    NSSCertificate **ci;
    CERTCertificate *cert;
    NSSDER subject;
    PRBool myList = PR_FALSE;
    cc = STAN_GetDefaultCryptoContext();
    NSSITEM_FROM_SECITEM(&subject, name);
    /* Collect both temp and perm certs for the subject */
    tSubjectCerts =
        NSSCryptoContext_FindCertificatesBySubject(cc, &subject, NULL, 0, NULL);
    pSubjectCerts = NSSTrustDomain_FindCertificatesBySubject(handle, &subject,
                                                             NULL, 0, NULL);
    if (!tSubjectCerts && !pSubjectCerts) {
        return NULL;
    }
    if (certList == NULL) {
        certList = CERT_NewCertList();
        myList = PR_TRUE;
        if (!certList)
            goto loser;
    }
    /* Iterate over the matching temp certs.  Add them to the list */
    ci = tSubjectCerts;
    while (ci && *ci) {
        cert = STAN_GetCERTCertificateOrRelease(*ci);
        /* *ci may be invalid at this point, don't reference it again */
        if (cert) {
            /* NOTE: add_to_subject_list adopts the incoming cert. */
            add_to_subject_list(certList, cert, validOnly, sorttime);
        }
        ci++;
    }
    /* Iterate over the matching perm certs.  Add them to the list */
    ci = pSubjectCerts;
    while (ci && *ci) {
        cert = STAN_GetCERTCertificateOrRelease(*ci);
        /* *ci may be invalid at this point, don't reference it again */
        if (cert) {
            /* NOTE: add_to_subject_list adopts the incoming cert. */
            add_to_subject_list(certList, cert, validOnly, sorttime);
        }
        ci++;
    }
    /* all the references have been adopted or freed at this point, just
     * free the arrays now */
    nss_ZFreeIf(tSubjectCerts);
    nss_ZFreeIf(pSubjectCerts);
    return certList;
loser:
    /* need to free the references in tSubjectCerts and pSubjectCerts! */
    nssCertificateArray_Destroy(tSubjectCerts);
    nssCertificateArray_Destroy(pSubjectCerts);
    if (myList && certList != NULL) {
        CERT_DestroyCertList(certList);
    }
    return NULL;
}

void
CERT_DestroyCertificate(CERTCertificate *cert)
{
    if (cert) {
        /* don't use STAN_GetNSSCertificate because we don't want to
         * go to the trouble of translating the CERTCertificate into
         * an NSSCertificate just to destroy it.  If it hasn't been done
         * yet, don't do it at all
         *
         * cert->nssCertificate contains its own locks and refcount, but as it
         * may be NULL, the pointer itself must be guarded by some other lock.
         * Rather than creating a new global lock for only this purpose, share
         * an existing global lock that happens to be taken near the write in
         * fill_CERTCertificateFields(). The longer-term goal is to refactor
         * all these global locks to be certificate-scoped. */
        CERT_MaybeLockCertTempPerm(cert);
        NSSCertificate *tmp = cert->nssCertificate;
        CERT_MaybeUnlockCertTempPerm(cert);
        if (tmp) {
            /* delete the NSSCertificate */
            NSSCertificate_Destroy(tmp);
        } else if (cert->arena) {
            PORT_FreeArena(cert->arena, PR_FALSE);
        }
    }
    return;
}

int
CERT_GetDBContentVersion(CERTCertDBHandle *handle)
{
    /* should read the DB content version from the pkcs #11 device */
    return 0;
}

SECStatus
certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr,
                         SECItem *emailProfile, SECItem *profileTime)
{
    PRTime oldtime;
    PRTime newtime;
    SECStatus rv = SECFailure;
    PRBool saveit;
    SECItem oldprof, oldproftime;
    SECItem *oldProfile = NULL;
    SECItem *oldProfileTime = NULL;
    PK11SlotInfo *slot = NULL;
    NSSCertificate *c;
    NSSCryptoContext *cc;
    nssSMIMEProfile *stanProfile = NULL;
    PRBool freeOldProfile = PR_FALSE;

    c = STAN_GetNSSCertificate(cert);
    if (!c)
        return SECFailure;
    cc = c->object.cryptoContext;
    if (cc != NULL) {
        stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c);
        if (stanProfile) {
            PORT_Assert(stanProfile->profileData);
            SECITEM_FROM_NSSITEM(&oldprof, stanProfile->profileData);
            oldProfile = &oldprof;
            SECITEM_FROM_NSSITEM(&oldproftime, stanProfile->profileTime);
            oldProfileTime = &oldproftime;
        }
    } else {
        oldProfile = PK11_FindSMimeProfile(&slot, (char *)emailAddr,
                                           &cert->derSubject, &oldProfileTime);
        freeOldProfile = PR_TRUE;
    }

    saveit = PR_FALSE;

    /* both profileTime and emailProfile have to exist or not exist */
    if (emailProfile == NULL) {
        profileTime = NULL;
    } else if (profileTime == NULL) {
        emailProfile = NULL;
    }

    if (oldProfileTime == NULL) {
        saveit = PR_TRUE;
    } else {
        /* there was already a profile for this email addr */
        if (profileTime) {
            /* we have an old and new profile - save whichever is more recent*/
            if (oldProfileTime->len == 0) {
                /* always replace if old entry doesn't have a time */
                oldtime = LL_MININT;
            } else {
                rv = DER_UTCTimeToTime(&oldtime, oldProfileTime);
                if (rv != SECSuccess) {
                    goto loser;
                }
            }

            rv = DER_UTCTimeToTime(&newtime, profileTime);
            if (rv != SECSuccess) {
                goto loser;
            }

            if (LL_CMP(newtime, >, oldtime)) {
                /* this is a newer profile, save it and cert */
                saveit = PR_TRUE;
            }
        } else {
            saveit = PR_TRUE;
        }
    }

    if (saveit) {
        if (cc) {
            if (stanProfile && profileTime && emailProfile) {
                /* stanProfile is already stored in the crypto context,
                 * overwrite the data
                 */
                NSSArena *arena = stanProfile->object.arena;
                stanProfile->profileTime = nssItem_Create(
                    arena, NULL, profileTime->len, profileTime->data);
                stanProfile->profileData = nssItem_Create(
                    arena, NULL, emailProfile->len, emailProfile->data);
            } else if (profileTime && emailProfile) {
                PRStatus nssrv;
                NSSItem profTime, profData;
                NSSITEM_FROM_SECITEM(&profTime, profileTime);
                NSSITEM_FROM_SECITEM(&profData, emailProfile);
                stanProfile = nssSMIMEProfile_Create(c, &profTime, &profData);
                if (!stanProfile)
                    goto loser;
                nssrv = nssCryptoContext_ImportSMIMEProfile(cc, stanProfile);
                rv = (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
            }
        } else {
            rv = PK11_SaveSMimeProfile(slot, (char *)emailAddr,
                                       &cert->derSubject, emailProfile,
                                       profileTime);
        }
    } else {
        rv = SECSuccess;
    }

loser:
    if (oldProfile && freeOldProfile) {
        SECITEM_FreeItem(oldProfile, PR_TRUE);
    }
    if (oldProfileTime && freeOldProfile) {
        SECITEM_FreeItem(oldProfileTime, PR_TRUE);
    }
    if (stanProfile) {
        nssSMIMEProfile_Destroy(stanProfile);
    }
    if (slot) {
        PK11_FreeSlot(slot);
    }

    return (rv);
}

/*
 *
 * Manage S/MIME profiles
 *
 */

SECStatus
CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
                      SECItem *profileTime)
{
    const char *emailAddr;
    SECStatus rv;
    PRBool isperm = PR_FALSE;

    if (!cert) {
        return SECFailure;
    }

    if (cert->slot && !PK11_IsInternal(cert->slot)) {
        /* this cert comes from an external source, we need to add it
        to the cert db before creating an S/MIME profile */
        PK11SlotInfo *internalslot = PK11_GetInternalKeySlot();
        if (!internalslot) {
            return SECFailure;
        }
        rv = PK11_ImportCert(internalslot, cert, CK_INVALID_HANDLE, NULL,
                             PR_FALSE);

        PK11_FreeSlot(internalslot);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }

    rv = CERT_GetCertIsPerm(cert, &isperm);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    if (cert->slot && isperm && CERT_IsUserCert(cert) &&
        (!emailProfile || !emailProfile->len)) {
        /* Don't clobber emailProfile for user certs. */
        return SECSuccess;
    }

    for (emailAddr = CERT_GetFirstEmailAddress(cert); emailAddr != NULL;
         emailAddr = CERT_GetNextEmailAddress(cert, emailAddr)) {
        rv = certdb_SaveSingleProfile(cert, emailAddr, emailProfile,
                                      profileTime);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }
    return SECSuccess;
}

SECItem *
CERT_FindSMimeProfile(CERTCertificate *cert)
{
    PK11SlotInfo *slot = NULL;
    NSSCertificate *c;
    NSSCryptoContext *cc;
    SECItem *rvItem = NULL;

    if (!cert || !cert->emailAddr || !cert->emailAddr[0]) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    c = STAN_GetNSSCertificate(cert);
    if (!c)
        return NULL;
    cc = c->object.cryptoContext;
    if (cc != NULL) {
        nssSMIMEProfile *stanProfile;
        stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c);
        if (stanProfile) {
            rvItem =
                SECITEM_AllocItem(NULL, NULL, stanProfile->profileData->size);
            if (rvItem) {
                rvItem->data = stanProfile->profileData->data;
            }
            nssSMIMEProfile_Destroy(stanProfile);
        }
        return rvItem;
    }
    rvItem =
        PK11_FindSMimeProfile(&slot, cert->emailAddr, &cert->derSubject, NULL);
    if (slot) {
        PK11_FreeSlot(slot);
    }
    return rvItem;
}

SECStatus
CERT_GetCertIsPerm(const CERTCertificate *cert, PRBool *isperm)
{
    if (cert == NULL) {
        return SECFailure;
    }

    CERT_LockCertTempPerm(cert);
    *isperm = cert->isperm;
    CERT_UnlockCertTempPerm(cert);
    return SECSuccess;
}

SECStatus
CERT_GetCertIsTemp(const CERTCertificate *cert, PRBool *istemp)
{
    if (cert == NULL) {
        return SECFailure;
    }

    CERT_LockCertTempPerm(cert);
    *istemp = cert->istemp;
    CERT_UnlockCertTempPerm(cert);
    return SECSuccess;
}

/*
 * deprecated functions that are now just stubs.
 */
/*
 * Close the database
 */
void
__CERT_ClosePermCertDB(CERTCertDBHandle *handle)
{
    PORT_Assert("CERT_ClosePermCertDB is Deprecated" == NULL);
    return;
}

SECStatus
CERT_OpenCertDBFilename(CERTCertDBHandle *handle, char *certdbname,
                        PRBool readOnly)
{
    PORT_Assert("CERT_OpenCertDBFilename is Deprecated" == NULL);
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return SECFailure;
}

SECItem *
SECKEY_HashPassword(char *pw, SECItem *salt)
{
    PORT_Assert("SECKEY_HashPassword is Deprecated" == NULL);
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return NULL;
}

SECStatus
__CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle,
                                   SECItem *derSubject, void *cb, void *cbarg)
{
    PORT_Assert("CERT_TraversePermCertsForSubject is Deprecated" == NULL);
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return SECFailure;
}

SECStatus
__CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname,
                                    void *cb, void *cbarg)
{
    PORT_Assert("CERT_TraversePermCertsForNickname is Deprecated" == NULL);
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return SECFailure;
}
