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

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);
    permInstance = nssToken_ImportCertificate(
        internal, NULL, NSSCertificateType_PKIX, &c->id, stanNick, &c->encoding,
        &c->issuer, &c->subject, &c->serial, cert->emailAddr, PR_TRUE);
    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->nssCertificate = NULL;
    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);
    if (PR_TRUE) {
        /* 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.
         */
        NSSCertificate *tmp = cert->nssCertificate;
        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;
}
