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

/*
 * Hacks to integrate NSS 3.4 and NSS 4.0 certificates.
 */

#ifndef NSSPKI_H
#include "nsspki.h"
#endif /* NSSPKI_H */

#ifndef PKI_H
#include "pki.h"
#endif /* PKI_H */

#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */

#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */

#ifndef DEVNSS3HACK_H
#include "dev3hack.h"
#endif /* DEVNSS3HACK_H */

#ifndef PKINSS3HACK_H
#include "pki3hack.h"
#endif /* PKINSS3HACK_H */

#include "secitem.h"
#include "certdb.h"
#include "certt.h"
#include "cert.h"
#include "certi.h"
#include "pk11func.h"
#include "pkistore.h"
#include "secmod.h"
#include "nssrwlk.h"

NSSTrustDomain *g_default_trust_domain = NULL;

NSSCryptoContext *g_default_crypto_context = NULL;

NSSTrustDomain *
STAN_GetDefaultTrustDomain()
{
    return g_default_trust_domain;
}

NSSCryptoContext *
STAN_GetDefaultCryptoContext()
{
    return g_default_crypto_context;
}

extern const NSSError NSS_ERROR_ALREADY_INITIALIZED;
extern const NSSError NSS_ERROR_INTERNAL_ERROR;

NSS_IMPLEMENT PRStatus
STAN_InitTokenForSlotInfo(NSSTrustDomain *td, PK11SlotInfo *slot)
{
    NSSToken *token;
    if (!td) {
        td = g_default_trust_domain;
        if (!td) {
            /* we're called while still initting. slot will get added
             * appropriately through normal init processes */
            return PR_SUCCESS;
        }
    }
    token = nssToken_CreateFromPK11SlotInfo(td, slot);
    if (token) {
        /* PK11Slot_SetNSSToken increments the refcount on |token| to 2 */
        PK11Slot_SetNSSToken(slot, token);

        /* we give our reference to |td->tokenList| */
        NSSRWLock_LockWrite(td->tokensLock);
        nssList_Add(td->tokenList, token);
        NSSRWLock_UnlockWrite(td->tokensLock);
    } else {
        PK11Slot_SetNSSToken(slot, NULL);
    }
    return PR_SUCCESS;
}

NSS_IMPLEMENT PRStatus
STAN_ResetTokenInterator(NSSTrustDomain *td)
{
    if (!td) {
        td = g_default_trust_domain;
        if (!td) {
            /* we're called while still initting. slot will get added
             * appropriately through normal init processes */
            return PR_SUCCESS;
        }
    }
    NSSRWLock_LockWrite(td->tokensLock);
    nssListIterator_Destroy(td->tokens);
    td->tokens = nssList_CreateIterator(td->tokenList);
    NSSRWLock_UnlockWrite(td->tokensLock);
    return PR_SUCCESS;
}

NSS_IMPLEMENT PRStatus
STAN_LoadDefaultNSS3TrustDomain(
    void)
{
    NSSTrustDomain *td;
    SECMODModuleList *mlp;
    SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
    int i;

    if (g_default_trust_domain || g_default_crypto_context) {
        /* Stan is already initialized or a previous shutdown failed. */
        nss_SetError(NSS_ERROR_ALREADY_INITIALIZED);
        return PR_FAILURE;
    }
    td = NSSTrustDomain_Create(NULL, NULL, NULL, NULL);
    if (!td) {
        return PR_FAILURE;
    }
    /*
     * Deadlock warning: we should never acquire the moduleLock while
     * we hold the tokensLock. We can use the NSSRWLock Rank feature to
     * guarrentee this. tokensLock have a higher rank than module lock.
     */
    td->tokenList = nssList_Create(td->arena, PR_TRUE);
    if (!td->tokenList) {
        goto loser;
    }
    SECMOD_GetReadLock(moduleLock);
    NSSRWLock_LockWrite(td->tokensLock);
    for (mlp = SECMOD_GetDefaultModuleList(); mlp != NULL; mlp = mlp->next) {
        for (i = 0; i < mlp->module->slotCount; i++) {
            STAN_InitTokenForSlotInfo(td, mlp->module->slots[i]);
        }
    }
    td->tokens = nssList_CreateIterator(td->tokenList);
    NSSRWLock_UnlockWrite(td->tokensLock);
    SECMOD_ReleaseReadLock(moduleLock);
    if (!td->tokens) {
        goto loser;
    }
    g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
    if (!g_default_crypto_context) {
        goto loser;
    }
    g_default_trust_domain = td;
    return PR_SUCCESS;

loser:
    NSSTrustDomain_Destroy(td);
    return PR_FAILURE;
}

/*
 * must be called holding the ModuleListLock (either read or write).
 */
NSS_IMPLEMENT SECStatus
STAN_AddModuleToDefaultTrustDomain(
    SECMODModule *module)
{
    NSSTrustDomain *td;
    int i;
    td = STAN_GetDefaultTrustDomain();
    for (i = 0; i < module->slotCount; i++) {
        STAN_InitTokenForSlotInfo(td, module->slots[i]);
    }
    STAN_ResetTokenInterator(td);
    return SECSuccess;
}

/*
 * must be called holding the ModuleListLock (either read or write).
 */
NSS_IMPLEMENT SECStatus
STAN_RemoveModuleFromDefaultTrustDomain(
    SECMODModule *module)
{
    NSSToken *token;
    NSSTrustDomain *td;
    int i;
    td = STAN_GetDefaultTrustDomain();
    for (i = 0; i < module->slotCount; i++) {
        token = PK11Slot_GetNSSToken(module->slots[i]);
        if (token) {
            nssToken_NotifyCertsNotVisible(token);
            NSSRWLock_LockWrite(td->tokensLock);
            nssList_Remove(td->tokenList, token);
            NSSRWLock_UnlockWrite(td->tokensLock);
            PK11Slot_SetNSSToken(module->slots[i], NULL);
            (void)nssToken_Destroy(token); /* for the |td->tokenList| reference */
            (void)nssToken_Destroy(token); /* for our PK11Slot_GetNSSToken reference */
        }
    }
    NSSRWLock_LockWrite(td->tokensLock);
    nssListIterator_Destroy(td->tokens);
    td->tokens = nssList_CreateIterator(td->tokenList);
    NSSRWLock_UnlockWrite(td->tokensLock);
    return SECSuccess;
}

NSS_IMPLEMENT PRStatus
STAN_Shutdown()
{
    PRStatus status = PR_SUCCESS;
    if (g_default_trust_domain) {
        if (NSSTrustDomain_Destroy(g_default_trust_domain) == PR_SUCCESS) {
            g_default_trust_domain = NULL;
        } else {
            status = PR_FAILURE;
        }
    }
    if (g_default_crypto_context) {
        if (NSSCryptoContext_Destroy(g_default_crypto_context) == PR_SUCCESS) {
            g_default_crypto_context = NULL;
        } else {
            status = PR_FAILURE;
        }
    }
    return status;
}

/* this function should not be a hack; it will be needed in 4.0 (rename) */
NSS_IMPLEMENT NSSItem *
STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der)
{
    NSSItem *rvKey;
    SECItem secDER;
    SECItem secKey = { 0 };
    SECStatus secrv;
    PLArenaPool *arena;

    SECITEM_FROM_NSSITEM(&secDER, der);

    /* nss3 call uses nss3 arena's */
    arena = PORT_NewArena(256);
    if (!arena) {
        return NULL;
    }
    secrv = CERT_KeyFromDERCert(arena, &secDER, &secKey);
    if (secrv != SECSuccess) {
        PORT_FreeArena(arena, PR_FALSE);
        return NULL;
    }
    rvKey = nssItem_Create(arenaOpt, NULL, secKey.len, (void *)secKey.data);
    PORT_FreeArena(arena, PR_FALSE);
    return rvKey;
}

NSS_IMPLEMENT PRStatus
nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der,
                                     NSSDER *issuer, NSSDER *serial)
{
    SECItem derCert = { 0 };
    SECItem derIssuer = { 0 };
    SECItem derSerial = { 0 };
    SECStatus secrv;
    derCert.data = (unsigned char *)der->data;
    derCert.len = der->size;
    secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer);
    if (secrv != SECSuccess) {
        return PR_FAILURE;
    }
    secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial);
    if (secrv != SECSuccess) {
        PORT_Free(derSerial.data);
        return PR_FAILURE;
    }
    issuer->data = derIssuer.data;
    issuer->size = derIssuer.len;
    serial->data = derSerial.data;
    serial->size = derSerial.len;
    return PR_SUCCESS;
}

static NSSItem *
nss3certificate_getIdentifier(nssDecodedCert *dc)
{
    NSSItem *rvID;
    CERTCertificate *c = (CERTCertificate *)dc->data;
    rvID = nssItem_Create(NULL, NULL, c->certKey.len, c->certKey.data);
    return rvID;
}

static void *
nss3certificate_getIssuerIdentifier(nssDecodedCert *dc)
{
    CERTCertificate *c = (CERTCertificate *)dc->data;
    return (void *)c->authKeyID;
}

static nssCertIDMatch
nss3certificate_matchIdentifier(nssDecodedCert *dc, void *id)
{
    CERTCertificate *c = (CERTCertificate *)dc->data;
    CERTAuthKeyID *authKeyID = (CERTAuthKeyID *)id;
    SECItem skid;
    nssCertIDMatch match = nssCertIDMatch_Unknown;

    /* keyIdentifier */
    if (authKeyID->keyID.len > 0 &&
        CERT_FindSubjectKeyIDExtension(c, &skid) == SECSuccess) {
        PRBool skiEqual;
        skiEqual = SECITEM_ItemsAreEqual(&authKeyID->keyID, &skid);
        PORT_Free(skid.data);
        if (skiEqual) {
            /* change the state to positive match, but keep going */
            match = nssCertIDMatch_Yes;
        } else {
            /* exit immediately on failure */
            return nssCertIDMatch_No;
        }
    }

    /* issuer/serial (treated as pair) */
    if (authKeyID->authCertIssuer) {
        SECItem *caName = NULL;
        SECItem *caSN = &authKeyID->authCertSerialNumber;

        caName = (SECItem *)CERT_GetGeneralNameByType(
            authKeyID->authCertIssuer,
            certDirectoryName, PR_TRUE);
        if (caName != NULL &&
            SECITEM_ItemsAreEqual(&c->derIssuer, caName) &&
            SECITEM_ItemsAreEqual(&c->serialNumber, caSN)) {
            match = nssCertIDMatch_Yes;
        } else {
            match = nssCertIDMatch_Unknown;
        }
    }
    return match;
}

static PRBool
nss3certificate_isValidIssuer(nssDecodedCert *dc)
{
    CERTCertificate *c = (CERTCertificate *)dc->data;
    unsigned int ignore;
    return CERT_IsCACert(c, &ignore);
}

static NSSUsage *
nss3certificate_getUsage(nssDecodedCert *dc)
{
    /* CERTCertificate *c = (CERTCertificate *)dc->data; */
    return NULL;
}

static PRBool
nss3certificate_isValidAtTime(nssDecodedCert *dc, NSSTime *time)
{
    SECCertTimeValidity validity;
    CERTCertificate *c = (CERTCertificate *)dc->data;
    validity = CERT_CheckCertValidTimes(c, NSSTime_GetPRTime(time), PR_TRUE);
    if (validity == secCertTimeValid) {
        return PR_TRUE;
    }
    return PR_FALSE;
}

static PRBool
nss3certificate_isNewerThan(nssDecodedCert *dc, nssDecodedCert *cmpdc)
{
    /* I know this isn't right, but this is glue code anyway */
    if (cmpdc->type == dc->type) {
        CERTCertificate *certa = (CERTCertificate *)dc->data;
        CERTCertificate *certb = (CERTCertificate *)cmpdc->data;
        return CERT_IsNewer(certa, certb);
    }
    return PR_FALSE;
}

/* CERT_FilterCertListByUsage */
static PRBool
nss3certificate_matchUsage(nssDecodedCert *dc, const NSSUsage *usage)
{
    CERTCertificate *cc;
    unsigned int requiredKeyUsage = 0;
    unsigned int requiredCertType = 0;
    SECStatus secrv;
    PRBool match;
    PRBool ca;

    /* This is for NSS 3.3 functions that do not specify a usage */
    if (usage->anyUsage) {
        return PR_TRUE;
    }
    ca = usage->nss3lookingForCA;
    secrv = CERT_KeyUsageAndTypeForCertUsage(usage->nss3usage, ca,
                                             &requiredKeyUsage,
                                             &requiredCertType);
    if (secrv != SECSuccess) {
        return PR_FALSE;
    }
    cc = (CERTCertificate *)dc->data;
    secrv = CERT_CheckKeyUsage(cc, requiredKeyUsage);
    match = (PRBool)(secrv == SECSuccess);
    if (match) {
        unsigned int certType = 0;
        if (ca) {
            (void)CERT_IsCACert(cc, &certType);
        } else {
            certType = cc->nsCertType;
        }
        if (!(certType & requiredCertType)) {
            match = PR_FALSE;
        }
    }
    return match;
}

static PRBool
nss3certificate_isTrustedForUsage(nssDecodedCert *dc, const NSSUsage *usage)
{
    CERTCertificate *cc;
    PRBool ca;
    SECStatus secrv;
    unsigned int requiredFlags;
    unsigned int trustFlags;
    SECTrustType trustType;
    CERTCertTrust trust;

    /* This is for NSS 3.3 functions that do not specify a usage */
    if (usage->anyUsage) {
        return PR_FALSE; /* XXX is this right? */
    }
    cc = (CERTCertificate *)dc->data;
    ca = usage->nss3lookingForCA;
    if (!ca) {
        PRBool trusted;
        unsigned int failedFlags;
        secrv = cert_CheckLeafTrust(cc, usage->nss3usage,
                                    &failedFlags, &trusted);
        return secrv == SECSuccess && trusted;
    }
    secrv = CERT_TrustFlagsForCACertUsage(usage->nss3usage, &requiredFlags,
                                          &trustType);
    if (secrv != SECSuccess) {
        return PR_FALSE;
    }
    secrv = CERT_GetCertTrust(cc, &trust);
    if (secrv != SECSuccess) {
        return PR_FALSE;
    }
    if (trustType == trustTypeNone) {
        /* normally trustTypeNone usages accept any of the given trust bits
         * being on as acceptable. */
        trustFlags = trust.sslFlags | trust.emailFlags |
                     trust.objectSigningFlags;
    } else {
        trustFlags = SEC_GET_TRUST_FLAGS(&trust, trustType);
    }
    return (trustFlags & requiredFlags) == requiredFlags;
}

static NSSASCII7 *
nss3certificate_getEmailAddress(nssDecodedCert *dc)
{
    CERTCertificate *cc = (CERTCertificate *)dc->data;
    return (cc && cc->emailAddr && cc->emailAddr[0])
               ? (NSSASCII7 *)cc->emailAddr
               : NULL;
}

static PRStatus
nss3certificate_getDERSerialNumber(nssDecodedCert *dc,
                                   NSSDER *serial, NSSArena *arena)
{
    CERTCertificate *cc = (CERTCertificate *)dc->data;
    SECItem derSerial = { 0 };
    SECStatus secrv;
    secrv = CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
    if (secrv == SECSuccess) {
        (void)nssItem_Create(arena, serial, derSerial.len, derSerial.data);
        PORT_Free(derSerial.data);
        return PR_SUCCESS;
    }
    return PR_FAILURE;
}

/* Returns NULL if "encoding" cannot be decoded. */
NSS_IMPLEMENT nssDecodedCert *
nssDecodedPKIXCertificate_Create(
    NSSArena *arenaOpt,
    NSSDER *encoding)
{
    nssDecodedCert *rvDC = NULL;
    CERTCertificate *cert;
    SECItem secDER;

    SECITEM_FROM_NSSITEM(&secDER, encoding);
    cert = CERT_DecodeDERCertificate(&secDER, PR_TRUE, NULL);
    if (cert) {
        rvDC = nss_ZNEW(arenaOpt, nssDecodedCert);
        if (rvDC) {
            rvDC->type = NSSCertificateType_PKIX;
            rvDC->data = (void *)cert;
            rvDC->getIdentifier = nss3certificate_getIdentifier;
            rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier;
            rvDC->matchIdentifier = nss3certificate_matchIdentifier;
            rvDC->isValidIssuer = nss3certificate_isValidIssuer;
            rvDC->getUsage = nss3certificate_getUsage;
            rvDC->isValidAtTime = nss3certificate_isValidAtTime;
            rvDC->isNewerThan = nss3certificate_isNewerThan;
            rvDC->matchUsage = nss3certificate_matchUsage;
            rvDC->isTrustedForUsage = nss3certificate_isTrustedForUsage;
            rvDC->getEmailAddress = nss3certificate_getEmailAddress;
            rvDC->getDERSerialNumber = nss3certificate_getDERSerialNumber;
        } else {
            CERT_DestroyCertificate(cert);
        }
    }
    return rvDC;
}

static nssDecodedCert *
create_decoded_pkix_cert_from_nss3cert(
    NSSArena *arenaOpt,
    CERTCertificate *cc)
{
    nssDecodedCert *rvDC = nss_ZNEW(arenaOpt, nssDecodedCert);
    if (rvDC) {
        rvDC->type = NSSCertificateType_PKIX;
        rvDC->data = (void *)cc;
        rvDC->getIdentifier = nss3certificate_getIdentifier;
        rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier;
        rvDC->matchIdentifier = nss3certificate_matchIdentifier;
        rvDC->isValidIssuer = nss3certificate_isValidIssuer;
        rvDC->getUsage = nss3certificate_getUsage;
        rvDC->isValidAtTime = nss3certificate_isValidAtTime;
        rvDC->isNewerThan = nss3certificate_isNewerThan;
        rvDC->matchUsage = nss3certificate_matchUsage;
        rvDC->isTrustedForUsage = nss3certificate_isTrustedForUsage;
        rvDC->getEmailAddress = nss3certificate_getEmailAddress;
        rvDC->getDERSerialNumber = nss3certificate_getDERSerialNumber;
    }
    return rvDC;
}

NSS_IMPLEMENT PRStatus
nssDecodedPKIXCertificate_Destroy(nssDecodedCert *dc)
{
    CERTCertificate *cert = (CERTCertificate *)dc->data;

    /* The decoder may only be half initialized (the case where we find we
     * could not decode the certificate). In this case, there is not cert to
     * free, just free the dc structure. */
    if (cert) {
        PRBool freeSlot = cert->ownSlot;
        PK11SlotInfo *slot = cert->slot;
        PLArenaPool *arena = cert->arena;
        /* zero cert before freeing. Any stale references to this cert
         * after this point will probably cause an exception.  */
        PORT_Memset(cert, 0, sizeof *cert);
        /* free the arena that contains the cert. */
        PORT_FreeArena(arena, PR_FALSE);
        if (slot && freeSlot) {
            PK11_FreeSlot(slot);
        }
    }
    nss_ZFreeIf(dc);
    return PR_SUCCESS;
}

/* see pk11cert.c:pk11_HandleTrustObject */
static unsigned int
get_nss3trust_from_nss4trust(nssTrustLevel t)
{
    unsigned int rt = 0;
    if (t == nssTrustLevel_Trusted) {
        rt |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
    }
    if (t == nssTrustLevel_TrustedDelegator) {
        rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA;
    }
    if (t == nssTrustLevel_NotTrusted) {
        rt |= CERTDB_TERMINAL_RECORD;
    }
    if (t == nssTrustLevel_ValidDelegator) {
        rt |= CERTDB_VALID_CA;
    }
    return rt;
}

static CERTCertTrust *
cert_trust_from_stan_trust(NSSTrust *t, PLArenaPool *arena)
{
    CERTCertTrust *rvTrust;
    unsigned int client;
    if (!t) {
        return NULL;
    }
    rvTrust = PORT_ArenaAlloc(arena, sizeof(CERTCertTrust));
    if (!rvTrust)
        return NULL;
    rvTrust->sslFlags = get_nss3trust_from_nss4trust(t->serverAuth);
    client = get_nss3trust_from_nss4trust(t->clientAuth);
    if (client & (CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA)) {
        client &= ~(CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA);
        rvTrust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA;
    }
    rvTrust->sslFlags |= client;
    rvTrust->emailFlags = get_nss3trust_from_nss4trust(t->emailProtection);
    rvTrust->objectSigningFlags = get_nss3trust_from_nss4trust(t->codeSigning);
    return rvTrust;
}

CERTCertTrust *
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
{
    CERTCertTrust *rvTrust = NULL;
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
    NSSTrust *t;
    t = nssTrustDomain_FindTrustForCertificate(td, c);
    if (t) {
        rvTrust = cert_trust_from_stan_trust(t, cc->arena);
        if (!rvTrust) {
            nssTrust_Destroy(t);
            return NULL;
        }
        nssTrust_Destroy(t);
    } else {
        rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
        if (!rvTrust) {
            return NULL;
        }
        memset(rvTrust, 0, sizeof(*rvTrust));
    }
    if (NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL)) {
        rvTrust->sslFlags |= CERTDB_USER;
        rvTrust->emailFlags |= CERTDB_USER;
        rvTrust->objectSigningFlags |= CERTDB_USER;
    }
    return rvTrust;
}

static nssCryptokiInstance *
get_cert_instance(NSSCertificate *c)
{
    nssCryptokiObject *instance, **ci;
    nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
    if (!instances) {
        return NULL;
    }
    instance = NULL;
    for (ci = instances; *ci; ci++) {
        if (!instance) {
            instance = nssCryptokiObject_Clone(*ci);
        } else {
            /* This only really works for two instances...  But 3.4 can't
             * handle more anyway.  The logic is, if there are multiple
             * instances, prefer the one that is not internal (e.g., on
             * a hardware device.
             */
            if (PK11_IsInternal(instance->token->pk11slot)) {
                nssCryptokiObject_Destroy(instance);
                instance = nssCryptokiObject_Clone(*ci);
            }
        }
    }
    nssCryptokiObjectArray_Destroy(instances);
    return instance;
}

char *
STAN_GetCERTCertificateNameForInstance(
    PLArenaPool *arenaOpt,
    NSSCertificate *c,
    nssCryptokiInstance *instance)
{
    NSSCryptoContext *context = c->object.cryptoContext;
    PRStatus nssrv;
    int nicklen, tokenlen, len;
    NSSUTF8 *tokenName = NULL;
    NSSUTF8 *stanNick = NULL;
    char *nickname = NULL;
    char *nick;

    if (instance) {
        stanNick = instance->label;
    } else if (context) {
        stanNick = c->object.tempName;
    }
    if (stanNick) {
        /* fill other fields needed by NSS3 functions using CERTCertificate */
        if (instance && (!PK11_IsInternalKeySlot(instance->token->pk11slot) ||
                         PORT_Strchr(stanNick, ':') != NULL)) {
            tokenName = nssToken_GetName(instance->token);
            tokenlen = nssUTF8_Size(tokenName, &nssrv);
        } else {
            /* don't use token name for internal slot; 3.3 didn't */
            tokenlen = 0;
        }
        nicklen = nssUTF8_Size(stanNick, &nssrv);
        len = tokenlen + nicklen;
        if (arenaOpt) {
            nickname = PORT_ArenaAlloc(arenaOpt, len);
        } else {
            nickname = PORT_Alloc(len);
        }
        nick = nickname;
        if (tokenName) {
            memcpy(nick, tokenName, tokenlen - 1);
            nick += tokenlen - 1;
            *nick++ = ':';
        }
        memcpy(nick, stanNick, nicklen - 1);
        nickname[len - 1] = '\0';
    }
    return nickname;
}

char *
STAN_GetCERTCertificateName(PLArenaPool *arenaOpt, NSSCertificate *c)
{
    char *result;
    nssCryptokiInstance *instance = get_cert_instance(c);
    /* It's OK to call this function, even if instance is NULL */
    result = STAN_GetCERTCertificateNameForInstance(arenaOpt, c, instance);
    if (instance)
        nssCryptokiObject_Destroy(instance);
    return result;
}

static void
fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced)
{
    CERTCertTrust *trust = NULL;
    NSSTrust *nssTrust;
    NSSCryptoContext *context = c->object.cryptoContext;
    nssCryptokiInstance *instance;
    NSSUTF8 *stanNick = NULL;

    /* We are holding the base class object's lock on entry of this function
     * This lock protects writes to fields of the CERTCertificate .
     * It is also needed by some functions to compute values such as trust.
     */
    instance = get_cert_instance(c);

    if (instance) {
        stanNick = instance->label;
    } else if (context) {
        stanNick = c->object.tempName;
    }
    /* fill other fields needed by NSS3 functions using CERTCertificate */
    if ((!cc->nickname && stanNick) || forced) {
        PRStatus nssrv;
        int nicklen, tokenlen, len;
        NSSUTF8 *tokenName = NULL;
        char *nick;
        if (instance &&
            (!PK11_IsInternalKeySlot(instance->token->pk11slot) ||
             (stanNick && PORT_Strchr(stanNick, ':') != NULL))) {
            tokenName = nssToken_GetName(instance->token);
            tokenlen = nssUTF8_Size(tokenName, &nssrv);
        } else {
            /* don't use token name for internal slot; 3.3 didn't */
            tokenlen = 0;
        }
        if (stanNick) {
            nicklen = nssUTF8_Size(stanNick, &nssrv);
            len = tokenlen + nicklen;
            nick = PORT_ArenaAlloc(cc->arena, len);
            if (tokenName) {
                memcpy(nick, tokenName, tokenlen - 1);
                nick[tokenlen - 1] = ':';
                memcpy(nick + tokenlen, stanNick, nicklen - 1);
            } else {
                memcpy(nick, stanNick, nicklen - 1);
            }
            nick[len - 1] = '\0';
            cc->nickname = nick;
        } else {
            cc->nickname = NULL;
        }
    }
    if (context) {
        /* trust */
        nssTrust = nssCryptoContext_FindTrustForCertificate(context, c);
        if (!nssTrust) {
            /* chicken and egg issue:
             *
             * c->issuer and c->serial are empty at this point, but
             * nssTrustDomain_FindTrustForCertificate use them to look up
             * up the trust object, so we point them to cc->derIssuer and
             * cc->serialNumber.
             *
             * Our caller will fill these in with proper arena copies when we
             * return. */
            c->issuer.data = cc->derIssuer.data;
            c->issuer.size = cc->derIssuer.len;
            c->serial.data = cc->serialNumber.data;
            c->serial.size = cc->serialNumber.len;
            nssTrust = nssTrustDomain_FindTrustForCertificate(context->td, c);
        }
        if (nssTrust) {
            trust = cert_trust_from_stan_trust(nssTrust, cc->arena);
            if (trust) {
                /* we should destroy cc->trust before replacing it, but it's
                   allocated in cc->arena, so memory growth will occur on each
                   refresh */
                CERT_LockCertTrust(cc);
                cc->trust = trust;
                CERT_UnlockCertTrust(cc);
            }
            nssTrust_Destroy(nssTrust);
        }
    } else if (instance) {
        /* slot */
        if (cc->slot != instance->token->pk11slot) {
            if (cc->slot) {
                PK11_FreeSlot(cc->slot);
            }
            cc->slot = PK11_ReferenceSlot(instance->token->pk11slot);
        }
        cc->ownSlot = PR_TRUE;
        /* pkcs11ID */
        cc->pkcs11ID = instance->handle;
        /* trust */
        trust = nssTrust_GetCERTCertTrustForCert(c, cc);
        if (trust) {
            /* we should destroy cc->trust before replacing it, but it's
               allocated in cc->arena, so memory growth will occur on each
               refresh */
            CERT_LockCertTrust(cc);
            cc->trust = trust;
            CERT_UnlockCertTrust(cc);
        }
        /* Read the distrust fields from a nssckbi/builtins certificate and
         * fill the fields in CERTCertificate structure when any valid date
         * is found. */
        if (PK11_IsReadOnly(cc->slot) && PK11_HasRootCerts(cc->slot)) {
            /* The values are hard-coded and readonly. Read just once. */
            if (cc->distrust == NULL) {
                CERTCertDistrust distrustModel;
                SECItem model = { siUTCTime, NULL, 0 };
                distrustModel.serverDistrustAfter = model;
                distrustModel.emailDistrustAfter = model;
                SECStatus rServer = PK11_ReadAttribute(
                    cc->slot, cc->pkcs11ID, CKA_NSS_SERVER_DISTRUST_AFTER,
                    cc->arena, &distrustModel.serverDistrustAfter);
                SECStatus rEmail = PK11_ReadAttribute(
                    cc->slot, cc->pkcs11ID, CKA_NSS_EMAIL_DISTRUST_AFTER,
                    cc->arena, &distrustModel.emailDistrustAfter);
                /* Only allocate the Distrust structure if a valid date is found.
                 * The result length of a encoded valid timestamp is exactly 13 */
                const unsigned int kDistrustFieldSize = 13;
                if ((rServer == SECSuccess && rEmail == SECSuccess) &&
                    (distrustModel.serverDistrustAfter.len == kDistrustFieldSize ||
                     distrustModel.emailDistrustAfter.len == kDistrustFieldSize)) {
                    CERTCertDistrust *tmpPtr = PORT_ArenaAlloc(
                        cc->arena, sizeof(CERTCertDistrust));
                    PORT_Memcpy(tmpPtr, &distrustModel,
                                sizeof(CERTCertDistrust));
                    cc->distrust = tmpPtr;
                }
            }
        }
    }
    if (instance) {
        nssCryptokiObject_Destroy(instance);
    }
    /* database handle is now the trust domain */
    cc->dbhandle = c->object.trustDomain;
    /* subjectList ? */
    /* istemp and isperm are supported in NSS 3.4 */
    CERT_LockCertTempPerm(cc);
    cc->istemp = PR_FALSE; /* CERT_NewTemp will override this */
    cc->isperm = PR_TRUE;  /* by default */
    /* pointer back */
    cc->nssCertificate = c;
    CERT_UnlockCertTempPerm(cc);
    if (trust) {
        /* force the cert type to be recomputed to include trust info */
        PRUint32 nsCertType = cert_ComputeCertType(cc);

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

static CERTCertificate *
stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate)
{
    nssDecodedCert *dc = NULL;
    CERTCertificate *cc = NULL;
    CERTCertTrust certTrust;

    /* make sure object does not go away until we finish */
    nssPKIObject_AddRef(&c->object);
    nssPKIObject_Lock(&c->object);

    dc = c->decoding;
    if (!dc) {
        dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding);
        if (!dc) {
            goto loser;
        }
        cc = (CERTCertificate *)dc->data;
        PORT_Assert(cc); /* software error */
        if (!cc) {
            nssDecodedPKIXCertificate_Destroy(dc);
            nss_SetError(NSS_ERROR_INTERNAL_ERROR);
            goto loser;
        }
        PORT_Assert(!c->decoding);
        if (!c->decoding) {
            c->decoding = dc;
        } else {
            /* this should never happen. Fail. */
            nssDecodedPKIXCertificate_Destroy(dc);
            nss_SetError(NSS_ERROR_INTERNAL_ERROR);
            goto loser;
        }
    }
    cc = (CERTCertificate *)dc->data;
    PORT_Assert(cc);
    if (!cc) {
        nss_SetError(NSS_ERROR_INTERNAL_ERROR);
        goto loser;
    }
    CERT_LockCertTempPerm(cc);
    NSSCertificate *nssCert = cc->nssCertificate;
    CERT_UnlockCertTempPerm(cc);
    if (!nssCert || forceUpdate) {
        fill_CERTCertificateFields(c, cc, forceUpdate);
    } else if (CERT_GetCertTrust(cc, &certTrust) != SECSuccess) {
        CERTCertTrust *trust;
        if (!c->object.cryptoContext) {
            /* If it's a perm cert, it might have been stored before the
             * trust, so look for the trust again.
             */
            trust = nssTrust_GetCERTCertTrustForCert(c, cc);
        } else {
            /* If it's a temp cert, it might have been stored before the
             * builtin trust module is loaded, so look for the trust
             * again, but don't set the empty trust if it is not found.
             */
            NSSTrust *t = nssTrustDomain_FindTrustForCertificate(c->object.cryptoContext->td, c);
            if (!t) {
                goto loser;
            }
            trust = cert_trust_from_stan_trust(t, cc->arena);
            nssTrust_Destroy(t);
            if (!trust) {
                goto loser;
            }
        }

        CERT_LockCertTrust(cc);
        cc->trust = trust;
        CERT_UnlockCertTrust(cc);
    }

loser:
    nssPKIObject_Unlock(&c->object);
    nssPKIObject_Destroy(&c->object);
    return cc;
}

NSS_IMPLEMENT CERTCertificate *
STAN_ForceCERTCertificateUpdate(NSSCertificate *c)
{
    if (c->decoding) {
        return stan_GetCERTCertificate(c, PR_TRUE);
    }
    return NULL;
}

NSS_IMPLEMENT CERTCertificate *
STAN_GetCERTCertificate(NSSCertificate *c)
{
    return stan_GetCERTCertificate(c, PR_FALSE);
}
/*
 * many callers of STAN_GetCERTCertificate() intend that
 * the CERTCertificate returned inherits the reference to the
 * NSSCertificate. For these callers it's convenient to have
 * this function 'own' the reference and either return a valid
 * CERTCertificate structure which inherits the reference or
 * destroy the reference to NSSCertificate and returns NULL.
 */
NSS_IMPLEMENT CERTCertificate *
STAN_GetCERTCertificateOrRelease(NSSCertificate *c)
{
    CERTCertificate *nss3cert = stan_GetCERTCertificate(c, PR_FALSE);
    if (!nss3cert) {
        nssCertificate_Destroy(c);
    }
    return nss3cert;
}

static nssTrustLevel
get_stan_trust(unsigned int t, PRBool isClientAuth)
{
    if (isClientAuth) {
        if (t & CERTDB_TRUSTED_CLIENT_CA) {
            return nssTrustLevel_TrustedDelegator;
        }
    } else {
        if (t & CERTDB_TRUSTED_CA || t & CERTDB_NS_TRUSTED_CA) {
            return nssTrustLevel_TrustedDelegator;
        }
    }
    if (t & CERTDB_TRUSTED) {
        return nssTrustLevel_Trusted;
    }
    if (t & CERTDB_TERMINAL_RECORD) {
        return nssTrustLevel_NotTrusted;
    }
    if (t & CERTDB_VALID_CA) {
        return nssTrustLevel_ValidDelegator;
    }
    return nssTrustLevel_MustVerify;
}

NSS_EXTERN NSSCertificate *
STAN_GetNSSCertificate(CERTCertificate *cc)
{
    NSSCertificate *c;
    nssCryptokiInstance *instance;
    nssPKIObject *pkiob;
    NSSArena *arena;
    CERT_LockCertTempPerm(cc);
    c = cc->nssCertificate;
    CERT_UnlockCertTempPerm(cc);
    if (c) {
        return c;
    }
    /* i don't think this should happen.  but if it can, need to create
     * NSSCertificate from CERTCertificate values here.  */
    /* Yup, it can happen. */
    arena = NSSArena_Create();
    if (!arena) {
        return NULL;
    }
    c = nss_ZNEW(arena, NSSCertificate);
    if (!c) {
        nssArena_Destroy(arena);
        return NULL;
    }
    NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert);
    c->type = NSSCertificateType_PKIX;
    pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKIMonitor);
    if (!pkiob) {
        nssArena_Destroy(arena);
        return NULL;
    }
    c->object = *pkiob;
    nssItem_Create(arena,
                   &c->issuer, cc->derIssuer.len, cc->derIssuer.data);
    nssItem_Create(arena,
                   &c->subject, cc->derSubject.len, cc->derSubject.data);
    /* CERTCertificate stores serial numbers decoded.  I need the DER
    * here.  sigh.
    */
    SECItem derSerial;
    SECStatus secrv;
    secrv = CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
    if (secrv == SECFailure) {
        nssArena_Destroy(arena);
        return NULL;
    }
    nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data);
    PORT_Free(derSerial.data);

    if (cc->emailAddr && cc->emailAddr[0]) {
        c->email = nssUTF8_Create(arena,
                                  nssStringType_PrintableString,
                                  (NSSUTF8 *)cc->emailAddr,
                                  PORT_Strlen(cc->emailAddr));
    }
    if (cc->slot) {
        instance = nss_ZNEW(arena, nssCryptokiInstance);
        if (!instance) {
            nssArena_Destroy(arena);
            return NULL;
        }
        instance->token = PK11Slot_GetNSSToken(cc->slot);
        if (!instance->token) {
            nssArena_Destroy(arena);
            return NULL;
        }
        instance->handle = cc->pkcs11ID;
        instance->isTokenObject = PR_TRUE;
        if (cc->nickname) {
            instance->label = nssUTF8_Create(arena,
                                             nssStringType_UTF8String,
                                             (NSSUTF8 *)cc->nickname,
                                             PORT_Strlen(cc->nickname));
        }
        nssPKIObject_AddInstance(&c->object, instance);
    }
    c->decoding = create_decoded_pkix_cert_from_nss3cert(NULL, cc);
    CERT_LockCertTempPerm(cc);
    cc->nssCertificate = c;
    CERT_UnlockCertTempPerm(cc);
    return c;
}

static NSSToken *
stan_GetTrustToken(
    NSSCertificate *c)
{
    NSSToken *ttok = NULL;
    NSSToken *rtok = NULL;
    NSSToken *tok = NULL;
    nssCryptokiObject **ip;
    nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
    if (!instances) {
        return PR_FALSE;
    }
    for (ip = instances; *ip; ip++) {
        nssCryptokiObject *instance = *ip;
        nssCryptokiObject *to =
            nssToken_FindTrustForCertificate(instance->token, NULL,
                                             &c->encoding, &c->issuer, &c->serial,
                                             nssTokenSearchType_TokenOnly);
        NSSToken *ctok = instance->token;
        PRBool ro = PK11_IsReadOnly(ctok->pk11slot);

        if (to) {
            nssCryptokiObject_Destroy(to);
            ttok = ctok;
            if (!ro) {
                break;
            }
        } else {
            if (!rtok && ro) {
                rtok = ctok;
            }
            if (!tok && !ro) {
                tok = ctok;
            }
        }
    }
    nssCryptokiObjectArray_Destroy(instances);
    return ttok ? ttok : (tok ? tok : rtok);
}

NSS_EXTERN PRStatus
STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
{
    PRStatus nssrv;
    NSSCertificate *c = STAN_GetNSSCertificate(cc);
    NSSToken *tok;
    NSSTrustDomain *td;
    NSSTrust *nssTrust;
    NSSArena *arena;
    CERTCertTrust *oldTrust;
    CERTCertTrust *newTrust;
    nssListIterator *tokens;
    PRBool moving_object;
    nssCryptokiObject *newInstance;
    nssPKIObject *pkiob;

    if (c == NULL) {
        return PR_FAILURE;
    }
    oldTrust = nssTrust_GetCERTCertTrustForCert(c, cc);
    if (oldTrust) {
        if (memcmp(oldTrust, trust, sizeof(CERTCertTrust)) == 0) {
            /* ... and the new trust is no different, done) */
            return PR_SUCCESS;
        } else {
            /* take over memory already allocated in cc's arena */
            newTrust = oldTrust;
        }
    } else {
        newTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
    }
    memcpy(newTrust, trust, sizeof(CERTCertTrust));
    CERT_LockCertTrust(cc);
    cc->trust = newTrust;
    CERT_UnlockCertTrust(cc);
    /* Set the NSSCerticate's trust */
    arena = nssArena_Create();
    if (!arena)
        return PR_FAILURE;
    nssTrust = nss_ZNEW(arena, NSSTrust);
    if (!nssTrust) {
        nssArena_Destroy(arena);
        return PR_FAILURE;
    }
    pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKILock);
    if (!pkiob) {
        nssArena_Destroy(arena);
        return PR_FAILURE;
    }
    nssTrust->object = *pkiob;
    nssTrust->certificate = c;
    nssTrust->serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE);
    nssTrust->clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE);
    nssTrust->emailProtection = get_stan_trust(trust->emailFlags, PR_FALSE);
    nssTrust->codeSigning = get_stan_trust(trust->objectSigningFlags, PR_FALSE);
    nssTrust->stepUpApproved =
        (PRBool)(trust->sslFlags & CERTDB_GOVT_APPROVED_CA);
    if (c->object.cryptoContext != NULL) {
        /* The cert is in a context, set the trust there */
        NSSCryptoContext *cctx = c->object.cryptoContext;
        nssrv = nssCryptoContext_ImportTrust(cctx, nssTrust);
        if (nssrv != PR_SUCCESS) {
            goto done;
        }
        if (c->object.numInstances == 0) {
            /* The context is the only instance, finished */
            goto done;
        }
    }
    td = STAN_GetDefaultTrustDomain();
    tok = stan_GetTrustToken(c);
    moving_object = PR_FALSE;
    if (tok && PK11_IsReadOnly(tok->pk11slot)) {
        NSSRWLock_LockRead(td->tokensLock);
        tokens = nssList_CreateIterator(td->tokenList);
        if (!tokens) {
            nssrv = PR_FAILURE;
            NSSRWLock_UnlockRead(td->tokensLock);
            goto done;
        }
        for (tok = (NSSToken *)nssListIterator_Start(tokens);
             tok != (NSSToken *)NULL;
             tok = (NSSToken *)nssListIterator_Next(tokens)) {
            if (!PK11_IsReadOnly(tok->pk11slot))
                break;
        }
        nssListIterator_Finish(tokens);
        nssListIterator_Destroy(tokens);
        NSSRWLock_UnlockRead(td->tokensLock);
        moving_object = PR_TRUE;
    }
    if (tok) {
        if (moving_object) {
            /* this is kind of hacky.  the softoken needs the cert
             * object in order to store trust.  forcing it to be perm
             */
            NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL);
            NSSASCII7 *email = NULL;

            if (PK11_IsInternal(tok->pk11slot)) {
                email = c->email;
            }
            newInstance = nssToken_ImportCertificate(tok, NULL,
                                                     NSSCertificateType_PKIX,
                                                     &c->id,
                                                     nickname,
                                                     &c->encoding,
                                                     &c->issuer,
                                                     &c->subject,
                                                     &c->serial,
                                                     email,
                                                     PR_TRUE);
            nss_ZFreeIf(nickname);
            nickname = NULL;
            if (!newInstance) {
                nssrv = PR_FAILURE;
                goto done;
            }
            nssPKIObject_AddInstance(&c->object, newInstance);
        }
        newInstance = nssToken_ImportTrust(tok, NULL, &c->encoding,
                                           &c->issuer, &c->serial,
                                           nssTrust->serverAuth,
                                           nssTrust->clientAuth,
                                           nssTrust->codeSigning,
                                           nssTrust->emailProtection,
                                           nssTrust->stepUpApproved, PR_TRUE);
        /* If the selected token can't handle trust, dump the trust on
         * the internal token */
        if (!newInstance && !PK11_IsInternalKeySlot(tok->pk11slot)) {
            PK11SlotInfo *slot = PK11_GetInternalKeySlot();
            NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL);
            NSSASCII7 *email = c->email;
            tok = PK11Slot_GetNSSToken(slot);
            PK11_FreeSlot(slot);
            if (!tok) {
                nssrv = PR_FAILURE;
                goto done;
            }

            newInstance = nssToken_ImportCertificate(tok, NULL,
                                                     NSSCertificateType_PKIX,
                                                     &c->id,
                                                     nickname,
                                                     &c->encoding,
                                                     &c->issuer,
                                                     &c->subject,
                                                     &c->serial,
                                                     email,
                                                     PR_TRUE);
            nss_ZFreeIf(nickname);
            nickname = NULL;
            if (!newInstance) {
                (void)nssToken_Destroy(tok);
                nssrv = PR_FAILURE;
                goto done;
            }
            nssPKIObject_AddInstance(&c->object, newInstance);
            newInstance = nssToken_ImportTrust(tok, NULL, &c->encoding,
                                               &c->issuer, &c->serial,
                                               nssTrust->serverAuth,
                                               nssTrust->clientAuth,
                                               nssTrust->codeSigning,
                                               nssTrust->emailProtection,
                                               nssTrust->stepUpApproved, PR_TRUE);
            (void)nssToken_Destroy(tok);
        }
        if (newInstance) {
            nssCryptokiObject_Destroy(newInstance);
            nssrv = PR_SUCCESS;
        } else {
            nssrv = PR_FAILURE;
        }
    } else {
        nssrv = PR_FAILURE;
    }
done:
    (void)nssTrust_Destroy(nssTrust);
    return nssrv;
}

/*
** Delete trust objects matching the given slot.
** Returns error if a device fails to delete.
**
** This function has the side effect of moving the
** surviving entries to the front of the object list
** and nullifying the rest.
*/
static PRStatus
DeleteCertTrustMatchingSlot(PK11SlotInfo *pk11slot, nssPKIObject *tObject)
{
    int numNotDestroyed = 0; /* the ones skipped plus the failures */
    int failureCount = 0;    /* actual deletion failures by devices */
    unsigned int index;

    nssPKIObject_AddRef(tObject);
    nssPKIObject_Lock(tObject);
    /* Keep going even if a module fails to delete. */
    for (index = 0; index < tObject->numInstances; index++) {
        nssCryptokiObject *instance = tObject->instances[index];
        if (!instance) {
            continue;
        }

        /* ReadOnly and not matched treated the same */
        if (PK11_IsReadOnly(instance->token->pk11slot) ||
            pk11slot != instance->token->pk11slot) {
            tObject->instances[numNotDestroyed++] = instance;
            continue;
        }

        /* Here we have found a matching one */
        tObject->instances[index] = NULL;
        if (nssToken_DeleteStoredObject(instance) == PR_SUCCESS) {
            nssCryptokiObject_Destroy(instance);
        } else {
            tObject->instances[numNotDestroyed++] = instance;
            failureCount++;
        }
    }
    if (numNotDestroyed == 0) {
        nss_ZFreeIf(tObject->instances);
        tObject->numInstances = 0;
    } else {
        tObject->numInstances = numNotDestroyed;
    }

    nssPKIObject_Unlock(tObject);
    nssPKIObject_Destroy(tObject);

    return failureCount == 0 ? PR_SUCCESS : PR_FAILURE;
}

/*
** Delete trust objects matching the slot of the given certificate.
** Returns an error if any device fails to delete.
*/
NSS_EXTERN PRStatus
STAN_DeleteCertTrustMatchingSlot(NSSCertificate *c)
{
    PRStatus nssrv = PR_SUCCESS;

    unsigned int i;
    nssPKIObject *tobject = NULL;
    nssPKIObject *cobject = &c->object;

    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
    NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c);
    if (!nssTrust) {
        return PR_FAILURE;
    }

    tobject = &nssTrust->object;

    /* Iterate through the cert and trust object instances looking for
     * those with matching pk11 slots to delete. Even if some device
     * can't delete we keep going. Keeping a status variable for the
     * loop so that once it's failed the other gets set.
     */
    NSSRWLock_LockRead(td->tokensLock);
    nssPKIObject_AddRef(cobject);
    nssPKIObject_Lock(cobject);
    for (i = 0; i < cobject->numInstances; i++) {
        nssCryptokiObject *cInstance = cobject->instances[i];
        if (cInstance && !PK11_IsReadOnly(cInstance->token->pk11slot)) {
            PRStatus status;
            if (!tobject->numInstances || !tobject->instances)
                continue;
            status = DeleteCertTrustMatchingSlot(cInstance->token->pk11slot, tobject);
            if (status == PR_FAILURE) {
                /* set the outer one but keep going */
                nssrv = PR_FAILURE;
            }
        }
    }
    nssTrust_Destroy(nssTrust);
    nssPKIObject_Unlock(cobject);
    nssPKIObject_Destroy(cobject);
    NSSRWLock_UnlockRead(td->tokensLock);
    return nssrv;
}

/* CERT_TraversePermCertsForSubject */
NSS_IMPLEMENT PRStatus
nssTrustDomain_TraverseCertificatesBySubject(
    NSSTrustDomain *td,
    NSSDER *subject,
    PRStatus (*callback)(NSSCertificate *c, void *arg),
    void *arg)
{
    PRStatus nssrv = PR_SUCCESS;
    NSSArena *tmpArena;
    NSSCertificate **subjectCerts;
    NSSCertificate *c;
    PRIntn i;
    tmpArena = NSSArena_Create();
    if (!tmpArena) {
        return PR_FAILURE;
    }
    subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td, subject, NULL,
                                                            0, tmpArena);
    if (subjectCerts) {
        for (i = 0, c = subjectCerts[i]; c; i++) {
            nssrv = callback(c, arg);
            if (nssrv != PR_SUCCESS)
                break;
        }
    }
    nssArena_Destroy(tmpArena);
    return nssrv;
}

/* CERT_TraversePermCertsForNickname */
NSS_IMPLEMENT PRStatus
nssTrustDomain_TraverseCertificatesByNickname(
    NSSTrustDomain *td,
    NSSUTF8 *nickname,
    PRStatus (*callback)(NSSCertificate *c, void *arg),
    void *arg)
{
    PRStatus nssrv = PR_SUCCESS;
    NSSArena *tmpArena;
    NSSCertificate **nickCerts;
    NSSCertificate *c;
    PRIntn i;
    tmpArena = NSSArena_Create();
    if (!tmpArena) {
        return PR_FAILURE;
    }
    nickCerts = NSSTrustDomain_FindCertificatesByNickname(td, nickname, NULL,
                                                          0, tmpArena);
    if (nickCerts) {
        for (i = 0, c = nickCerts[i]; c; i++) {
            nssrv = callback(c, arg);
            if (nssrv != PR_SUCCESS)
                break;
        }
    }
    nssArena_Destroy(tmpArena);
    return nssrv;
}

static void
cert_dump_iter(const void *k, void *v, void *a)
{
    NSSCertificate *c = (NSSCertificate *)k;
    CERTCertificate *cert = STAN_GetCERTCertificate(c);
    printf("[%2d] \"%s\"\n", c->object.refCount, cert->subjectName);
}

void
nss_DumpCertificateCacheInfo()
{
    NSSTrustDomain *td;
    NSSCryptoContext *cc;
    td = STAN_GetDefaultTrustDomain();
    cc = STAN_GetDefaultCryptoContext();
    printf("\n\nCertificates in the cache:\n");
    nssTrustDomain_DumpCacheInfo(td, cert_dump_iter, NULL);
    printf("\n\nCertificates in the temporary store:\n");
    if (cc->certStore) {
        nssCertificateStore_DumpStoreInfo(cc->certStore, cert_dump_iter, NULL);
    }
}
