/* 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);
    PK11Slot_SetNSSToken(slot, token);
    /* Don't add nonexistent token to TD's token list */
    if (token) {
        NSSRWLock_LockWrite(td->tokensLock);
        nssList_Add(td->tokenList, token);
        NSSRWLock_UnlockWrite(td->tokensLock);
    }
    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);
            nssToken_Destroy(token);
        }
    }
    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 = nssToken_AddRef(PK11Slot_GetNSSToken(cc->slot));
        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);

            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 (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);
    }
}
