/* 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/. */
/*
 * This file manages PKCS #11 instances of certificates.
 */

#include "secport.h"
#include "seccomon.h"
#include "secmod.h"
#include "secmodi.h"
#include "secmodti.h"
#include "pkcs11.h"
#include "pk11func.h"
#include "cert.h"
#include "certi.h"
#include "secitem.h"
#include "keyhi.h"
#include "secoid.h"
#include "pkcs7t.h"
#include "cmsreclist.h"

#include "certdb.h"
#include "secerr.h"
#include "sslerr.h"

#include "pki3hack.h"
#include "dev3hack.h"

#include "devm.h"
#include "nsspki.h"
#include "pki.h"
#include "pkim.h"
#include "pkitm.h"
#include "pkistore.h" /* to remove temp cert */
#include "devt.h"
#include "ckhelper.h"
#include "pkcs11uri.h"

extern const NSSError NSS_ERROR_NOT_FOUND;
extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;

struct nss3_cert_cbstr {
    SECStatus (*callback)(CERTCertificate *, void *);
    nssList *cached;
    void *arg;
};

/* Translate from NSSCertificate to CERTCertificate, then pass the latter
 * to a callback.
 */
static PRStatus
convert_cert(NSSCertificate *c, void *arg)
{
    CERTCertificate *nss3cert;
    SECStatus secrv;
    struct nss3_cert_cbstr *nss3cb = (struct nss3_cert_cbstr *)arg;
    /* 'c' is not adopted. caller will free it */
    nss3cert = STAN_GetCERTCertificate(c);
    if (!nss3cert)
        return PR_FAILURE;
    secrv = (*nss3cb->callback)(nss3cert, nss3cb->arg);
    return (secrv) ? PR_FAILURE : PR_SUCCESS;
}

/*
 * build a cert nickname based on the token name and the label of the
 * certificate If the label in NULL, build a label based on the ID.
 */
static int
toHex(int x)
{
    return (x < 10) ? (x + '0') : (x + 'a' - 10);
}
#define MAX_CERT_ID 4
#define DEFAULT_STRING "Cert ID "
static char *
pk11_buildNickname(PK11SlotInfo *slot, CK_ATTRIBUTE *cert_label,
                   CK_ATTRIBUTE *key_label, CK_ATTRIBUTE *cert_id)
{
    int prefixLen = PORT_Strlen(slot->token_name);
    int suffixLen = 0;
    char *suffix = NULL;
    char buildNew[sizeof(DEFAULT_STRING) + MAX_CERT_ID * 2];
    char *next, *nickname;

    if (cert_label && (cert_label->ulValueLen)) {
        suffixLen = cert_label->ulValueLen;
        suffix = (char *)cert_label->pValue;
    } else if (key_label && (key_label->ulValueLen)) {
        suffixLen = key_label->ulValueLen;
        suffix = (char *)key_label->pValue;
    } else if (cert_id && cert_id->ulValueLen > 0) {
        int i, first = cert_id->ulValueLen - MAX_CERT_ID;
        int offset = sizeof(DEFAULT_STRING);
        char *idValue = (char *)cert_id->pValue;

        PORT_Memcpy(buildNew, DEFAULT_STRING, sizeof(DEFAULT_STRING) - 1);
        next = buildNew + offset;
        if (first < 0)
            first = 0;
        for (i = first; i < (int)cert_id->ulValueLen; i++) {
            *next++ = toHex((idValue[i] >> 4) & 0xf);
            *next++ = toHex(idValue[i] & 0xf);
        }
        *next++ = 0;
        suffix = buildNew;
        suffixLen = PORT_Strlen(buildNew);
    } else {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return NULL;
    }

    /* if is internal key slot, add code to skip the prefix!! */
    next = nickname = (char *)PORT_Alloc(prefixLen + 1 + suffixLen + 1);
    if (nickname == NULL)
        return NULL;

    PORT_Memcpy(next, slot->token_name, prefixLen);
    next += prefixLen;
    *next++ = ':';
    PORT_Memcpy(next, suffix, suffixLen);
    next += suffixLen;
    *next++ = 0;
    return nickname;
}

PRBool
PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
                CK_OBJECT_HANDLE certID)
{
    CK_OBJECT_CLASS theClass;

    if (slot == NULL)
        return PR_FALSE;
    if (cert == NULL)
        return PR_FALSE;

    theClass = CKO_PRIVATE_KEY;
    if (pk11_LoginStillRequired(slot, NULL)) {
        theClass = CKO_PUBLIC_KEY;
    }
    if (PK11_MatchItem(slot, certID, theClass) != CK_INVALID_HANDLE) {
        return PR_TRUE;
    }

    if (theClass == CKO_PUBLIC_KEY) {
        SECKEYPublicKey *pubKey = CERT_ExtractPublicKey(cert);
        CK_ATTRIBUTE theTemplate;

        if (pubKey == NULL) {
            return PR_FALSE;
        }

        PK11_SETATTRS(&theTemplate, 0, NULL, 0);
        switch (pubKey->keyType) {
            case rsaKey:
            case rsaPssKey:
            case rsaOaepKey:
                PK11_SETATTRS(&theTemplate, CKA_MODULUS, pubKey->u.rsa.modulus.data,
                              pubKey->u.rsa.modulus.len);
                break;
            case dsaKey:
                PK11_SETATTRS(&theTemplate, CKA_VALUE, pubKey->u.dsa.publicValue.data,
                              pubKey->u.dsa.publicValue.len);
                break;
            case dhKey:
                PK11_SETATTRS(&theTemplate, CKA_VALUE, pubKey->u.dh.publicValue.data,
                              pubKey->u.dh.publicValue.len);
                break;
            case ecKey:
                PK11_SETATTRS(&theTemplate, CKA_EC_POINT,
                              pubKey->u.ec.publicValue.data,
                              pubKey->u.ec.publicValue.len);
                break;
            case keaKey:
            case fortezzaKey:
            case nullKey:
                /* fall through and return false */
                break;
        }

        if (theTemplate.ulValueLen == 0) {
            SECKEY_DestroyPublicKey(pubKey);
            return PR_FALSE;
        }
        pk11_SignedToUnsigned(&theTemplate);
        if (pk11_FindObjectByTemplate(slot, &theTemplate, 1) != CK_INVALID_HANDLE) {
            SECKEY_DestroyPublicKey(pubKey);
            return PR_TRUE;
        }
        SECKEY_DestroyPublicKey(pubKey);
    }
    return PR_FALSE;
}

/*
 * Check out if a cert has ID of zero. This is a magic ID that tells
 * NSS that this cert may be an automagically trusted cert.
 * The Cert has to be self signed as well. That check is done elsewhere.
 *
 */
PRBool
pk11_isID0(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID)
{
    CK_ATTRIBUTE keyID = { CKA_ID, NULL, 0 };
    PRBool isZero = PR_FALSE;
    int i;
    CK_RV crv;

    crv = PK11_GetAttributes(NULL, slot, certID, &keyID, 1);
    if (crv != CKR_OK) {
        return isZero;
    }

    if (keyID.ulValueLen != 0) {
        char *value = (char *)keyID.pValue;
        isZero = PR_TRUE; /* ID exists, may be zero */
        for (i = 0; i < (int)keyID.ulValueLen; i++) {
            if (value[i] != 0) {
                isZero = PR_FALSE; /* nope */
                break;
            }
        }
    }
    PORT_Free(keyID.pValue);
    return isZero;
}

/*
 * Create an NSSCertificate from a slot/certID pair, return it as a
 * CERTCertificate.  Optionally, output the nickname string.
 */
static CERTCertificate *
pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
              CK_ATTRIBUTE *privateLabel, char **nickptr)
{
    NSSCertificate *c;
    nssCryptokiObject *co = NULL;
    nssPKIObject *pkio;
    NSSToken *token;
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();

    /* Get the cryptoki object from the handle */
    token = PK11Slot_GetNSSToken(slot);
    if (token->defaultSession) {
        co = nssCryptokiObject_Create(token, token->defaultSession, certID);
    } else {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
    }
    if (!co) {
        return NULL;
    }

    /* Create a PKI object from the cryptoki instance */
    pkio = nssPKIObject_Create(NULL, co, td, NULL, nssPKIMonitor);
    if (!pkio) {
        nssCryptokiObject_Destroy(co);
        return NULL;
    }

    /* Create a certificate */
    c = nssCertificate_Create(pkio);
    if (!c) {
        nssPKIObject_Destroy(pkio);
        return NULL;
    }

    /* Build and output a nickname, if desired.
     * This must be done before calling nssTrustDomain_AddCertsToCache
     * because that function may destroy c, pkio and co!
     */
    if ((nickptr) && (co->label)) {
        CK_ATTRIBUTE label, id;

        label.type = CKA_LABEL;
        label.pValue = co->label;
        label.ulValueLen = PORT_Strlen(co->label);

        id.type = CKA_ID;
        id.pValue = c->id.data;
        id.ulValueLen = c->id.size;

        *nickptr = pk11_buildNickname(slot, &label, privateLabel, &id);
    }

    /* This function may destroy the cert in "c" and all its subordinate
     * structures, and replace the value in "c" with the address of a
     * different NSSCertificate that it found in the cache.
     * Presumably, the nickname which we just output above remains valid. :)
     */
    (void)nssTrustDomain_AddCertsToCache(td, &c, 1);
    return STAN_GetCERTCertificateOrRelease(c);
}

/*
 * Build an CERTCertificate structure from a PKCS#11 object ID.... certID
 * Must be a CertObject. This code does not explicitly checks that.
 */
CERTCertificate *
PK11_MakeCertFromHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
                        CK_ATTRIBUTE *privateLabel)
{
    char *nickname = NULL;
    CERTCertificate *cert = NULL;
    CERTCertTrust *trust;

    cert = pk11_fastCert(slot, certID, privateLabel, &nickname);
    if (cert == NULL)
        goto loser;

    if (nickname) {
        if (cert->nickname != NULL) {
            cert->dbnickname = cert->nickname;
        }
        cert->nickname = PORT_ArenaStrdup(cert->arena, nickname);
        PORT_Free(nickname);
        nickname = NULL;
    }

    /* remember where this cert came from.... If we have just looked
     * it up from the database and it already has a slot, don't add a new
     * one. */
    if (cert->slot == NULL) {
        cert->slot = PK11_ReferenceSlot(slot);
        cert->pkcs11ID = certID;
        cert->ownSlot = PR_TRUE;
        cert->series = slot->series;
    }

    trust = (CERTCertTrust *)PORT_ArenaAlloc(cert->arena, sizeof(CERTCertTrust));
    if (trust == NULL)
        goto loser;
    PORT_Memset(trust, 0, sizeof(CERTCertTrust));

    if (!pk11_HandleTrustObject(slot, cert, trust)) {
        unsigned int type;

        /* build some cert trust flags */
        if (CERT_IsCACert(cert, &type)) {
            unsigned int trustflags = CERTDB_VALID_CA;

            /* Allow PKCS #11 modules to give us trusted CA's. We only accept
             * valid CA's which are self-signed here. They must have an object
             * ID of '0'.  */
            if (pk11_isID0(slot, certID) &&
                cert->isRoot) {
                trustflags |= CERTDB_TRUSTED_CA;
                /* is the slot a fortezza card? allow the user or
                 * admin to turn on objectSigning, but don't turn
                 * full trust on explicitly */
                if (PK11_DoesMechanism(slot, CKM_KEA_KEY_DERIVE)) {
                    trust->objectSigningFlags |= CERTDB_VALID_CA;
                }
            }
            if ((type & NS_CERT_TYPE_SSL_CA) == NS_CERT_TYPE_SSL_CA) {
                trust->sslFlags |= trustflags;
            }
            if ((type & NS_CERT_TYPE_EMAIL_CA) == NS_CERT_TYPE_EMAIL_CA) {
                trust->emailFlags |= trustflags;
            }
            if ((type & NS_CERT_TYPE_OBJECT_SIGNING_CA) == NS_CERT_TYPE_OBJECT_SIGNING_CA) {
                trust->objectSigningFlags |= trustflags;
            }
        }
    }

    if (PK11_IsUserCert(slot, cert, certID)) {
        trust->sslFlags |= CERTDB_USER;
        trust->emailFlags |= CERTDB_USER;
        /*    trust->objectSigningFlags |= CERTDB_USER; */
    }
    CERT_LockCertTrust(cert);
    cert->trust = trust;
    CERT_UnlockCertTrust(cert);

    return cert;

loser:
    if (nickname)
        PORT_Free(nickname);
    if (cert)
        CERT_DestroyCertificate(cert);
    return NULL;
}

/*
 * Build get a certificate from a private key
 */
CERTCertificate *
PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey)
{
    PK11SlotInfo *slot = privKey->pkcs11Slot;
    CK_OBJECT_HANDLE handle = privKey->pkcs11ID;
    CK_OBJECT_HANDLE certID =
        PK11_MatchItem(slot, handle, CKO_CERTIFICATE);
    CERTCertificate *cert;

    if (certID == CK_INVALID_HANDLE) {
        PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
        return NULL;
    }
    cert = PK11_MakeCertFromHandle(slot, certID, NULL);
    return (cert);
}

/*
 * delete a cert and it's private key (if no other certs are pointing to the
 * private key.
 */
SECStatus
PK11_DeleteTokenCertAndKey(CERTCertificate *cert, void *wincx)
{
    SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(cert, wincx);
    CK_OBJECT_HANDLE pubKey;
    PK11SlotInfo *slot = NULL;

    pubKey = pk11_FindPubKeyByAnyCert(cert, &slot, wincx);
    if (privKey) {
        /* For 3.4, utilize the generic cert delete function */
        SEC_DeletePermCertificate(cert);
        PK11_DeleteTokenPrivateKey(privKey, PR_FALSE);
    }
    if ((pubKey != CK_INVALID_HANDLE) && (slot != NULL)) {
        PK11_DestroyTokenObject(slot, pubKey);
        PK11_FreeSlot(slot);
    }
    return SECSuccess;
}

/*
 * cert callback structure
 */
typedef struct pk11DoCertCallbackStr {
    SECStatus (*callback)(PK11SlotInfo *slot, CERTCertificate *, void *);
    SECStatus (*noslotcallback)(CERTCertificate *, void *);
    SECStatus (*itemcallback)(CERTCertificate *, SECItem *, void *);
    void *callbackArg;
} pk11DoCertCallback;

typedef struct pk11CertCallbackStr {
    SECStatus (*callback)(CERTCertificate *, SECItem *, void *);
    void *callbackArg;
} pk11CertCallback;

struct fake_der_cb_argstr {
    SECStatus (*callback)(CERTCertificate *, SECItem *, void *);
    void *arg;
};

static SECStatus
fake_der_cb(CERTCertificate *c, void *a)
{
    struct fake_der_cb_argstr *fda = (struct fake_der_cb_argstr *)a;
    return (*fda->callback)(c, &c->derCert, fda->arg);
}

/*
 * Extract all the certs on a card from a slot.
 */
SECStatus
PK11_TraverseSlotCerts(SECStatus (*callback)(CERTCertificate *, SECItem *, void *),
                       void *arg, void *wincx)
{
    NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
    struct fake_der_cb_argstr fda;
    struct nss3_cert_cbstr pk11cb;

    /* authenticate to the tokens first */
    (void)pk11_TraverseAllSlots(NULL, NULL, PR_TRUE, wincx);

    fda.callback = callback;
    fda.arg = arg;
    pk11cb.callback = fake_der_cb;
    pk11cb.arg = &fda;
    NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb);
    return SECSuccess;
}

static void
transfer_token_certs_to_collection(nssList *certList, NSSToken *token,
                                   nssPKIObjectCollection *collection)
{
    NSSCertificate **certs;
    PRUint32 i, count;
    NSSToken **tokens, **tp;
    count = nssList_Count(certList);
    if (count == 0) {
        return;
    }
    certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
    if (!certs) {
        return;
    }
    nssList_GetArray(certList, (void **)certs, count);
    for (i = 0; i < count; i++) {
        tokens = nssPKIObject_GetTokens(&certs[i]->object, NULL);
        if (tokens) {
            for (tp = tokens; *tp; tp++) {
                if (*tp == token) {
                    nssPKIObjectCollection_AddObject(collection,
                                                     (nssPKIObject *)certs[i]);
                }
            }
            nssTokenArray_Destroy(tokens);
        }
        CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(certs[i]));
    }
    nss_ZFreeIf(certs);
}

static void
transfer_uri_certs_to_collection(nssList *certList, PK11URI *uri,
                                 nssPKIObjectCollection *collection)
{

    NSSCertificate **certs;
    PRUint32 i, count;
    NSSToken **tokens, **tp;
    PK11SlotInfo *slot;
    const char *id;

    id = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_ID);
    count = nssList_Count(certList);
    if (count == 0) {
        return;
    }
    certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
    if (!certs) {
        return;
    }
    nssList_GetArray(certList, (void **)certs, count);
    for (i = 0; i < count; i++) {
        /*
	 * Filter the subject matched certs based on the
	 * CKA_ID from the URI
	 */
        if (id && (strlen(id) != certs[i]->id.size ||
                   memcmp(id, certs[i]->id.data, certs[i]->id.size)))
            continue;
        tokens = nssPKIObject_GetTokens(&certs[i]->object, NULL);
        if (tokens) {
            for (tp = tokens; *tp; tp++) {
                const char *value;
                slot = (*tp)->pk11slot;

                value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_TOKEN);
                if (value &&
                    !pk11_MatchString(value,
                                      (char *)slot->tokenInfo.label,
                                      sizeof(slot->tokenInfo.label))) {
                    continue;
                }

                value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_MANUFACTURER);
                if (value &&
                    !pk11_MatchString(value,
                                      (char *)slot->tokenInfo.manufacturerID,
                                      sizeof(slot->tokenInfo.manufacturerID))) {
                    continue;
                }

                value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_MODEL);
                if (value &&
                    !pk11_MatchString(value,
                                      (char *)slot->tokenInfo.model,
                                      sizeof(slot->tokenInfo.model))) {
                    continue;
                }

                nssPKIObjectCollection_AddObject(collection,
                                                 (nssPKIObject *)certs[i]);
                break;
            }
            nssTokenArray_Destroy(tokens);
        }
        CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(certs[i]));
    }
    nss_ZFreeIf(certs);
}

static NSSCertificate **
find_certs_from_uri(const char *uriString, void *wincx)
{
    PK11URI *uri = NULL;
    CK_ATTRIBUTE attributes[10];
    CK_ULONG nattributes = 0;
    const char *label;
    PK11SlotInfo *slotinfo;
    nssCryptokiObject **instances;
    PRStatus status;
    nssPKIObjectCollection *collection = NULL;
    NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
    NSSCertificate **certs = NULL;
    nssList *certList = NULL;
    SECStatus rv;
    CK_OBJECT_CLASS s_class = CKO_CERTIFICATE;
    static const CK_BBOOL s_true = CK_TRUE;
    NSSToken **tokens, **tok;

    uri = PK11URI_ParseURI(uriString);
    if (uri == NULL) {
        goto loser;
    }

    collection = nssCertificateCollection_Create(defaultTD, NULL);
    if (!collection) {
        goto loser;
    }
    certList = nssList_Create(NULL, PR_FALSE);
    if (!certList) {
        goto loser;
    }

    label = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_OBJECT);
    if (label) {
        (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
                                                          (const char *)label,
                                                          certList);
    } else {
        (void)nssTrustDomain_GetCertsFromCache(defaultTD, certList);
    }

    transfer_uri_certs_to_collection(certList, uri, collection);

    /* add the CKA_CLASS and CKA_TOKEN attributes manually */
    attributes[nattributes].type = CKA_CLASS;
    attributes[nattributes].pValue = (void *)&s_class;
    attributes[nattributes].ulValueLen = sizeof(s_class);
    nattributes++;

    attributes[nattributes].type = CKA_TOKEN;
    attributes[nattributes].pValue = (void *)&s_true;
    attributes[nattributes].ulValueLen = sizeof(s_true);
    nattributes++;

    if (label) {
        attributes[nattributes].type = CKA_LABEL;
        attributes[nattributes].pValue = (void *)label;
        attributes[nattributes].ulValueLen = strlen(label);
        nattributes++;
    }

    tokens = NSSTrustDomain_FindTokensByURI(defaultTD, uri);
    for (tok = tokens; tok && *tok; tok++) {
        if (nssToken_IsPresent(*tok)) {
            slotinfo = (*tok)->pk11slot;

            rv = pk11_AuthenticateUnfriendly(slotinfo, PR_TRUE, wincx);
            if (rv != SECSuccess) {
                continue;
            }
            instances = nssToken_FindObjectsByTemplate(*tok, NULL,
                                                       attributes,
                                                       nattributes,
                                                       0, &status);
            nssPKIObjectCollection_AddInstances(collection, instances, 0);
            nss_ZFreeIf(instances);
        }
        nssToken_Destroy(*tok);
    }
    nss_ZFreeIf(tokens);
    nssList_Destroy(certList);
    certs = nssPKIObjectCollection_GetCertificates(collection, NULL, 0, NULL);

loser:
    if (collection) {
        nssPKIObjectCollection_Destroy(collection);
    }
    if (uri) {
        PK11URI_DestroyURI(uri);
    }
    return certs;
}

CERTCertificate *
PK11_FindCertFromURI(const char *uri, void *wincx)
{
    static const NSSUsage usage = { PR_TRUE /* ... */ };
    NSSCertificate *cert = NULL;
    NSSCertificate **certs = NULL;
    CERTCertificate *rvCert = NULL;

    certs = find_certs_from_uri(uri, wincx);
    if (certs) {
        cert = nssCertificateArray_FindBestCertificate(certs, NULL,
                                                       &usage, NULL);
        if (cert) {
            rvCert = STAN_GetCERTCertificateOrRelease(cert);
        }
        nssCertificateArray_Destroy(certs);
    }
    return rvCert;
}

CERTCertList *
PK11_FindCertsFromURI(const char *uri, void *wincx)
{
    int i;
    CERTCertList *certList = NULL;
    NSSCertificate **foundCerts;
    NSSCertificate *c;

    foundCerts = find_certs_from_uri(uri, wincx);
    if (foundCerts) {
        PRTime now = PR_Now();
        certList = CERT_NewCertList();
        for (i = 0, c = *foundCerts; c; c = foundCerts[++i]) {
            if (certList) {
                CERTCertificate *certCert = STAN_GetCERTCertificateOrRelease(c);
                /* c may be invalid after this, don't reference it */
                if (certCert) {
                    /* CERT_AddCertToListSorted adopts certCert  */
                    CERT_AddCertToListSorted(certList, certCert,
                                             CERT_SortCBValidity, &now);
                }
            } else {
                nssCertificate_Destroy(c);
            }
        }
        if (certList && CERT_LIST_HEAD(certList) == NULL) {
            CERT_DestroyCertList(certList);
            certList = NULL;
        }
        /* all the certs have been adopted or freed, free the  raw array */
        nss_ZFreeIf(foundCerts);
    }
    return certList;
}

static NSSCertificate **
find_certs_from_nickname(const char *nickname, void *wincx)
{
    PRStatus status;
    NSSCertificate **certs = NULL;
    NSSToken *token = NULL;
    NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
    PK11SlotInfo *slot = NULL;
    SECStatus rv;
    char *nickCopy;
    char *delimit = NULL;
    char *tokenName;

    if (!PORT_Strncasecmp(nickname, "pkcs11:", strlen("pkcs11:"))) {
        certs = find_certs_from_uri(nickname, wincx);
        if (certs)
            return certs;
    }
    nickCopy = PORT_Strdup(nickname);
    if (!nickCopy) {
        /* error code is set */
        return NULL;
    }
    if ((delimit = PORT_Strchr(nickCopy, ':')) != NULL) {
        tokenName = nickCopy;
        nickname = delimit + 1;
        *delimit = '\0';
        /* find token by name */
        token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
        if (token) {
            slot = PK11_ReferenceSlot(token->pk11slot);
        } else {
            PORT_SetError(SEC_ERROR_NO_TOKEN);
        }
        *delimit = ':';
    } else {
        slot = PK11_GetInternalKeySlot();
        token = PK11Slot_GetNSSToken(slot);
        if (token) {
            nssToken_AddRef(token);
        } else {
            PORT_SetError(SEC_ERROR_NO_TOKEN);
        }
    }
    if (token) {
        nssList *certList;
        nssCryptokiObject **instances;
        nssPKIObjectCollection *collection;
        nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
        if (!PK11_IsPresent(slot)) {
            goto loser;
        }
        rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
        if (rv != SECSuccess) {
            goto loser;
        }
        collection = nssCertificateCollection_Create(defaultTD, NULL);
        if (!collection) {
            goto loser;
        }
        certList = nssList_Create(NULL, PR_FALSE);
        if (!certList) {
            nssPKIObjectCollection_Destroy(collection);
            goto loser;
        }
        (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
                                                          nickname,
                                                          certList);
        transfer_token_certs_to_collection(certList, token, collection);
        instances = nssToken_FindCertificatesByNickname(token,
                                                        NULL,
                                                        nickname,
                                                        tokenOnly,
                                                        0,
                                                        &status);
        nssPKIObjectCollection_AddInstances(collection, instances, 0);
        nss_ZFreeIf(instances);
        /* if it wasn't found, repeat the process for email address */
        if (nssPKIObjectCollection_Count(collection) == 0 &&
            PORT_Strchr(nickname, '@') != NULL) {
            char *lowercaseName = CERT_FixupEmailAddr(nickname);
            if (lowercaseName) {
                (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
                                                                      lowercaseName,
                                                                      certList);
                transfer_token_certs_to_collection(certList, token, collection);
                instances = nssToken_FindCertificatesByEmail(token,
                                                             NULL,
                                                             lowercaseName,
                                                             tokenOnly,
                                                             0,
                                                             &status);
                nssPKIObjectCollection_AddInstances(collection, instances, 0);
                nss_ZFreeIf(instances);
                PORT_Free(lowercaseName);
            }
        }
        certs = nssPKIObjectCollection_GetCertificates(collection,
                                                       NULL, 0, NULL);
        nssPKIObjectCollection_Destroy(collection);
        nssList_Destroy(certList);
    }
loser:
    if (token) {
        nssToken_Destroy(token);
    }
    if (slot) {
        PK11_FreeSlot(slot);
    }
    if (nickCopy)
        PORT_Free(nickCopy);
    return certs;
}

CERTCertificate *
PK11_FindCertFromNickname(const char *nickname, void *wincx)
{
    CERTCertificate *rvCert = NULL;
    NSSCertificate *cert = NULL;
    NSSCertificate **certs = NULL;
    static const NSSUsage usage = { PR_TRUE /* ... */ };

    certs = find_certs_from_nickname(nickname, wincx);
    if (certs) {
        cert = nssCertificateArray_FindBestCertificate(certs, NULL,
                                                       &usage, NULL);
        if (cert) {
            rvCert = STAN_GetCERTCertificateOrRelease(cert);
        }
        nssCertificateArray_Destroy(certs);
    }
    return rvCert;
}

/* Traverse slots callback */
typedef struct FindCertsEmailArgStr {
    char *email;
    CERTCertList *certList;
} FindCertsEmailArg;

SECStatus
FindCertsEmailCallback(CERTCertificate *cert, SECItem *item, void *arg)
{
    FindCertsEmailArg *cbparam = (FindCertsEmailArg *)arg;
    const char *cert_email = CERT_GetFirstEmailAddress(cert);
    PRBool found = PR_FALSE;

    /* Email address present in certificate? */
    if (cert_email == NULL) {
        return SECSuccess;
    }

    /* Parameter correctly set? */
    if (cbparam->email == NULL) {
        return SECFailure;
    }

    /* Loop over all email addresses */
    do {
        if (!strcmp(cert_email, cbparam->email)) {
            /* found one matching email address */
            PRTime now = PR_Now();
            found = PR_TRUE;
            CERT_AddCertToListSorted(cbparam->certList,
                                     CERT_DupCertificate(cert),
                                     CERT_SortCBValidity, &now);
        }
        cert_email = CERT_GetNextEmailAddress(cert, cert_email);
    } while (cert_email && !found);

    return SECSuccess;
}

/* Find all certificates with matching email address */
CERTCertList *
PK11_FindCertsFromEmailAddress(const char *email, void *wincx)
{
    FindCertsEmailArg cbparam;
    SECStatus rv;

    cbparam.certList = CERT_NewCertList();
    if (cbparam.certList == NULL) {
        return NULL;
    }

    cbparam.email = CERT_FixupEmailAddr(email);
    if (cbparam.email == NULL) {
        CERT_DestroyCertList(cbparam.certList);
        return NULL;
    }

    rv = PK11_TraverseSlotCerts(FindCertsEmailCallback, &cbparam, NULL);
    if (rv != SECSuccess) {
        CERT_DestroyCertList(cbparam.certList);
        PORT_Free(cbparam.email);
        return NULL;
    }

    /* empty list? */
    if (CERT_LIST_EMPTY(cbparam.certList)) {
        CERT_DestroyCertList(cbparam.certList);
        cbparam.certList = NULL;
    }

    PORT_Free(cbparam.email);
    return cbparam.certList;
}

CERTCertList *
PK11_FindCertsFromNickname(const char *nickname, void *wincx)
{
    int i;
    CERTCertList *certList = NULL;
    NSSCertificate **foundCerts = NULL;
    NSSCertificate *c;

    foundCerts = find_certs_from_nickname(nickname, wincx);
    if (foundCerts) {
        PRTime now = PR_Now();
        certList = CERT_NewCertList();
        for (i = 0, c = *foundCerts; c; c = foundCerts[++i]) {
            if (certList) {
                CERTCertificate *certCert = STAN_GetCERTCertificateOrRelease(c);
                /* c may be invalid after this, don't reference it */
                if (certCert) {
                    /* CERT_AddCertToListSorted adopts certCert  */
                    CERT_AddCertToListSorted(certList, certCert,
                                             CERT_SortCBValidity, &now);
                }
            } else {
                nssCertificate_Destroy(c);
            }
        }
        /* all the certs have been adopted or freed, free the  raw array */
        nss_ZFreeIf(foundCerts);
    }
    return certList;
}

/*
 * extract a key ID for a certificate...
 * NOTE: We call this function from PKCS11.c If we ever use
 * pkcs11 to extract the public key (we currently do not), this will break.
 */
SECItem *
PK11_GetPubIndexKeyID(CERTCertificate *cert)
{
    SECKEYPublicKey *pubk;
    SECItem *newItem = NULL;

    pubk = CERT_ExtractPublicKey(cert);
    if (pubk == NULL)
        return NULL;

    switch (pubk->keyType) {
        case rsaKey:
            newItem = SECITEM_DupItem(&pubk->u.rsa.modulus);
            break;
        case dsaKey:
            newItem = SECITEM_DupItem(&pubk->u.dsa.publicValue);
            break;
        case dhKey:
            newItem = SECITEM_DupItem(&pubk->u.dh.publicValue);
            break;
        case ecKey:
            newItem = SECITEM_DupItem(&pubk->u.ec.publicValue);
            break;
        case fortezzaKey:
        default:
            newItem = NULL; /* Fortezza Fix later... */
    }
    SECKEY_DestroyPublicKey(pubk);
    /* make hash of it */
    return newItem;
}

/*
 * generate a CKA_ID from a certificate.
 */
SECItem *
pk11_mkcertKeyID(CERTCertificate *cert)
{
    SECItem *pubKeyData = PK11_GetPubIndexKeyID(cert);
    SECItem *certCKA_ID;

    if (pubKeyData == NULL)
        return NULL;

    certCKA_ID = PK11_MakeIDFromPubKey(pubKeyData);
    SECITEM_FreeItem(pubKeyData, PR_TRUE);
    return certCKA_ID;
}

/*
 * Write the cert into the token.
 */
SECStatus
PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
                CK_OBJECT_HANDLE key, const char *nickname,
                PRBool includeTrust)
{
    PRStatus status;
    NSSCertificate *c;
    nssCryptokiObject *keyobj, *certobj;
    NSSToken *token = PK11Slot_GetNSSToken(slot);
    SECItem *keyID = pk11_mkcertKeyID(cert);
    char *emailAddr = NULL;
    nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
    nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };

    if (keyID == NULL) {
        goto loser; /* error code should be set already */
    }
    if (!token) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        goto loser;
    }

    if (PK11_IsInternal(slot) && cert->emailAddr && cert->emailAddr[0]) {
        emailAddr = cert->emailAddr;
    }

    /* need to get the cert as a stan cert */
    if (cert->nssCertificate) {
        c = cert->nssCertificate;
    } else {
        c = STAN_GetNSSCertificate(cert);
        if (c == NULL) {
            goto loser;
        }
    }

    /* set the id for the cert */
    nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data);
    if (!c->id.data) {
        goto loser;
    }

    if (key != CK_INVALID_HANDLE) {
        /* create an object for the key, ... */
        keyobj = nss_ZNEW(NULL, nssCryptokiObject);
        if (!keyobj) {
            goto loser;
        }
        keyobj->token = nssToken_AddRef(token);
        keyobj->handle = key;
        keyobj->isTokenObject = PR_TRUE;

        /* ... in order to set matching attributes for the key */
        status = nssCryptokiPrivateKey_SetCertificate(keyobj, NULL, nickname,
                                                      &c->id, &c->subject);
        nssCryptokiObject_Destroy(keyobj);
        if (status != PR_SUCCESS) {
            goto loser;
        }
    }

    /* do the token import */
    certobj = nssToken_ImportCertificate(token, NULL,
                                         NSSCertificateType_PKIX,
                                         &c->id,
                                         nickname,
                                         &c->encoding,
                                         &c->issuer,
                                         &c->subject,
                                         &c->serial,
                                         emailAddr,
                                         PR_TRUE);
    if (!certobj) {
        if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) {
            PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL);
            SECITEM_FreeItem(keyID, PR_TRUE);
            return SECFailure;
        }
        goto loser;
    }

    if (c->object.cryptoContext) {
        /* Delete the temp instance */
        NSSCryptoContext *cc = c->object.cryptoContext;
        nssCertificateStore_Lock(cc->certStore, &lockTrace);
        nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
        nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace);
        c->object.cryptoContext = NULL;
        CERT_LockCertTempPerm(cert);
        cert->istemp = PR_FALSE;
        cert->isperm = PR_TRUE;
        CERT_UnlockCertTempPerm(cert);
    }

    /* add the new instance to the cert, force an update of the
     * CERTCertificate, and finish
     */
    nssPKIObject_AddInstance(&c->object, certobj);
    /* nssTrustDomain_AddCertsToCache may release a reference to 'c' and
     * replace 'c' with a different value. So we add a reference to 'c' to
     * prevent 'c' from being destroyed. */
    nssCertificate_AddRef(c);
    nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
    (void)STAN_ForceCERTCertificateUpdate(c);
    nssCertificate_Destroy(c);
    SECITEM_FreeItem(keyID, PR_TRUE);
    return SECSuccess;
loser:
    CERT_MapStanError();
    SECITEM_FreeItem(keyID, PR_TRUE);
    if (PORT_GetError() != SEC_ERROR_TOKEN_NOT_LOGGED_IN) {
        PORT_SetError(SEC_ERROR_ADDING_CERT);
    }
    return SECFailure;
}

SECStatus
PK11_ImportDERCert(PK11SlotInfo *slot, SECItem *derCert,
                   CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust)
{
    CERTCertificate *cert;
    SECStatus rv;

    cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                   derCert, NULL, PR_FALSE, PR_TRUE);
    if (cert == NULL)
        return SECFailure;

    rv = PK11_ImportCert(slot, cert, key, nickname, includeTrust);
    CERT_DestroyCertificate(cert);
    return rv;
}

/*
 * get a certificate handle, look at the cached handle first..
 */
CK_OBJECT_HANDLE
pk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert,
                   CK_ATTRIBUTE *theTemplate, int tsize)
{
    CK_OBJECT_HANDLE certh;

    if (cert->slot == slot) {
        certh = cert->pkcs11ID;
        if ((certh == CK_INVALID_HANDLE) ||
            (cert->series != slot->series)) {
            certh = pk11_FindObjectByTemplate(slot, theTemplate, tsize);
            cert->pkcs11ID = certh;
            cert->series = slot->series;
        }
    } else {
        certh = pk11_FindObjectByTemplate(slot, theTemplate, tsize);
    }
    return certh;
}

/*
 * return the private key From a given Cert
 */
SECKEYPrivateKey *
PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert,
                            void *wincx)
{
    int err;
    CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
    CK_ATTRIBUTE theTemplate[] = {
        { CKA_VALUE, NULL, 0 },
        { CKA_CLASS, NULL, 0 }
    };
    /* if you change the array, change the variable below as well */
    int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
    CK_OBJECT_HANDLE certh;
    CK_OBJECT_HANDLE keyh;
    CK_ATTRIBUTE *attrs = theTemplate;
    PRBool needLogin;
    SECStatus rv;

    PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data,
                  cert->derCert.len);
    attrs++;
    PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));

    /*
     * issue the find
     */
    rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
    if (rv != SECSuccess) {
        return NULL;
    }

    certh = pk11_getcerthandle(slot, cert, theTemplate, tsize);
    if (certh == CK_INVALID_HANDLE) {
        return NULL;
    }
    /*
     * prevent a login race condition. If slot is logged in between
     * our call to pk11_LoginStillRequired and the
     * PK11_MatchItem. The matchItem call will either succeed, or
     * we will call it one more time after calling PK11_Authenticate
     * (which is a noop on an authenticated token).
     */
    needLogin = pk11_LoginStillRequired(slot, wincx);
    keyh = PK11_MatchItem(slot, certh, CKO_PRIVATE_KEY);
    if ((keyh == CK_INVALID_HANDLE) && needLogin &&
        (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) ||
         SEC_ERROR_TOKEN_NOT_LOGGED_IN == err)) {
        /* try it again authenticated */
        rv = PK11_Authenticate(slot, PR_TRUE, wincx);
        if (rv != SECSuccess) {
            return NULL;
        }
        keyh = PK11_MatchItem(slot, certh, CKO_PRIVATE_KEY);
    }
    if (keyh == CK_INVALID_HANDLE) {
        return NULL;
    }
    return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyh, wincx);
}

/*
 * import a cert for a private key we have already generated. Set the label
 * on both to be the nickname. This is for the Key Gen, orphaned key case.
 */
PK11SlotInfo *
PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr,
                      void *wincx)
{
    PK11SlotList *list;
    PK11SlotListElement *le;
    SECItem *keyID;
    CK_OBJECT_HANDLE key;
    PK11SlotInfo *slot = NULL;
    SECStatus rv;
    int err;

    keyID = pk11_mkcertKeyID(cert);
    /* get them all! */
    list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, wincx);
    if ((keyID == NULL) || (list == NULL)) {
        if (keyID)
            SECITEM_FreeItem(keyID, PR_TRUE);
        if (list)
            PK11_FreeSlotList(list);
        return NULL;
    }

    /* Look for the slot that holds the Key */
    for (le = list->head; le; le = le->next) {
        /*
         * prevent a login race condition. If le->slot is logged in between
         * our call to pk11_LoginStillRequired and the
         * pk11_FindPrivateKeyFromCertID, the find will either succeed, or
         * we will call it one more time after calling PK11_Authenticate
         * (which is a noop on an authenticated token).
         */
        PRBool needLogin = pk11_LoginStillRequired(le->slot, wincx);
        key = pk11_FindPrivateKeyFromCertID(le->slot, keyID);
        if ((key == CK_INVALID_HANDLE) && needLogin &&
            (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) ||
             SEC_ERROR_TOKEN_NOT_LOGGED_IN == err)) {
            /* authenticate and try again */
            rv = PK11_Authenticate(le->slot, PR_TRUE, wincx);
            if (rv != SECSuccess)
                continue;
            key = pk11_FindPrivateKeyFromCertID(le->slot, keyID);
        }
        if (key != CK_INVALID_HANDLE) {
            slot = PK11_ReferenceSlot(le->slot);
            if (keyPtr)
                *keyPtr = key;
            break;
        }
    }

    SECITEM_FreeItem(keyID, PR_TRUE);
    PK11_FreeSlotList(list);
    return slot;
}
/*
 * import a cert for a private key we have already generated. Set the label
 * on both to be the nickname. This is for the Key Gen, orphaned key case.
 */
PK11SlotInfo *
PK11_KeyForDERCertExists(SECItem *derCert, CK_OBJECT_HANDLE *keyPtr,
                         void *wincx)
{
    CERTCertificate *cert;
    PK11SlotInfo *slot = NULL;

    /* letting this use go -- the only thing that the cert is used for is
     * to get the ID attribute.
     */
    cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
    if (cert == NULL)
        return NULL;

    slot = PK11_KeyForCertExists(cert, keyPtr, wincx);
    CERT_DestroyCertificate(cert);
    return slot;
}

PK11SlotInfo *
PK11_ImportCertForKey(CERTCertificate *cert, const char *nickname,
                      void *wincx)
{
    PK11SlotInfo *slot = NULL;
    CK_OBJECT_HANDLE key;

    slot = PK11_KeyForCertExists(cert, &key, wincx);

    if (slot) {
        if (PK11_ImportCert(slot, cert, key, nickname, PR_FALSE) != SECSuccess) {
            PK11_FreeSlot(slot);
            slot = NULL;
        }
    } else {
        PORT_SetError(SEC_ERROR_ADDING_CERT);
    }

    return slot;
}

PK11SlotInfo *
PK11_ImportDERCertForKey(SECItem *derCert, char *nickname, void *wincx)
{
    CERTCertificate *cert;
    PK11SlotInfo *slot = NULL;

    cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                   derCert, NULL, PR_FALSE, PR_TRUE);
    if (cert == NULL)
        return NULL;

    slot = PK11_ImportCertForKey(cert, nickname, wincx);
    CERT_DestroyCertificate(cert);
    return slot;
}

static CK_OBJECT_HANDLE
pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
                              CK_ATTRIBUTE *searchTemplate, int count, void *wincx)
{
    PK11SlotList *list;
    PK11SlotListElement *le;
    CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
    PK11SlotInfo *slot = NULL;
    SECStatus rv;

    *slotPtr = NULL;

    /* get them all! */
    list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, wincx);
    if (list == NULL) {
        return CK_INVALID_HANDLE;
    }

    /* Look for the slot that holds the Key */
    for (le = list->head; le; le = le->next) {
        rv = pk11_AuthenticateUnfriendly(le->slot, PR_TRUE, wincx);
        if (rv != SECSuccess)
            continue;

        certHandle = pk11_FindObjectByTemplate(le->slot, searchTemplate, count);
        if (certHandle != CK_INVALID_HANDLE) {
            slot = PK11_ReferenceSlot(le->slot);
            break;
        }
    }

    PK11_FreeSlotList(list);

    if (slot == NULL) {
        return CK_INVALID_HANDLE;
    }
    *slotPtr = slot;
    return certHandle;
}

CERTCertificate *
PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
                                  CERTIssuerAndSN *issuerSN, void *wincx)
{
    CERTCertificate *rvCert = NULL;
    NSSCertificate *cert = NULL;
    NSSDER issuer, serial;
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
    NSSToken *token = slot->nssToken;
    nssSession *session;
    nssCryptokiObject *instance = NULL;
    nssPKIObject *object = NULL;
    SECItem *derSerial;
    PRStatus status;

    if (!issuerSN || !issuerSN->derIssuer.data || !issuerSN->derIssuer.len ||
        !issuerSN->serialNumber.data || !issuerSN->serialNumber.len ||
        issuerSN->derIssuer.len > CERT_MAX_DN_BYTES ||
        issuerSN->serialNumber.len > CERT_MAX_SERIAL_NUMBER_BYTES) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    /* Paranoia */
    if (token == NULL) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return NULL;
    }

    /* PKCS#11 needs to use DER-encoded serial numbers.  Create a
     * CERTIssuerAndSN that actually has the encoded value and pass that
     * to PKCS#11 (and the crypto context).
     */
    derSerial = SEC_ASN1EncodeItem(NULL, NULL,
                                   &issuerSN->serialNumber,
                                   SEC_ASN1_GET(SEC_IntegerTemplate));
    if (!derSerial) {
        return NULL;
    }

    NSSITEM_FROM_SECITEM(&issuer, &issuerSN->derIssuer);
    NSSITEM_FROM_SECITEM(&serial, derSerial);

    session = nssToken_GetDefaultSession(token);
    if (!session) {
        goto loser;
    }

    instance = nssToken_FindCertificateByIssuerAndSerialNumber(token, session,
                                                               &issuer, &serial, nssTokenSearchType_TokenForced, &status);

    SECITEM_FreeItem(derSerial, PR_TRUE);

    if (!instance) {
        goto loser;
    }
    object = nssPKIObject_Create(NULL, instance, td, NULL, nssPKIMonitor);
    if (!object) {
        goto loser;
    }
    instance = NULL; /* adopted by the previous call */
    cert = nssCertificate_Create(object);
    if (!cert) {
        goto loser;
    }
    object = NULL; /* adopted by the previous call */
    nssTrustDomain_AddCertsToCache(td, &cert, 1);
    /* on failure, cert is freed below */
    rvCert = STAN_GetCERTCertificate(cert);
    if (!rvCert) {
        goto loser;
    }
    return rvCert;

loser:
    if (instance) {
        nssCryptokiObject_Destroy(instance);
    }
    if (object) {
        nssPKIObject_Destroy(object);
    }
    if (cert) {
        nssCertificate_Destroy(cert);
    }
    return NULL;
}

static PRCallOnceType keyIDHashCallOnce;

static PRStatus PR_CALLBACK
pk11_keyIDHash_populate(void *wincx)
{
    CERTCertList *certList;
    CERTCertListNode *node = NULL;
    SECItem subjKeyID = { siBuffer, NULL, 0 };
    SECItem *slotid = NULL;
    SECMODModuleList *modules, *mlp;
    SECMODListLock *moduleLock;
    int i;

    certList = PK11_ListCerts(PK11CertListUser, wincx);
    if (!certList) {
        return PR_FAILURE;
    }

    for (node = CERT_LIST_HEAD(certList);
         !CERT_LIST_END(node, certList);
         node = CERT_LIST_NEXT(node)) {
        if (CERT_FindSubjectKeyIDExtension(node->cert,
                                           &subjKeyID) == SECSuccess &&
            subjKeyID.data != NULL) {
            cert_AddSubjectKeyIDMapping(&subjKeyID, node->cert);
            SECITEM_FreeItem(&subjKeyID, PR_FALSE);
        }
    }
    CERT_DestroyCertList(certList);

    /*
     * Record the state of each slot in a hash. The concatenation of slotID
     * and moduleID is used as its key, with the slot series as its value.
     */
    slotid = SECITEM_AllocItem(NULL, NULL,
                               sizeof(CK_SLOT_ID) + sizeof(SECMODModuleID));
    if (!slotid) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return PR_FAILURE;
    }
    moduleLock = SECMOD_GetDefaultModuleListLock();
    if (!moduleLock) {
        SECITEM_FreeItem(slotid, PR_TRUE);
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
        return PR_FAILURE;
    }
    SECMOD_GetReadLock(moduleLock);
    modules = SECMOD_GetDefaultModuleList();
    for (mlp = modules; mlp; mlp = mlp->next) {
        for (i = 0; i < mlp->module->slotCount; i++) {
            memcpy(slotid->data, &mlp->module->slots[i]->slotID,
                   sizeof(CK_SLOT_ID));
            memcpy(&slotid->data[sizeof(CK_SLOT_ID)], &mlp->module->moduleID,
                   sizeof(SECMODModuleID));
            cert_UpdateSubjectKeyIDSlotCheck(slotid,
                                             mlp->module->slots[i]->series);
        }
    }
    SECMOD_ReleaseReadLock(moduleLock);
    SECITEM_FreeItem(slotid, PR_TRUE);

    return PR_SUCCESS;
}

/*
 * We're looking for a cert which we have the private key for that's on the
 * list of recipients. This searches one slot.
 * this is the new version for NSS SMIME code
 * this stuff should REALLY be in the SMIME code, but some things in here are not public
 * (they should be!)
 */
static CERTCertificate *
pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipientlist,
                                  int *rlIndex, void *pwarg)
{
    NSSCMSRecipient *ri = NULL;
    int i;
    PRBool tokenRescanDone = PR_FALSE;
    CERTCertTrust trust;

    for (i = 0; (ri = recipientlist[i]) != NULL; i++) {
        CERTCertificate *cert = NULL;
        if (ri->kind == RLSubjKeyID) {
            SECItem *derCert = cert_FindDERCertBySubjectKeyID(ri->id.subjectKeyID);
            if (!derCert && !tokenRescanDone) {
                /*
                 * We didn't find the cert by its key ID. If we have slots
                 * with removable tokens, a failure from
                 * cert_FindDERCertBySubjectKeyID doesn't necessarily imply
                 * that the cert is unavailable - the token might simply
                 * have been inserted after the initial run of
                 * pk11_keyIDHash_populate (wrapped by PR_CallOnceWithArg),
                 * or a different token might have been present in that
                 * slot, initially. Let's check for new tokens...
                 */
                PK11SlotList *sl = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
                                                     PR_FALSE, PR_FALSE, pwarg);
                if (sl) {
                    PK11SlotListElement *le;
                    SECItem *slotid = SECITEM_AllocItem(NULL, NULL,
                                                        sizeof(CK_SLOT_ID) + sizeof(SECMODModuleID));
                    if (!slotid) {
                        PORT_SetError(SEC_ERROR_NO_MEMORY);
                        PK11_FreeSlotList(sl);
                        return NULL;
                    }
                    for (le = sl->head; le; le = le->next) {
                        memcpy(slotid->data, &le->slot->slotID,
                               sizeof(CK_SLOT_ID));
                        memcpy(&slotid->data[sizeof(CK_SLOT_ID)],
                               &le->slot->module->moduleID,
                               sizeof(SECMODModuleID));
                        /*
                         * Any changes with the slot since our last check?
                         * If so, re-read the certs in that specific slot.
                         */
                        if (cert_SubjectKeyIDSlotCheckSeries(slotid) != PK11_GetSlotSeries(le->slot)) {
                            CERTCertListNode *node = NULL;
                            SECItem subjKeyID = { siBuffer, NULL, 0 };
                            CERTCertList *cl = PK11_ListCertsInSlot(le->slot);
                            if (!cl) {
                                continue;
                            }
                            for (node = CERT_LIST_HEAD(cl);
                                 !CERT_LIST_END(node, cl);
                                 node = CERT_LIST_NEXT(node)) {
                                if (CERT_IsUserCert(node->cert) &&
                                    CERT_FindSubjectKeyIDExtension(node->cert,
                                                                   &subjKeyID) == SECSuccess) {
                                    if (subjKeyID.data) {
                                        cert_AddSubjectKeyIDMapping(&subjKeyID,
                                                                    node->cert);
                                        cert_UpdateSubjectKeyIDSlotCheck(slotid,
                                                                         PK11_GetSlotSeries(le->slot));
                                    }
                                    SECITEM_FreeItem(&subjKeyID, PR_FALSE);
                                }
                            }
                            CERT_DestroyCertList(cl);
                        }
                    }
                    PK11_FreeSlotList(sl);
                    SECITEM_FreeItem(slotid, PR_TRUE);
                }
                /* only check once per message/recipientlist */
                tokenRescanDone = PR_TRUE;
                /* do another lookup (hopefully we found that cert...) */
                derCert = cert_FindDERCertBySubjectKeyID(ri->id.subjectKeyID);
            }
            if (derCert) {
                cert = PK11_FindCertFromDERCertItem(slot, derCert, pwarg);
                SECITEM_FreeItem(derCert, PR_TRUE);
            }
        } else {
            cert = PK11_FindCertByIssuerAndSNOnToken(slot, ri->id.issuerAndSN,
                                                     pwarg);
        }
        if (cert) {
            /* this isn't our cert */
            if (CERT_GetCertTrust(cert, &trust) != SECSuccess ||
                ((trust.emailFlags & CERTDB_USER) != CERTDB_USER)) {
                CERT_DestroyCertificate(cert);
                continue;
            }
            ri->slot = PK11_ReferenceSlot(slot);
            *rlIndex = i;
            return cert;
        }
    }
    *rlIndex = -1;
    return NULL;
}

/*
 * This function is the same as above, but it searches all the slots.
 * this is the new version for NSS SMIME code
 * this stuff should REALLY be in the SMIME code, but some things in here are not public
 * (they should be!)
 */
static CERTCertificate *
pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *wincx, int *rlIndex)
{
    PK11SlotList *list;
    PK11SlotListElement *le;
    CERTCertificate *cert = NULL;
    SECStatus rv;

    /* get them all! */
    list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, wincx);
    if (list == NULL) {
        return CK_INVALID_HANDLE;
    }

    /* Look for the slot that holds the Key */
    for (le = list->head; le; le = le->next) {
        rv = pk11_AuthenticateUnfriendly(le->slot, PR_TRUE, wincx);
        if (rv != SECSuccess)
            continue;

        cert = pk11_FindCertObjectByRecipientNew(le->slot,
                                                 recipientlist, rlIndex, wincx);
        if (cert)
            break;
    }

    PK11_FreeSlotList(list);

    return cert;
}

/*
 * We're looking for a cert which we have the private key for that's on the
 * list of recipients. This searches one slot.
 */
static CERTCertificate *
pk11_FindCertObjectByRecipient(PK11SlotInfo *slot,
                               SEC_PKCS7RecipientInfo **recipientArray,
                               SEC_PKCS7RecipientInfo **rip, void *pwarg)
{
    SEC_PKCS7RecipientInfo *ri = NULL;
    CERTCertTrust trust;
    int i;

    for (i = 0; (ri = recipientArray[i]) != NULL; i++) {
        CERTCertificate *cert;

        cert = PK11_FindCertByIssuerAndSNOnToken(slot, ri->issuerAndSN,
                                                 pwarg);
        if (cert) {
            /* this isn't our cert */
            if (CERT_GetCertTrust(cert, &trust) != SECSuccess ||
                ((trust.emailFlags & CERTDB_USER) != CERTDB_USER)) {
                CERT_DestroyCertificate(cert);
                continue;
            }
            *rip = ri;
            return cert;
        }
    }
    *rip = NULL;
    return NULL;
}

/*
 * This function is the same as above, but it searches all the slots.
 */
static CERTCertificate *
pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
                                  SEC_PKCS7RecipientInfo **recipientArray,
                                  SEC_PKCS7RecipientInfo **rip,
                                  void *wincx)
{
    PK11SlotList *list;
    PK11SlotListElement *le;
    CERTCertificate *cert = NULL;
    PK11SlotInfo *slot = NULL;
    SECStatus rv;

    *slotPtr = NULL;

    /* get them all! */
    list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, wincx);
    if (list == NULL) {
        return CK_INVALID_HANDLE;
    }

    *rip = NULL;

    /* Look for the slot that holds the Key */
    for (le = list->head; le; le = le->next) {
        rv = pk11_AuthenticateUnfriendly(le->slot, PR_TRUE, wincx);
        if (rv != SECSuccess)
            continue;

        cert = pk11_FindCertObjectByRecipient(le->slot, recipientArray,
                                              rip, wincx);
        if (cert) {
            slot = PK11_ReferenceSlot(le->slot);
            break;
        }
    }

    PK11_FreeSlotList(list);

    if (slot == NULL) {
        return NULL;
    }
    *slotPtr = slot;
    PORT_Assert(cert != NULL);
    return cert;
}

/*
 * We need to invert the search logic for PKCS 7 because if we search for
 * each cert on the list over all the slots, we wind up with lots of spurious
 * password prompts. This way we get only one password prompt per slot, at
 * the max, and most of the time we can find the cert, and only prompt for
 * the key...
 */
CERTCertificate *
PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr,
                                   SEC_PKCS7RecipientInfo **array,
                                   SEC_PKCS7RecipientInfo **rip,
                                   SECKEYPrivateKey **privKey, void *wincx)
{
    CERTCertificate *cert = NULL;

    *privKey = NULL;
    *slotPtr = NULL;
    cert = pk11_AllFindCertObjectByRecipient(slotPtr, array, rip, wincx);
    if (!cert) {
        return NULL;
    }

    *privKey = PK11_FindKeyByAnyCert(cert, wincx);
    if (*privKey == NULL) {
        goto loser;
    }

    return cert;
loser:
    if (cert)
        CERT_DestroyCertificate(cert);
    if (*slotPtr)
        PK11_FreeSlot(*slotPtr);
    *slotPtr = NULL;
    return NULL;
}

/*
 * This is the new version of the above function for NSS SMIME code
 * this stuff should REALLY be in the SMIME code, but some things in here are not public
 * (they should be!)
 */
int
PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *wincx)
{
    CERTCertificate *cert;
    NSSCMSRecipient *rl;
    PRStatus rv;
    int rlIndex;

    rv = PR_CallOnceWithArg(&keyIDHashCallOnce, pk11_keyIDHash_populate, wincx);
    if (rv != PR_SUCCESS)
        return -1;

    cert = pk11_AllFindCertObjectByRecipientNew(recipientlist, wincx, &rlIndex);
    if (!cert) {
        return -1;
    }

    rl = recipientlist[rlIndex];

    /* at this point, rl->slot is set */

    rl->privkey = PK11_FindKeyByAnyCert(cert, wincx);
    if (rl->privkey == NULL) {
        goto loser;
    }

    /* make a cert from the cert handle */
    rl->cert = cert;
    return rlIndex;

loser:
    if (cert)
        CERT_DestroyCertificate(cert);
    if (rl->slot)
        PK11_FreeSlot(rl->slot);
    rl->slot = NULL;
    return -1;
}

CERTCertificate *
PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
                           void *wincx)
{
    CERTCertificate *rvCert = NULL;
    NSSCertificate *cert;
    NSSDER issuer, serial;
    NSSCryptoContext *cc;
    SECItem *derSerial;

    if (!issuerSN || !issuerSN->derIssuer.data || !issuerSN->derIssuer.len ||
        !issuerSN->serialNumber.data || !issuerSN->serialNumber.len ||
        issuerSN->derIssuer.len > CERT_MAX_DN_BYTES ||
        issuerSN->serialNumber.len > CERT_MAX_SERIAL_NUMBER_BYTES) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    if (slotPtr)
        *slotPtr = NULL;

    /* PKCS#11 needs to use DER-encoded serial numbers.  Create a
     * CERTIssuerAndSN that actually has the encoded value and pass that
     * to PKCS#11 (and the crypto context).
     */
    derSerial = SEC_ASN1EncodeItem(NULL, NULL,
                                   &issuerSN->serialNumber,
                                   SEC_ASN1_GET(SEC_IntegerTemplate));
    if (!derSerial) {
        return NULL;
    }

    NSSITEM_FROM_SECITEM(&issuer, &issuerSN->derIssuer);
    NSSITEM_FROM_SECITEM(&serial, derSerial);

    cc = STAN_GetDefaultCryptoContext();
    cert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(cc,
                                                                   &issuer,
                                                                   &serial);
    if (cert) {
        SECITEM_FreeItem(derSerial, PR_TRUE);
        return STAN_GetCERTCertificateOrRelease(cert);
    }

    do {
        /* free the old cert on retry. Associated slot was not present */
        if (rvCert) {
            CERT_DestroyCertificate(rvCert);
            rvCert = NULL;
        }

        cert = NSSTrustDomain_FindCertificateByIssuerAndSerialNumber(
            STAN_GetDefaultTrustDomain(),
            &issuer,
            &serial);
        if (!cert) {
            break;
        }

        rvCert = STAN_GetCERTCertificateOrRelease(cert);
        if (rvCert == NULL) {
            break;
        }

        /* Check to see if the cert's token is still there */
    } while (!PK11_IsPresent(rvCert->slot));

    if (rvCert && slotPtr)
        *slotPtr = PK11_ReferenceSlot(rvCert->slot);

    SECITEM_FreeItem(derSerial, PR_TRUE);
    return rvCert;
}

CK_OBJECT_HANDLE
PK11_FindObjectForCert(CERTCertificate *cert, void *wincx, PK11SlotInfo **pSlot)
{
    CK_OBJECT_HANDLE certHandle;
    CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
    CK_ATTRIBUTE *attr;
    CK_ATTRIBUTE searchTemplate[] = {
        { CKA_CLASS, NULL, 0 },
        { CKA_VALUE, NULL, 0 },
    };
    int templateSize = sizeof(searchTemplate) / sizeof(searchTemplate[0]);

    attr = searchTemplate;
    PK11_SETATTRS(attr, CKA_CLASS, &certClass, sizeof(certClass));
    attr++;
    PK11_SETATTRS(attr, CKA_VALUE, cert->derCert.data, cert->derCert.len);

    if (cert->slot) {
        certHandle = pk11_getcerthandle(cert->slot, cert, searchTemplate,
                                        templateSize);
        if (certHandle != CK_INVALID_HANDLE) {
            *pSlot = PK11_ReferenceSlot(cert->slot);
            return certHandle;
        }
    }

    certHandle = pk11_FindCertObjectByTemplate(pSlot, searchTemplate,
                                               templateSize, wincx);
    if (certHandle != CK_INVALID_HANDLE) {
        if (cert->slot == NULL) {
            cert->slot = PK11_ReferenceSlot(*pSlot);
            cert->pkcs11ID = certHandle;
            cert->ownSlot = PR_TRUE;
            cert->series = cert->slot->series;
        }
    }

    return (certHandle);
}

SECKEYPrivateKey *
PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx)
{
    CK_OBJECT_HANDLE certHandle;
    CK_OBJECT_HANDLE keyHandle;
    PK11SlotInfo *slot = NULL;
    SECKEYPrivateKey *privKey = NULL;
    PRBool needLogin;
    SECStatus rv;
    int err;

    certHandle = PK11_FindObjectForCert(cert, wincx, &slot);
    if (certHandle == CK_INVALID_HANDLE) {
        return NULL;
    }
    /*
     * prevent a login race condition. If slot is logged in between
     * our call to pk11_LoginStillRequired and the
     * PK11_MatchItem. The matchItem call will either succeed, or
     * we will call it one more time after calling PK11_Authenticate
     * (which is a noop on an authenticated token).
     */
    needLogin = pk11_LoginStillRequired(slot, wincx);
    keyHandle = PK11_MatchItem(slot, certHandle, CKO_PRIVATE_KEY);
    if ((keyHandle == CK_INVALID_HANDLE) && needLogin &&
        (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) ||
         SEC_ERROR_TOKEN_NOT_LOGGED_IN == err)) {
        /* authenticate and try again */
        rv = PK11_Authenticate(slot, PR_TRUE, wincx);
        if (rv == SECSuccess) {
            keyHandle = PK11_MatchItem(slot, certHandle, CKO_PRIVATE_KEY);
        }
    }
    if (keyHandle != CK_INVALID_HANDLE) {
        privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
    }
    if (slot) {
        PK11_FreeSlot(slot);
    }
    return privKey;
}

CK_OBJECT_HANDLE
pk11_FindPubKeyByAnyCert(CERTCertificate *cert, PK11SlotInfo **slot, void *wincx)
{
    CK_OBJECT_HANDLE certHandle;
    CK_OBJECT_HANDLE keyHandle;

    certHandle = PK11_FindObjectForCert(cert, wincx, slot);
    if (certHandle == CK_INVALID_HANDLE) {
        return CK_INVALID_HANDLE;
    }
    keyHandle = PK11_MatchItem(*slot, certHandle, CKO_PUBLIC_KEY);
    if (keyHandle == CK_INVALID_HANDLE) {
        PK11_FreeSlot(*slot);
        return CK_INVALID_HANDLE;
    }
    return keyHandle;
}

/*
 * find the number of certs in the slot with the same subject name
 */
int
PK11_NumberCertsForCertSubject(CERTCertificate *cert)
{
    CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
    CK_ATTRIBUTE theTemplate[] = {
        { CKA_CLASS, NULL, 0 },
        { CKA_SUBJECT, NULL, 0 },
    };
    CK_ATTRIBUTE *attr = theTemplate;
    int templateSize = sizeof(theTemplate) / sizeof(theTemplate[0]);

    PK11_SETATTRS(attr, CKA_CLASS, &certClass, sizeof(certClass));
    attr++;
    PK11_SETATTRS(attr, CKA_SUBJECT, cert->derSubject.data, cert->derSubject.len);

    if (cert->slot == NULL) {
        PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
                                               PR_FALSE, PR_TRUE, NULL);
        PK11SlotListElement *le;
        int count = 0;

        if (!list) {
            /* error code is set */
            return 0;
        }

        /* loop through all the fortezza tokens */
        for (le = list->head; le; le = le->next) {
            count += PK11_NumberObjectsFor(le->slot, theTemplate, templateSize);
        }
        PK11_FreeSlotList(list);
        return count;
    }

    return PK11_NumberObjectsFor(cert->slot, theTemplate, templateSize);
}

/*
 *  Walk all the certs with the same subject
 */
SECStatus
PK11_TraverseCertsForSubject(CERTCertificate *cert,
                             SECStatus (*callback)(CERTCertificate *, void *), void *arg)
{
    if (!cert) {
        return SECFailure;
    }
    if (cert->slot == NULL) {
        PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
                                               PR_FALSE, PR_TRUE, NULL);
        PK11SlotListElement *le;

        if (!list) {
            /* error code is set */
            return SECFailure;
        }
        /* loop through all the tokens */
        for (le = list->head; le; le = le->next) {
            PK11_TraverseCertsForSubjectInSlot(cert, le->slot, callback, arg);
        }
        PK11_FreeSlotList(list);
        return SECSuccess;
    }

    return PK11_TraverseCertsForSubjectInSlot(cert, cert->slot, callback, arg);
}

SECStatus
PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
                                   SECStatus (*callback)(CERTCertificate *, void *), void *arg)
{
    PRStatus nssrv = PR_SUCCESS;
    NSSToken *token;
    NSSDER subject;
    NSSTrustDomain *td;
    nssList *subjectList;
    nssPKIObjectCollection *collection;
    nssCryptokiObject **instances;
    NSSCertificate **certs;
    nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
    td = STAN_GetDefaultTrustDomain();
    NSSITEM_FROM_SECITEM(&subject, &cert->derSubject);
    token = PK11Slot_GetNSSToken(slot);
    if (!nssToken_IsPresent(token)) {
        return SECSuccess;
    }
    collection = nssCertificateCollection_Create(td, NULL);
    if (!collection) {
        return SECFailure;
    }
    subjectList = nssList_Create(NULL, PR_FALSE);
    if (!subjectList) {
        nssPKIObjectCollection_Destroy(collection);
        return SECFailure;
    }
    (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject,
                                                     subjectList);
    transfer_token_certs_to_collection(subjectList, token, collection);
    instances = nssToken_FindCertificatesBySubject(token, NULL,
                                                   &subject,
                                                   tokenOnly, 0, &nssrv);
    nssPKIObjectCollection_AddInstances(collection, instances, 0);
    nss_ZFreeIf(instances);
    nssList_Destroy(subjectList);
    certs = nssPKIObjectCollection_GetCertificates(collection,
                                                   NULL, 0, NULL);
    nssPKIObjectCollection_Destroy(collection);
    if (certs) {
        CERTCertificate *oldie;
        NSSCertificate **cp;
        for (cp = certs; *cp; cp++) {
            oldie = STAN_GetCERTCertificate(*cp);
            if (!oldie) {
                continue;
            }
            if ((*callback)(oldie, arg) != SECSuccess) {
                nssrv = PR_FAILURE;
                break;
            }
        }
        nssCertificateArray_Destroy(certs);
    }
    return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
}

SECStatus
PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
                                    SECStatus (*callback)(CERTCertificate *, void *), void *arg)
{
    PRStatus nssrv = PR_SUCCESS;
    NSSToken *token;
    NSSTrustDomain *td;
    NSSUTF8 *nick;
    PRBool created = PR_FALSE;
    nssCryptokiObject **instances;
    nssPKIObjectCollection *collection = NULL;
    NSSCertificate **certs;
    nssList *nameList = NULL;
    nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
    token = PK11Slot_GetNSSToken(slot);
    if (!nssToken_IsPresent(token)) {
        return SECSuccess;
    }
    if (nickname->data[nickname->len - 1] != '\0') {
        nick = nssUTF8_Create(NULL, nssStringType_UTF8String,
                              nickname->data, nickname->len);
        created = PR_TRUE;
    } else {
        nick = (NSSUTF8 *)nickname->data;
    }
    td = STAN_GetDefaultTrustDomain();
    collection = nssCertificateCollection_Create(td, NULL);
    if (!collection) {
        goto loser;
    }
    nameList = nssList_Create(NULL, PR_FALSE);
    if (!nameList) {
        goto loser;
    }
    (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
    transfer_token_certs_to_collection(nameList, token, collection);
    instances = nssToken_FindCertificatesByNickname(token, NULL,
                                                    nick,
                                                    tokenOnly, 0, &nssrv);
    nssPKIObjectCollection_AddInstances(collection, instances, 0);
    nss_ZFreeIf(instances);
    nssList_Destroy(nameList);
    certs = nssPKIObjectCollection_GetCertificates(collection,
                                                   NULL, 0, NULL);
    nssPKIObjectCollection_Destroy(collection);
    if (certs) {
        CERTCertificate *oldie;
        NSSCertificate **cp;
        for (cp = certs; *cp; cp++) {
            oldie = STAN_GetCERTCertificate(*cp);
            if (!oldie) {
                continue;
            }
            if ((*callback)(oldie, arg) != SECSuccess) {
                nssrv = PR_FAILURE;
                break;
            }
        }
        nssCertificateArray_Destroy(certs);
    }
    if (created)
        nss_ZFreeIf(nick);
    return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
loser:
    if (created) {
        nss_ZFreeIf(nick);
    }
    if (collection) {
        nssPKIObjectCollection_Destroy(collection);
    }
    if (nameList) {
        nssList_Destroy(nameList);
    }
    return SECFailure;
}

SECStatus
PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
                         SECStatus (*callback)(CERTCertificate *, void *), void *arg)
{
    PRStatus nssrv;
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
    NSSToken *tok;
    nssList *certList = NULL;
    nssCryptokiObject **instances;
    nssPKIObjectCollection *collection;
    NSSCertificate **certs;
    nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
    tok = PK11Slot_GetNSSToken(slot);
    if (!nssToken_IsPresent(tok)) {
        return SECSuccess;
    }
    collection = nssCertificateCollection_Create(td, NULL);
    if (!collection) {
        return SECFailure;
    }
    certList = nssList_Create(NULL, PR_FALSE);
    if (!certList) {
        nssPKIObjectCollection_Destroy(collection);
        return SECFailure;
    }
    (void)nssTrustDomain_GetCertsFromCache(td, certList);
    transfer_token_certs_to_collection(certList, tok, collection);
    instances = nssToken_FindObjects(tok, NULL, CKO_CERTIFICATE,
                                     tokenOnly, 0, &nssrv);
    nssPKIObjectCollection_AddInstances(collection, instances, 0);
    nss_ZFreeIf(instances);
    nssList_Destroy(certList);
    certs = nssPKIObjectCollection_GetCertificates(collection,
                                                   NULL, 0, NULL);
    nssPKIObjectCollection_Destroy(collection);
    if (certs) {
        CERTCertificate *oldie;
        NSSCertificate **cp;
        for (cp = certs; *cp; cp++) {
            oldie = STAN_GetCERTCertificate(*cp);
            if (!oldie) {
                continue;
            }
            if ((*callback)(oldie, arg) != SECSuccess) {
                nssrv = PR_FAILURE;
                break;
            }
        }
        nssCertificateArray_Destroy(certs);
    }
    return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
}

/*
 * return the certificate associated with a derCert
 */
CERTCertificate *
PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
                         void *wincx)
{
    return PK11_FindCertFromDERCertItem(slot, &cert->derCert, wincx);
}

CERTCertificate *
PK11_FindCertFromDERCertItem(PK11SlotInfo *slot, const SECItem *inDerCert,
                             void *wincx)

{
    NSSDER derCert;
    NSSToken *tok;
    nssCryptokiObject *co = NULL;
    SECStatus rv;
    CERTCertificate *cert = NULL;

    tok = PK11Slot_GetNSSToken(slot);
    NSSITEM_FROM_SECITEM(&derCert, inDerCert);
    rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
    if (rv != SECSuccess) {
        PK11_FreeSlot(slot);
        return NULL;
    }

    co = nssToken_FindCertificateByEncodedCertificate(tok, NULL, &derCert,
                                                      nssTokenSearchType_TokenOnly, NULL);

    if (co) {
        cert = PK11_MakeCertFromHandle(slot, co->handle, NULL);
        nssCryptokiObject_Destroy(co);
    }

    return cert;
}

/*
 * import a cert for a private key we have already generated. Set the label
 * on both to be the nickname.
 */
static CK_OBJECT_HANDLE
pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
                            void *wincx)
{
    SECItem *keyID;
    CK_OBJECT_HANDLE key;
    SECStatus rv;
    PRBool needLogin;
    int err;

    if ((slot == NULL) || (cert == NULL)) {
        return CK_INVALID_HANDLE;
    }

    keyID = pk11_mkcertKeyID(cert);
    if (keyID == NULL) {
        return CK_INVALID_HANDLE;
    }

    /*
     * prevent a login race condition. If slot is logged in between
     * our call to pk11_LoginStillRequired and the
     * pk11_FindPrivateKeyFromCerID. The matchItem call will either succeed, or
     * we will call it one more time after calling PK11_Authenticate
     * (which is a noop on an authenticated token).
     */
    needLogin = pk11_LoginStillRequired(slot, wincx);
    key = pk11_FindPrivateKeyFromCertID(slot, keyID);
    if ((key == CK_INVALID_HANDLE) && needLogin &&
        (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) ||
         SEC_ERROR_TOKEN_NOT_LOGGED_IN == err)) {
        /* authenticate and try again */
        rv = PK11_Authenticate(slot, PR_TRUE, wincx);
        if (rv != SECSuccess)
            goto loser;
        key = pk11_FindPrivateKeyFromCertID(slot, keyID);
    }

loser:
    SECITEM_ZfreeItem(keyID, PR_TRUE);
    return key;
}

SECKEYPrivateKey *
PK11_FindKeyByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
                      void *wincx)
{
    CK_OBJECT_HANDLE keyHandle;

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

    keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
    if (keyHandle == CK_INVALID_HANDLE) {
        return NULL;
    }

    return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
}

SECStatus
PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert,
                            char *nickname,
                            PRBool addCertUsage, void *wincx)
{
    CK_OBJECT_HANDLE keyHandle;

    if ((slot == NULL) || (cert == NULL) || (nickname == NULL)) {
        return SECFailure;
    }

    keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
    if (keyHandle == CK_INVALID_HANDLE) {
        return SECFailure;
    }

    return PK11_ImportCert(slot, cert, keyHandle, nickname, addCertUsage);
}

/* remove when the real version comes out */
#define SEC_OID_MISSI_KEA 300 /* until we have v3 stuff merged */
PRBool
KEAPQGCompare(CERTCertificate *server, CERTCertificate *cert)
{

    /* not implemented */
    return PR_FALSE;
}

PRBool
PK11_FortezzaHasKEA(CERTCertificate *cert)
{
    /* look at the subject and see if it is a KEA for MISSI key */
    SECOidData *oid;
    CERTCertTrust trust;

    if (CERT_GetCertTrust(cert, &trust) != SECSuccess ||
        ((trust.sslFlags & CERTDB_USER) != CERTDB_USER)) {
        return PR_FALSE;
    }

    oid = SECOID_FindOID(&cert->subjectPublicKeyInfo.algorithm.algorithm);
    if (!oid) {
        return PR_FALSE;
    }

    return (PRBool)((oid->offset == SEC_OID_MISSI_KEA_DSS_OLD) ||
                    (oid->offset == SEC_OID_MISSI_KEA_DSS) ||
                    (oid->offset == SEC_OID_MISSI_KEA));
}

/*
 * Find a kea cert on this slot that matches the domain of it's peer
 */
static CERTCertificate
    *
    pk11_GetKEAMate(PK11SlotInfo *slot, CERTCertificate *peer)
{
    int i;
    CERTCertificate *returnedCert = NULL;

    for (i = 0; i < slot->cert_count; i++) {
        CERTCertificate *cert = slot->cert_array[i];

        if (PK11_FortezzaHasKEA(cert) && KEAPQGCompare(peer, cert)) {
            returnedCert = CERT_DupCertificate(cert);
            break;
        }
    }
    return returnedCert;
}

/*
 * The following is a FORTEZZA only Certificate request. We call this when we
 * are doing a non-client auth SSL connection. We are only interested in the
 * fortezza slots, and we are only interested in certs that share the same root
 * key as the server.
 */
CERTCertificate *
PK11_FindBestKEAMatch(CERTCertificate *server, void *wincx)
{
    PK11SlotList *keaList = PK11_GetAllTokens(CKM_KEA_KEY_DERIVE,
                                              PR_FALSE, PR_TRUE, wincx);
    PK11SlotListElement *le;
    CERTCertificate *returnedCert = NULL;
    SECStatus rv;

    if (!keaList) {
        /* error code is set */
        return NULL;
    }

    /* loop through all the fortezza tokens */
    for (le = keaList->head; le; le = le->next) {
        rv = PK11_Authenticate(le->slot, PR_TRUE, wincx);
        if (rv != SECSuccess)
            continue;
        if (le->slot->session == CK_INVALID_SESSION) {
            continue;
        }
        returnedCert = pk11_GetKEAMate(le->slot, server);
        if (returnedCert)
            break;
    }
    PK11_FreeSlotList(keaList);

    return returnedCert;
}

/*
 * find a matched pair of kea certs to key exchange parameters from one
 * fortezza card to another as necessary.
 */
SECStatus
PK11_GetKEAMatchedCerts(PK11SlotInfo *slot1, PK11SlotInfo *slot2,
                        CERTCertificate **cert1, CERTCertificate **cert2)
{
    CERTCertificate *returnedCert = NULL;
    int i;

    for (i = 0; i < slot1->cert_count; i++) {
        CERTCertificate *cert = slot1->cert_array[i];

        if (PK11_FortezzaHasKEA(cert)) {
            returnedCert = pk11_GetKEAMate(slot2, cert);
            if (returnedCert != NULL) {
                *cert2 = returnedCert;
                *cert1 = CERT_DupCertificate(cert);
                return SECSuccess;
            }
        }
    }
    return SECFailure;
}

/*
 * return the private key From a given Cert
 */
CK_OBJECT_HANDLE
PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx)
{
    CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
    CK_ATTRIBUTE theTemplate[] = {
        { CKA_VALUE, NULL, 0 },
        { CKA_CLASS, NULL, 0 }
    };
    /* if you change the array, change the variable below as well */
    int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
    CK_ATTRIBUTE *attrs = theTemplate;
    SECStatus rv;

    PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data,
                  cert->derCert.len);
    attrs++;
    PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));

    /*
     * issue the find
     */
    rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
    if (rv != SECSuccess) {
        return CK_INVALID_HANDLE;
    }

    return pk11_getcerthandle(slot, cert, theTemplate, tsize);
}

/* Looking for PK11_GetKeyIDFromCert?
 * Use PK11_GetLowLevelKeyIDForCert instead.
 */

struct listCertsStr {
    PK11CertListType type;
    CERTCertList *certList;
};

static PRStatus
pk11ListCertCallback(NSSCertificate *c, void *arg)
{
    struct listCertsStr *listCertP = (struct listCertsStr *)arg;
    CERTCertificate *newCert = NULL;
    PK11CertListType type = listCertP->type;
    CERTCertList *certList = listCertP->certList;
    PRBool isUnique = PR_FALSE;
    PRBool isCA = PR_FALSE;
    char *nickname = NULL;
    unsigned int certType;
    SECStatus rv;

    if ((type == PK11CertListUnique) || (type == PK11CertListRootUnique) ||
        (type == PK11CertListCAUnique) || (type == PK11CertListUserUnique)) {
        /* only list one instance of each certificate, even if several exist */
        isUnique = PR_TRUE;
    }
    if ((type == PK11CertListCA) || (type == PK11CertListRootUnique) ||
        (type == PK11CertListCAUnique)) {
        isCA = PR_TRUE;
    }

    /* if we want user certs and we don't have one skip this cert */
    if (((type == PK11CertListUser) || (type == PK11CertListUserUnique)) &&
        !NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL)) {
        return PR_SUCCESS;
    }

    /* PK11CertListRootUnique means we want CA certs without a private key.
     * This is for legacy app support . PK11CertListCAUnique should be used
     * instead to get all CA certs, regardless of private key
     */
    if ((type == PK11CertListRootUnique) &&
        NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL)) {
        return PR_SUCCESS;
    }

    /* caller still owns the reference to 'c' */
    newCert = STAN_GetCERTCertificate(c);
    if (!newCert) {
        return PR_SUCCESS;
    }
    /* if we want CA certs and it ain't one, skip it */
    if (isCA && (!CERT_IsCACert(newCert, &certType))) {
        return PR_SUCCESS;
    }
    if (isUnique) {
        CERT_DupCertificate(newCert);

        nickname = STAN_GetCERTCertificateName(certList->arena, c);

        /* put slot certs at the end */
        if (newCert->slot && !PK11_IsInternal(newCert->slot)) {
            rv = CERT_AddCertToListTailWithData(certList, newCert, nickname);
        } else {
            rv = CERT_AddCertToListHeadWithData(certList, newCert, nickname);
        }
        /* if we didn't add the cert to the list, don't leak it */
        if (rv != SECSuccess) {
            CERT_DestroyCertificate(newCert);
        }
    } else {
        /* add multiple instances to the cert list */
        nssCryptokiObject **ip;
        nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
        if (!instances) {
            return PR_SUCCESS;
        }
        for (ip = instances; *ip; ip++) {
            nssCryptokiObject *instance = *ip;
            PK11SlotInfo *slot = instance->token->pk11slot;

            /* put the same CERTCertificate in the list for all instances */
            CERT_DupCertificate(newCert);

            nickname = STAN_GetCERTCertificateNameForInstance(
                certList->arena, c, instance);

            /* put slot certs at the end */
            if (slot && !PK11_IsInternal(slot)) {
                rv = CERT_AddCertToListTailWithData(certList, newCert, nickname);
            } else {
                rv = CERT_AddCertToListHeadWithData(certList, newCert, nickname);
            }
            /* if we didn't add the cert to the list, don't leak it */
            if (rv != SECSuccess) {
                CERT_DestroyCertificate(newCert);
            }
        }
        nssCryptokiObjectArray_Destroy(instances);
    }
    return PR_SUCCESS;
}

CERTCertList *
PK11_ListCerts(PK11CertListType type, void *pwarg)
{
    NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
    CERTCertList *certList = NULL;
    struct listCertsStr listCerts;
    certList = CERT_NewCertList();
    listCerts.type = type;
    listCerts.certList = certList;

    /* authenticate to the slots */
    (void)pk11_TraverseAllSlots(NULL, NULL, PR_TRUE, pwarg);
    NSSTrustDomain_TraverseCertificates(defaultTD, pk11ListCertCallback,
                                        &listCerts);
    return certList;
}

SECItem *
PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
                             CERTCertificate *cert, void *wincx)
{
    CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
    CK_ATTRIBUTE theTemplate[] = {
        { CKA_VALUE, NULL, 0 },
        { CKA_CLASS, NULL, 0 }
    };
    /* if you change the array, change the variable below as well */
    int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
    CK_OBJECT_HANDLE certHandle;
    CK_ATTRIBUTE *attrs = theTemplate;
    PK11SlotInfo *slotRef = NULL;
    SECItem *item;
    SECStatus rv;

    if (slot) {
        PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data,
                      cert->derCert.len);
        attrs++;
        PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));

        rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
        if (rv != SECSuccess) {
            return NULL;
        }
        certHandle = pk11_getcerthandle(slot, cert, theTemplate, tsize);
    } else {
        certHandle = PK11_FindObjectForCert(cert, wincx, &slotRef);
        if (certHandle == CK_INVALID_HANDLE) {
            return pk11_mkcertKeyID(cert);
        }
        slot = slotRef;
    }

    if (certHandle == CK_INVALID_HANDLE) {
        return NULL;
    }

    item = pk11_GetLowLevelKeyFromHandle(slot, certHandle);
    if (slotRef)
        PK11_FreeSlot(slotRef);
    return item;
}

/* argument type for listCertsCallback */
typedef struct {
    CERTCertList *list;
    PK11SlotInfo *slot;
} ListCertsArg;

static SECStatus
listCertsCallback(CERTCertificate *cert, void *arg)
{
    ListCertsArg *cdata = (ListCertsArg *)arg;
    char *nickname = NULL;
    nssCryptokiObject *instance, **ci;
    nssCryptokiObject **instances;
    NSSCertificate *c = STAN_GetNSSCertificate(cert);
    SECStatus rv;

    if (c == NULL) {
        return SECFailure;
    }
    instances = nssPKIObject_GetInstances(&c->object);
    if (!instances) {
        return SECFailure;
    }
    instance = NULL;
    for (ci = instances; *ci; ci++) {
        if ((*ci)->token->pk11slot == cdata->slot) {
            instance = *ci;
            break;
        }
    }
    PORT_Assert(instance != NULL);
    if (!instance) {
        nssCryptokiObjectArray_Destroy(instances);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    nickname = STAN_GetCERTCertificateNameForInstance(cdata->list->arena,
                                                      c, instance);
    nssCryptokiObjectArray_Destroy(instances);

    CERT_DupCertificate(cert);
    rv = CERT_AddCertToListTailWithData(cdata->list, cert, nickname);
    if (rv != SECSuccess) {
        CERT_DestroyCertificate(cert);
    }
    return rv;
}

CERTCertList *
PK11_ListCertsInSlot(PK11SlotInfo *slot)
{
    SECStatus status;
    CERTCertList *certs;
    ListCertsArg cdata;

    certs = CERT_NewCertList();
    if (certs == NULL)
        return NULL;
    cdata.list = certs;
    cdata.slot = slot;

    status = PK11_TraverseCertsInSlot(slot, listCertsCallback,
                                      &cdata);

    if (status != SECSuccess) {
        CERT_DestroyCertList(certs);
        certs = NULL;
    }

    return certs;
}

PK11SlotList *
PK11_GetAllSlotsForCert(CERTCertificate *cert, void *arg)
{
    nssCryptokiObject **ip;
    PK11SlotList *slotList;
    NSSCertificate *c;
    nssCryptokiObject **instances;
    PRBool found = PR_FALSE;

    if (!cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    c = STAN_GetNSSCertificate(cert);
    if (!c) {
        CERT_MapStanError();
        return NULL;
    }

    /* add multiple instances to the cert list */
    instances = nssPKIObject_GetInstances(&c->object);
    if (!instances) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return NULL;
    }

    slotList = PK11_NewSlotList();
    if (!slotList) {
        nssCryptokiObjectArray_Destroy(instances);
        return NULL;
    }

    for (ip = instances; *ip; ip++) {
        nssCryptokiObject *instance = *ip;
        PK11SlotInfo *slot = instance->token->pk11slot;
        if (slot) {
            PK11_AddSlotToList(slotList, slot, PR_TRUE);
            found = PR_TRUE;
        }
    }
    if (!found) {
        PK11_FreeSlotList(slotList);
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        slotList = NULL;
    }

    nssCryptokiObjectArray_Destroy(instances);
    return slotList;
}

/*
 * Using __PK11_SetCertificateNickname is *DANGEROUS*.
 *
 * The API will update the NSS database, but it *will NOT* update the in-memory data.
 * As a result, after calling this API, there will be INCONSISTENCY between
 * in-memory data and the database.
 *
 * Use of the API should be limited to short-lived tools, which will exit immediately
 * after using this API.
 *
 * If you ignore this warning, your process is TAINTED and will most likely misbehave.
 */
SECStatus
__PK11_SetCertificateNickname(CERTCertificate *cert, const char *nickname)
{
    /* Can't set nickname of temp cert. */
    if (!cert->slot || cert->pkcs11ID == CK_INVALID_HANDLE) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    return PK11_SetObjectNickname(cert->slot, cert->pkcs11ID, nickname);
}
