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

/*
 * Permanent Certificate database handling code
 */
#include "lowkeyti.h"
#include "pcert.h"
#include "mcom_db.h"
#include "pcert.h"
#include "secitem.h"
#include "secder.h"

#include "secerr.h"
#include "lgdb.h"

/* forward declaration */
NSSLOWCERTCertificate *
nsslowcert_FindCertByDERCertNoLocking(NSSLOWCERTCertDBHandle *handle, SECItem *derCert);
static SECStatus
nsslowcert_UpdateSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle,
                              char *emailAddr, SECItem *derSubject, SECItem *emailProfile,
                              SECItem *profileTime);
static SECStatus
nsslowcert_UpdatePermCert(NSSLOWCERTCertDBHandle *dbhandle,
                          NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust);
static SECStatus
nsslowcert_UpdateCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
                     SECItem *crlKey, char *url, PRBool isKRL);

static NSSLOWCERTCertificate *certListHead = NULL;
static NSSLOWCERTTrust *trustListHead = NULL;
static certDBEntryCert *entryListHead = NULL;
static int certListCount = 0;
static int trustListCount = 0;
static int entryListCount = 0;
#define MAX_CERT_LIST_COUNT 10
#define MAX_TRUST_LIST_COUNT 10
#define MAX_ENTRY_LIST_COUNT 10

/*
 * the following functions are wrappers for the db library that implement
 * a global lock to make the database thread safe.
 */
static PZLock *dbLock = NULL;
static PZLock *certRefCountLock = NULL;
static PZLock *certTrustLock = NULL;
static PZLock *freeListLock = NULL;

void
certdb_InitDBLock(NSSLOWCERTCertDBHandle *handle)
{
    if (dbLock == NULL) {
        dbLock = PZ_NewLock(nssILockCertDB);
        PORT_Assert(dbLock != NULL);
    }
}

SECStatus
nsslowcert_InitLocks(void)
{
    if (freeListLock == NULL) {
        freeListLock = PZ_NewLock(nssILockRefLock);
        if (freeListLock == NULL) {
            return SECFailure;
        }
    }
    if (certRefCountLock == NULL) {
        certRefCountLock = PZ_NewLock(nssILockRefLock);
        if (certRefCountLock == NULL) {
            return SECFailure;
        }
    }
    if (certTrustLock == NULL) {
        certTrustLock = PZ_NewLock(nssILockCertDB);
        if (certTrustLock == NULL) {
            return SECFailure;
        }
    }

    return SECSuccess;
}

/*
 * Acquire the global lock on the cert database.
 * This lock is currently used for the following operations:
 *  adding or deleting a cert to either the temp or perm databases
 *  converting a temp to perm or perm to temp
 *  changing (maybe just adding!?) the trust of a cert
 *      chaning the DB status checking Configuration
 */
static void
nsslowcert_LockDB(NSSLOWCERTCertDBHandle *handle)
{
    PZ_EnterMonitor(handle->dbMon);
    return;
}

/*
 * Free the global cert database lock.
 */
static void
nsslowcert_UnlockDB(NSSLOWCERTCertDBHandle *handle)
{
#ifdef DEBUG
    PRStatus prstat = PZ_ExitMonitor(handle->dbMon);
    PORT_Assert(prstat == PR_SUCCESS);
#else
    PZ_ExitMonitor(handle->dbMon);
#endif
}

/*
 * Acquire the cert reference count lock
 * There is currently one global lock for all certs, but I'm putting a cert
 * arg here so that it will be easy to make it per-cert in the future if
 * that turns out to be necessary.
 */
static void
nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert)
{
    PORT_Assert(certRefCountLock != NULL);

    PZ_Lock(certRefCountLock);
    return;
}

/*
 * Free the cert reference count lock
 */
static void
nsslowcert_UnlockCertRefCount(NSSLOWCERTCertificate *cert)
{
    PORT_Assert(certRefCountLock != NULL);

#ifdef DEBUG
    {
        PRStatus prstat = PZ_Unlock(certRefCountLock);
        PORT_Assert(prstat == PR_SUCCESS);
    }
#else
    PZ_Unlock(certRefCountLock);
#endif
}

/*
 * Acquire the cert trust lock
 * There is currently one global lock for all certs, but I'm putting a cert
 * arg here so that it will be easy to make it per-cert in the future if
 * that turns out to be necessary.
 */
static void
nsslowcert_LockCertTrust(NSSLOWCERTCertificate *cert)
{
    PORT_Assert(certTrustLock != NULL);

    PZ_Lock(certTrustLock);
    return;
}

/*
 * Free the cert trust lock
 */
static void
nsslowcert_UnlockCertTrust(NSSLOWCERTCertificate *cert)
{
    PORT_Assert(certTrustLock != NULL);

#ifdef DEBUG
    {
        PRStatus prstat = PZ_Unlock(certTrustLock);
        PORT_Assert(prstat == PR_SUCCESS);
    }
#else
    PZ_Unlock(certTrustLock);
#endif
}

/*
 * Acquire the cert reference count lock
 * There is currently one global lock for all certs, but I'm putting a cert
 * arg here so that it will be easy to make it per-cert in the future if
 * that turns out to be necessary.
 */
static void
nsslowcert_LockFreeList(void)
{
    PORT_Assert(freeListLock != NULL);

    SKIP_AFTER_FORK(PZ_Lock(freeListLock));
    return;
}

/*
 * Free the cert reference count lock
 */
static void
nsslowcert_UnlockFreeList(void)
{
    PORT_Assert(freeListLock != NULL);

#ifdef DEBUG
    {
        PRStatus prstat = PR_SUCCESS;
        SKIP_AFTER_FORK(prstat = PZ_Unlock(freeListLock));
        PORT_Assert(prstat == PR_SUCCESS);
    }
#else
    SKIP_AFTER_FORK(PZ_Unlock(freeListLock));
#endif
}

NSSLOWCERTCertificate *
nsslowcert_DupCertificate(NSSLOWCERTCertificate *c)
{
    if (c) {
        nsslowcert_LockCertRefCount(c);
        ++c->referenceCount;
        nsslowcert_UnlockCertRefCount(c);
    }
    return c;
}

static int
certdb_Get(DB *db, DBT *key, DBT *data, unsigned int flags)
{
    int ret;

    PORT_Assert(dbLock != NULL);
    PZ_Lock(dbLock);

    ret = (*db->get)(db, key, data, flags);

    (void)PZ_Unlock(dbLock);

    return (ret);
}

static int
certdb_Put(DB *db, DBT *key, DBT *data, unsigned int flags)
{
    int ret = 0;

    PORT_Assert(dbLock != NULL);
    PZ_Lock(dbLock);

    ret = (*db->put)(db, key, data, flags);

    (void)PZ_Unlock(dbLock);

    return (ret);
}

static int
certdb_Sync(DB *db, unsigned int flags)
{
    int ret;

    PORT_Assert(dbLock != NULL);
    PZ_Lock(dbLock);

    ret = (*db->sync)(db, flags);

    (void)PZ_Unlock(dbLock);

    return (ret);
}

#define DB_NOT_FOUND -30991 /* from DBM 3.2 */
static int
certdb_Del(DB *db, DBT *key, unsigned int flags)
{
    int ret;

    PORT_Assert(dbLock != NULL);
    PZ_Lock(dbLock);

    ret = (*db->del)(db, key, flags);

    (void)PZ_Unlock(dbLock);

    /* don't fail if the record is already deleted */
    if (ret == DB_NOT_FOUND) {
        ret = 0;
    }

    return (ret);
}

static int
certdb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags)
{
    int ret;

    PORT_Assert(dbLock != NULL);
    PZ_Lock(dbLock);

    ret = (*db->seq)(db, key, data, flags);

    (void)PZ_Unlock(dbLock);

    return (ret);
}

static void
certdb_Close(DB *db)
{
    PORT_Assert(dbLock != NULL);
    SKIP_AFTER_FORK(PZ_Lock(dbLock));

    (*db->close)(db);

    SKIP_AFTER_FORK(PZ_Unlock(dbLock));

    return;
}

void
pkcs11_freeNickname(char *nickname, char *space)
{
    if (nickname && nickname != space) {
        PORT_Free(nickname);
    }
}

char *
pkcs11_copyNickname(char *nickname, char *space, int spaceLen)
{
    int len;
    char *copy = NULL;

    len = PORT_Strlen(nickname) + 1;
    if (len <= spaceLen) {
        copy = space;
        PORT_Memcpy(copy, nickname, len);
    } else {
        copy = PORT_Strdup(nickname);
    }

    return copy;
}

void
pkcs11_freeStaticData(unsigned char *data, unsigned char *space)
{
    if (data && data != space) {
        PORT_Free(data);
    }
}

unsigned char *
pkcs11_allocStaticData(int len, unsigned char *space, int spaceLen)
{
    unsigned char *data = NULL;

    if (len <= spaceLen) {
        data = space;
    } else {
        data = (unsigned char *)PORT_Alloc(len);
    }

    return data;
}

unsigned char *
pkcs11_copyStaticData(unsigned char *data, int len,
                      unsigned char *space, int spaceLen)
{
    unsigned char *copy = pkcs11_allocStaticData(len, space, spaceLen);
    if (copy) {
        PORT_Memcpy(copy, data, len);
    }

    return copy;
}

/*
 * destroy a database entry
 */
static void
DestroyDBEntry(certDBEntry *entry)
{
    PLArenaPool *arena = entry->common.arena;

    /* must be one of our certDBEntry from the free list */
    if (arena == NULL) {
        certDBEntryCert *certEntry;
        if (entry->common.type != certDBEntryTypeCert) {
            return;
        }
        certEntry = (certDBEntryCert *)entry;

        pkcs11_freeStaticData(certEntry->derCert.data, certEntry->derCertSpace);
        pkcs11_freeNickname(certEntry->nickname, certEntry->nicknameSpace);

        nsslowcert_LockFreeList();
        if (entryListCount > MAX_ENTRY_LIST_COUNT) {
            PORT_Free(certEntry);
        } else {
            entryListCount++;
            PORT_Memset(certEntry, 0, sizeof(*certEntry));
            certEntry->next = entryListHead;
            entryListHead = certEntry;
        }
        nsslowcert_UnlockFreeList();
        return;
    }

    /* Zero out the entry struct, so that any further attempts to use it
     * will cause an exception (e.g. null pointer reference). */
    PORT_Memset(&entry->common, 0, sizeof entry->common);
    PORT_FreeArena(arena, PR_FALSE);

    return;
}

/* forward references */
static void nsslowcert_DestroyCertificateNoLocking(NSSLOWCERTCertificate *cert);

static SECStatus
DeleteDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryType type, SECItem *dbkey)
{
    DBT key;
    int ret;

    /* init the database key */
    key.data = dbkey->data;
    key.size = dbkey->len;

    dbkey->data[0] = (unsigned char)type;

    /* delete entry from database */
    ret = certdb_Del(handle->permCertDB, &key, 0);
    if (ret != 0) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    ret = certdb_Sync(handle->permCertDB, 0);
    if (ret) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    return (SECSuccess);

loser:
    return (SECFailure);
}

static SECStatus
ReadDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCommon *entry,
            SECItem *dbkey, SECItem *dbentry, PLArenaPool *arena)
{
    DBT data, key;
    int ret;
    unsigned char *buf;

    /* init the database key */
    key.data = dbkey->data;
    key.size = dbkey->len;

    dbkey->data[0] = (unsigned char)entry->type;

    /* read entry from database */
    ret = certdb_Get(handle->permCertDB, &key, &data, 0);
    if (ret != 0) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    /* validate the entry */
    if (data.size < SEC_DB_ENTRY_HEADER_LEN) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }
    buf = (unsigned char *)data.data;
    /* version 7 has the same schema, we may be using a v7 db if we openned
     * the databases readonly. */
    if (!((buf[0] == (unsigned char)CERT_DB_FILE_VERSION) ||
          (buf[0] == (unsigned char)CERT_DB_V7_FILE_VERSION))) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }
    if (buf[1] != (unsigned char)entry->type) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    /* copy out header information */
    entry->version = (unsigned int)buf[0];
    entry->type = (certDBEntryType)buf[1];
    entry->flags = (unsigned int)buf[2];

    /* format body of entry for return to caller */
    dbentry->len = data.size - SEC_DB_ENTRY_HEADER_LEN;
    if (dbentry->len) {
        if (arena) {
            dbentry->data = (unsigned char *)
                PORT_ArenaAlloc(arena, dbentry->len);
            if (dbentry->data == NULL) {
                PORT_SetError(SEC_ERROR_NO_MEMORY);
                goto loser;
            }

            PORT_Memcpy(dbentry->data, &buf[SEC_DB_ENTRY_HEADER_LEN],
                        dbentry->len);
        } else {
            dbentry->data = &buf[SEC_DB_ENTRY_HEADER_LEN];
        }
    } else {
        dbentry->data = NULL;
    }

    return (SECSuccess);

loser:
    return (SECFailure);
}

/**
 ** Implement low level database access
 **/
static SECStatus
WriteDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCommon *entry,
             SECItem *dbkey, SECItem *dbentry)
{
    int ret;
    DBT data, key;
    unsigned char *buf;

    data.data = dbentry->data;
    data.size = dbentry->len;

    buf = (unsigned char *)data.data;

    buf[0] = (unsigned char)entry->version;
    buf[1] = (unsigned char)entry->type;
    buf[2] = (unsigned char)entry->flags;

    key.data = dbkey->data;
    key.size = dbkey->len;

    dbkey->data[0] = (unsigned char)entry->type;

    /* put the record into the database now */
    ret = certdb_Put(handle->permCertDB, &key, &data, 0);

    if (ret != 0) {
        goto loser;
    }

    ret = certdb_Sync(handle->permCertDB, 0);

    if (ret) {
        goto loser;
    }

    return (SECSuccess);

loser:
    return (SECFailure);
}

/*
 * encode a database cert record
 */
static SECStatus
EncodeDBCertEntry(certDBEntryCert *entry, PLArenaPool *arena, SECItem *dbitem)
{
    unsigned int nnlen;
    unsigned char *buf;
    char *nn;
    char zbuf = 0;

    if (entry->nickname) {
        nn = entry->nickname;
    } else {
        nn = &zbuf;
    }
    nnlen = PORT_Strlen(nn) + 1;

    /* allocate space for encoded database record, including space
     * for low level header
     */
    dbitem->len = entry->derCert.len + nnlen + DB_CERT_ENTRY_HEADER_LEN +
                  SEC_DB_ENTRY_HEADER_LEN;

    dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
    if (dbitem->data == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* fill in database record */
    buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];

    buf[0] = (PRUint8)(entry->trust.sslFlags >> 8);
    buf[1] = (PRUint8)(entry->trust.sslFlags);
    buf[2] = (PRUint8)(entry->trust.emailFlags >> 8);
    buf[3] = (PRUint8)(entry->trust.emailFlags);
    buf[4] = (PRUint8)(entry->trust.objectSigningFlags >> 8);
    buf[5] = (PRUint8)(entry->trust.objectSigningFlags);
    buf[6] = (PRUint8)(entry->derCert.len >> 8);
    buf[7] = (PRUint8)(entry->derCert.len);
    buf[8] = (PRUint8)(nnlen >> 8);
    buf[9] = (PRUint8)(nnlen);

    PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN], entry->derCert.data,
                entry->derCert.len);

    PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN + entry->derCert.len],
                nn, nnlen);

    return (SECSuccess);

loser:
    return (SECFailure);
}

/*
 * encode a database key for a cert record
 */
static SECStatus
EncodeDBCertKey(const SECItem *certKey, PLArenaPool *arena, SECItem *dbkey)
{
    unsigned int len = certKey->len + SEC_DB_KEY_HEADER_LEN;
    if (len > NSS_MAX_LEGACY_DB_KEY_SIZE)
        goto loser;
    if (arena) {
        dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
    } else {
        if (dbkey->len < len) {
            dbkey->data = (unsigned char *)PORT_Alloc(len);
        }
    }
    dbkey->len = len;
    if (dbkey->data == NULL) {
        goto loser;
    }
    PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN],
                certKey->data, certKey->len);
    dbkey->data[0] = certDBEntryTypeCert;

    return (SECSuccess);
loser:
    return (SECFailure);
}

static SECStatus
EncodeDBGenericKey(const SECItem *certKey, PLArenaPool *arena, SECItem *dbkey,
                   certDBEntryType entryType)
{
    /*
     * we only allow _one_ KRL key!
     */
    if (entryType == certDBEntryTypeKeyRevocation) {
        dbkey->len = SEC_DB_KEY_HEADER_LEN;
        dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
        if (dbkey->data == NULL) {
            goto loser;
        }
        dbkey->data[0] = (unsigned char)entryType;
        return (SECSuccess);
    }

    dbkey->len = certKey->len + SEC_DB_KEY_HEADER_LEN;
    if (dbkey->len > NSS_MAX_LEGACY_DB_KEY_SIZE)
        goto loser;
    dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
    if (dbkey->data == NULL) {
        goto loser;
    }
    PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN],
                certKey->data, certKey->len);
    dbkey->data[0] = (unsigned char)entryType;

    return (SECSuccess);
loser:
    return (SECFailure);
}

static SECStatus
DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry)
{
    unsigned int nnlen;
    unsigned int headerlen;
    int lenoff;

    /* allow updates of old versions of the database */
    switch (entry->common.version) {
        case 5:
            headerlen = DB_CERT_V5_ENTRY_HEADER_LEN;
            lenoff = 3;
            break;
        case 6:
            /* should not get here */
            PORT_Assert(0);
            headerlen = DB_CERT_V6_ENTRY_HEADER_LEN;
            lenoff = 3;
            break;
        case 7:
        case 8:
            headerlen = DB_CERT_ENTRY_HEADER_LEN;
            lenoff = 6;
            break;
        default:
            /* better not get here */
            PORT_Assert(0);
            headerlen = DB_CERT_V5_ENTRY_HEADER_LEN;
            lenoff = 3;
            break;
    }

    /* is record long enough for header? */
    if (dbentry->len < headerlen) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    /* is database entry correct length? */
    entry->derCert.len = ((dbentry->data[lenoff] << 8) |
                          dbentry->data[lenoff + 1]);
    nnlen = ((dbentry->data[lenoff + 2] << 8) | dbentry->data[lenoff + 3]);
    lenoff = dbentry->len - (entry->derCert.len + nnlen + headerlen);
    if (lenoff) {
        if (lenoff < 0 || (lenoff & 0xffff) != 0) {
            PORT_SetError(SEC_ERROR_BAD_DATABASE);
            goto loser;
        }
        /* The cert size exceeded 64KB.  Reconstruct the correct length. */
        entry->derCert.len += lenoff;
    }

    /* Is data long enough? */
    if (dbentry->len < headerlen + entry->derCert.len) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    /* copy the dercert */
    entry->derCert.data = pkcs11_copyStaticData(&dbentry->data[headerlen],
                                                entry->derCert.len, entry->derCertSpace, sizeof(entry->derCertSpace));
    if (entry->derCert.data == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* copy the nickname */
    if (nnlen > 1) {
        /* Is data long enough? */
        if (dbentry->len < headerlen + entry->derCert.len + nnlen) {
            PORT_SetError(SEC_ERROR_BAD_DATABASE);
            goto loser;
        }
        entry->nickname = (char *)pkcs11_copyStaticData(
            &dbentry->data[headerlen + entry->derCert.len], nnlen,
            (unsigned char *)entry->nicknameSpace,
            sizeof(entry->nicknameSpace));
        if (entry->nickname == NULL) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
    } else {
        entry->nickname = NULL;
    }

    if (entry->common.version < 7) {
        /* allow updates of v5 db */
        entry->trust.sslFlags = dbentry->data[0];
        entry->trust.emailFlags = dbentry->data[1];
        entry->trust.objectSigningFlags = dbentry->data[2];
    } else {
        entry->trust.sslFlags = (dbentry->data[0] << 8) | dbentry->data[1];
        entry->trust.emailFlags = (dbentry->data[2] << 8) | dbentry->data[3];
        entry->trust.objectSigningFlags =
            (dbentry->data[4] << 8) | dbentry->data[5];
    }

    return (SECSuccess);
loser:
    return (SECFailure);
}

/*
 * Create a new certDBEntryCert from existing data
 */
static certDBEntryCert *
NewDBCertEntry(SECItem *derCert, char *nickname,
               NSSLOWCERTCertTrust *trust, int flags)
{
    certDBEntryCert *entry;
    PLArenaPool *arena = NULL;
    int nnlen;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        goto loser;
    }

    entry = PORT_ArenaZNew(arena, certDBEntryCert);
    if (entry == NULL) {
        goto loser;
    }

    /* fill in the dbCert */
    entry->common.arena = arena;
    entry->common.type = certDBEntryTypeCert;
    entry->common.version = CERT_DB_FILE_VERSION;
    entry->common.flags = flags;

    if (trust) {
        entry->trust = *trust;
    }

    entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, derCert->len);
    if (!entry->derCert.data) {
        goto loser;
    }
    entry->derCert.len = derCert->len;
    PORT_Memcpy(entry->derCert.data, derCert->data, derCert->len);

    nnlen = (nickname ? strlen(nickname) + 1 : 0);

    if (nnlen) {
        entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
        if (!entry->nickname) {
            goto loser;
        }
        PORT_Memcpy(entry->nickname, nickname, nnlen);

    } else {
        entry->nickname = 0;
    }

    return (entry);

loser:

    /* allocation error, free arena and return */
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    PORT_SetError(SEC_ERROR_NO_MEMORY);
    return (0);
}

/*
 * Decode a version 4 DBCert from the byte stream database format
 * and construct a current database entry struct
 */
static certDBEntryCert *
DecodeV4DBCertEntry(unsigned char *buf, int len)
{
    certDBEntryCert *entry;
    int certlen;
    int nnlen;
    PLArenaPool *arena;

    /* make sure length is at least long enough for the header */
    if (len < DBCERT_V4_HEADER_LEN) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        return (0);
    }

    /* get other lengths */
    certlen = buf[3] << 8 | buf[4];
    nnlen = buf[5] << 8 | buf[6];

    /* make sure DB entry is the right size */
    if ((certlen + nnlen + DBCERT_V4_HEADER_LEN) != len) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        return (0);
    }

    /* allocate arena */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return (0);
    }

    /* allocate structure and members */
    entry = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));

    if (!entry) {
        goto loser;
    }

    entry->common.arena = arena;
    entry->common.version = CERT_DB_FILE_VERSION;
    entry->common.type = certDBEntryTypeCert;
    entry->common.flags = 0;
    entry->trust.sslFlags = buf[0];
    entry->trust.emailFlags = buf[1];
    entry->trust.objectSigningFlags = buf[2];

    entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen);
    if (!entry->derCert.data) {
        goto loser;
    }
    entry->derCert.len = certlen;
    PORT_Memcpy(entry->derCert.data, &buf[DBCERT_V4_HEADER_LEN], certlen);

    if (nnlen) {
        entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
        if (!entry->nickname) {
            goto loser;
        }
        PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen);

        if (PORT_Strcmp(entry->nickname, "Server-Cert") == 0) {
            entry->trust.sslFlags |= CERTDB_USER;
        }
    } else {
        entry->nickname = 0;
    }

    return (entry);

loser:
    PORT_FreeArena(arena, PR_FALSE);
    PORT_SetError(SEC_ERROR_NO_MEMORY);
    return (0);
}

/*
 * Encode a Certificate database entry into byte stream suitable for
 * the database
 */
static SECStatus
WriteDBCertEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry)
{
    SECItem dbitem, dbkey;
    PLArenaPool *tmparena = NULL;
    SECItem tmpitem;
    SECStatus rv;

    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (tmparena == NULL) {
        goto loser;
    }

    rv = EncodeDBCertEntry(entry, tmparena, &dbitem);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* get the database key and format it */
    rv = nsslowcert_KeyFromDERCert(tmparena, &entry->derCert, &tmpitem);
    if (rv == SECFailure) {
        goto loser;
    }

    rv = EncodeDBCertKey(&tmpitem, tmparena, &dbkey);
    if (rv == SECFailure) {
        goto loser;
    }

    /* now write it to the database */
    rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_FreeArena(tmparena, PR_FALSE);
    return (SECSuccess);

loser:
    if (tmparena) {
        PORT_FreeArena(tmparena, PR_FALSE);
    }
    return (SECFailure);
}

/*
 * delete a certificate entry
 */
static SECStatus
DeleteDBCertEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey)
{
    SECItem dbkey;
    SECStatus rv;

    dbkey.data = NULL;
    dbkey.len = 0;

    rv = EncodeDBCertKey(certKey, NULL, &dbkey);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = DeleteDBEntry(handle, certDBEntryTypeCert, &dbkey);
    if (rv == SECFailure) {
        goto loser;
    }

    PORT_Free(dbkey.data);

    return (SECSuccess);

loser:
    if (dbkey.data) {
        PORT_Free(dbkey.data);
    }
    return (SECFailure);
}

static certDBEntryCert *
CreateCertEntry(void)
{
    certDBEntryCert *entry;

    nsslowcert_LockFreeList();
    entry = entryListHead;
    if (entry) {
        entryListCount--;
        entryListHead = entry->next;
    }
    PORT_Assert(entryListCount >= 0);
    nsslowcert_UnlockFreeList();
    if (entry) {
        return entry;
    }

    return PORT_ZNew(certDBEntryCert);
}

static void
DestroyCertEntryFreeList(void)
{
    certDBEntryCert *entry;

    nsslowcert_LockFreeList();
    while (NULL != (entry = entryListHead)) {
        entryListCount--;
        entryListHead = entry->next;
        PORT_Free(entry);
    }
    PORT_Assert(!entryListCount);
    entryListCount = 0;
    nsslowcert_UnlockFreeList();
}

/*
 * Read a certificate entry
 */
static certDBEntryCert *
ReadDBCertEntry(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey)
{
    certDBEntryCert *entry;
    SECItem dbkey;
    SECItem dbentry;
    SECStatus rv;
    unsigned char buf[512];

    dbkey.data = buf;
    dbkey.len = sizeof(buf);

    entry = CreateCertEntry();
    if (entry == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    entry->common.arena = NULL;
    entry->common.type = certDBEntryTypeCert;

    rv = EncodeDBCertKey(certKey, NULL, &dbkey);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, NULL);
    if (rv == SECFailure) {
        goto loser;
    }

    rv = DecodeDBCertEntry(entry, &dbentry);
    if (rv != SECSuccess) {
        goto loser;
    }

    pkcs11_freeStaticData(dbkey.data, buf);
    dbkey.data = NULL;
    return (entry);

loser:
    pkcs11_freeStaticData(dbkey.data, buf);
    dbkey.data = NULL;
    if (entry) {
        DestroyDBEntry((certDBEntry *)entry);
    }

    return (NULL);
}

/*
 * encode a database cert record
 */
static SECStatus
EncodeDBCrlEntry(certDBEntryRevocation *entry, PLArenaPool *arena, SECItem *dbitem)
{
    unsigned int nnlen = 0;
    unsigned char *buf;

    if (entry->url) {
        nnlen = PORT_Strlen(entry->url) + 1;
    }

    /* allocate space for encoded database record, including space
     * for low level header
     */
    dbitem->len = entry->derCrl.len + nnlen + SEC_DB_ENTRY_HEADER_LEN + DB_CRL_ENTRY_HEADER_LEN;

    dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
    if (dbitem->data == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* fill in database record */
    buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];

    buf[0] = (PRUint8)(entry->derCrl.len >> 8);
    buf[1] = (PRUint8)(entry->derCrl.len);
    buf[2] = (PRUint8)(nnlen >> 8);
    buf[3] = (PRUint8)(nnlen);

    PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN], entry->derCrl.data,
                entry->derCrl.len);

    if (nnlen != 0) {
        PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],
                    entry->url, nnlen);
    }

    return (SECSuccess);

loser:
    return (SECFailure);
}

static SECStatus
DecodeDBCrlEntry(certDBEntryRevocation *entry, SECItem *dbentry)
{
    unsigned int urlLen;
    int lenDiff;

    /* is record long enough for header? */
    if (dbentry->len < DB_CRL_ENTRY_HEADER_LEN) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    /* is database entry correct length? */
    entry->derCrl.len = ((dbentry->data[0] << 8) | dbentry->data[1]);
    urlLen = ((dbentry->data[2] << 8) | dbentry->data[3]);
    lenDiff = dbentry->len -
              (entry->derCrl.len + urlLen + DB_CRL_ENTRY_HEADER_LEN);
    if (lenDiff) {
        if (lenDiff < 0 || (lenDiff & 0xffff) != 0) {
            PORT_SetError(SEC_ERROR_BAD_DATABASE);
            goto loser;
        }
        /* CRL entry is greater than 64 K. Hack to make this continue to work */
        entry->derCrl.len += lenDiff;
    }

    /* copy the der CRL */
    entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
                                                          entry->derCrl.len);
    if (entry->derCrl.data == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    PORT_Memcpy(entry->derCrl.data, &dbentry->data[DB_CRL_ENTRY_HEADER_LEN],
                entry->derCrl.len);

    /* copy the url */
    entry->url = NULL;
    if (urlLen != 0) {
        entry->url = (char *)PORT_ArenaAlloc(entry->common.arena, urlLen);
        if (entry->url == NULL) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
        PORT_Memcpy(entry->url,
                    &dbentry->data[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],
                    urlLen);
    }

    return (SECSuccess);
loser:
    return (SECFailure);
}

/*
 * Create a new certDBEntryRevocation from existing data
 */
static certDBEntryRevocation *
NewDBCrlEntry(SECItem *derCrl, char *url, certDBEntryType crlType, int flags)
{
    certDBEntryRevocation *entry;
    PLArenaPool *arena = NULL;
    int nnlen;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        goto loser;
    }

    entry = PORT_ArenaZNew(arena, certDBEntryRevocation);
    if (entry == NULL) {
        goto loser;
    }

    /* fill in the dbRevolcation */
    entry->common.arena = arena;
    entry->common.type = crlType;
    entry->common.version = CERT_DB_FILE_VERSION;
    entry->common.flags = flags;

    entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(arena, derCrl->len);
    if (!entry->derCrl.data) {
        goto loser;
    }

    if (url) {
        nnlen = PORT_Strlen(url) + 1;
        entry->url = (char *)PORT_ArenaAlloc(arena, nnlen);
        if (!entry->url) {
            goto loser;
        }
        PORT_Memcpy(entry->url, url, nnlen);
    } else {
        entry->url = NULL;
    }

    entry->derCrl.len = derCrl->len;
    PORT_Memcpy(entry->derCrl.data, derCrl->data, derCrl->len);

    return (entry);

loser:

    /* allocation error, free arena and return */
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    PORT_SetError(SEC_ERROR_NO_MEMORY);
    return (0);
}

static SECStatus
WriteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryRevocation *entry,
                SECItem *crlKey)
{
    SECItem dbkey;
    PLArenaPool *tmparena = NULL;
    SECItem encodedEntry;
    SECStatus rv;

    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (tmparena == NULL) {
        goto loser;
    }

    rv = EncodeDBCrlEntry(entry, tmparena, &encodedEntry);
    if (rv == SECFailure) {
        goto loser;
    }

    rv = EncodeDBGenericKey(crlKey, tmparena, &dbkey, entry->common.type);
    if (rv == SECFailure) {
        goto loser;
    }

    /* now write it to the database */
    rv = WriteDBEntry(handle, &entry->common, &dbkey, &encodedEntry);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_FreeArena(tmparena, PR_FALSE);
    return (SECSuccess);

loser:
    if (tmparena) {
        PORT_FreeArena(tmparena, PR_FALSE);
    }
    return (SECFailure);
}
/*
 * delete a crl entry
 */
static SECStatus
DeleteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, const SECItem *crlKey,
                 certDBEntryType crlType)
{
    SECItem dbkey;
    PLArenaPool *arena = NULL;
    SECStatus rv;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }

    rv = EncodeDBGenericKey(crlKey, arena, &dbkey, crlType);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = DeleteDBEntry(handle, crlType, &dbkey);
    if (rv == SECFailure) {
        goto loser;
    }

    PORT_FreeArena(arena, PR_FALSE);
    return (SECSuccess);

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (SECFailure);
}

/*
 * Read a certificate entry
 */
static certDBEntryRevocation *
ReadDBCrlEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey,
               certDBEntryType crlType)
{
    PLArenaPool *arena = NULL;
    PLArenaPool *tmparena = NULL;
    certDBEntryRevocation *entry;
    SECItem dbkey;
    SECItem dbentry;
    SECStatus rv;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (tmparena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    entry = (certDBEntryRevocation *)
        PORT_ArenaAlloc(arena, sizeof(certDBEntryRevocation));
    if (entry == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    entry->common.arena = arena;
    entry->common.type = crlType;

    rv = EncodeDBGenericKey(certKey, tmparena, &dbkey, crlType);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, NULL);
    if (rv == SECFailure) {
        goto loser;
    }

    rv = DecodeDBCrlEntry(entry, &dbentry);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_FreeArena(tmparena, PR_FALSE);
    return (entry);

loser:
    if (tmparena) {
        PORT_FreeArena(tmparena, PR_FALSE);
    }
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (NULL);
}

void
nsslowcert_DestroyDBEntry(certDBEntry *entry)
{
    DestroyDBEntry(entry);
    return;
}

/*
 * Encode a database nickname record
 */
static SECStatus
EncodeDBNicknameEntry(certDBEntryNickname *entry, PLArenaPool *arena,
                      SECItem *dbitem)
{
    unsigned char *buf;

    /* allocate space for encoded database record, including space
     * for low level header
     */
    dbitem->len = entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN +
                  SEC_DB_ENTRY_HEADER_LEN;
    dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
    if (dbitem->data == NULL) {
        goto loser;
    }

    /* fill in database record */
    buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
    buf[0] = (PRUint8)(entry->subjectName.len >> 8);
    buf[1] = (PRUint8)(entry->subjectName.len);
    PORT_Memcpy(&buf[DB_NICKNAME_ENTRY_HEADER_LEN], entry->subjectName.data,
                entry->subjectName.len);

    return (SECSuccess);

loser:
    return (SECFailure);
}

/*
 * Encode a database key for a nickname record
 */
static SECStatus
EncodeDBNicknameKey(char *nickname, PLArenaPool *arena,
                    SECItem *dbkey)
{
    unsigned int nnlen;

    nnlen = PORT_Strlen(nickname) + 1; /* includes null */

    /* now get the database key and format it */
    dbkey->len = nnlen + SEC_DB_KEY_HEADER_LEN;
    if (dbkey->len > NSS_MAX_LEGACY_DB_KEY_SIZE)
        goto loser;
    dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
    if (dbkey->data == NULL) {
        goto loser;
    }
    PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], nickname, nnlen);
    dbkey->data[0] = certDBEntryTypeNickname;

    return (SECSuccess);

loser:
    return (SECFailure);
}

static SECStatus
DecodeDBNicknameEntry(certDBEntryNickname *entry, SECItem *dbentry,
                      char *nickname)
{
    int lenDiff;

    /* is record long enough for header? */
    if (dbentry->len < DB_NICKNAME_ENTRY_HEADER_LEN) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    /* is database entry correct length? */
    entry->subjectName.len = ((dbentry->data[0] << 8) | dbentry->data[1]);
    lenDiff = dbentry->len -
              (entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN);
    if (lenDiff) {
        if (lenDiff < 0 || (lenDiff & 0xffff) != 0) {
            PORT_SetError(SEC_ERROR_BAD_DATABASE);
            goto loser;
        }
        /* The entry size exceeded 64KB.  Reconstruct the correct length. */
        entry->subjectName.len += lenDiff;
    }

    /* copy the certkey */
    entry->subjectName.data =
        (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
                                         entry->subjectName.len);
    if (entry->subjectName.data == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    PORT_Memcpy(entry->subjectName.data,
                &dbentry->data[DB_NICKNAME_ENTRY_HEADER_LEN],
                entry->subjectName.len);
    entry->subjectName.type = siBuffer;

    entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena,
                                              PORT_Strlen(nickname) + 1);
    if (entry->nickname) {
        PORT_Strcpy(entry->nickname, nickname);
    }

    return (SECSuccess);

loser:
    return (SECFailure);
}

/*
 * create a new nickname entry
 */
static certDBEntryNickname *
NewDBNicknameEntry(char *nickname, SECItem *subjectName, unsigned int flags)
{
    PLArenaPool *arena = NULL;
    certDBEntryNickname *entry;
    int nnlen;
    SECStatus rv;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena,
                                                   sizeof(certDBEntryNickname));
    if (entry == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* init common fields */
    entry->common.arena = arena;
    entry->common.type = certDBEntryTypeNickname;
    entry->common.version = CERT_DB_FILE_VERSION;
    entry->common.flags = flags;

    /* copy the nickname */
    nnlen = PORT_Strlen(nickname) + 1;

    entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
    if (entry->nickname == NULL) {
        goto loser;
    }

    PORT_Memcpy(entry->nickname, nickname, nnlen);

    rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName);
    if (rv != SECSuccess) {
        goto loser;
    }

    return (entry);
loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (NULL);
}

/*
 * delete a nickname entry
 */
static SECStatus
DeleteDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, char *nickname)
{
    PLArenaPool *arena = NULL;
    SECStatus rv;
    SECItem dbkey;

    if (nickname == NULL) {
        return (SECSuccess);
    }

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }

    rv = EncodeDBNicknameKey(nickname, arena, &dbkey);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = DeleteDBEntry(handle, certDBEntryTypeNickname, &dbkey);
    if (rv == SECFailure) {
        goto loser;
    }

    PORT_FreeArena(arena, PR_FALSE);
    return (SECSuccess);

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (SECFailure);
}

/*
 * Read a nickname entry
 */
static certDBEntryNickname *
ReadDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, char *nickname)
{
    PLArenaPool *arena = NULL;
    PLArenaPool *tmparena = NULL;
    certDBEntryNickname *entry;
    SECItem dbkey;
    SECItem dbentry;
    SECStatus rv;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (tmparena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena,
                                                   sizeof(certDBEntryNickname));
    if (entry == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    entry->common.arena = arena;
    entry->common.type = certDBEntryTypeNickname;

    rv = EncodeDBNicknameKey(nickname, tmparena, &dbkey);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
    if (rv == SECFailure) {
        goto loser;
    }

    /* is record long enough for header? */
    if (dbentry.len < DB_NICKNAME_ENTRY_HEADER_LEN) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    rv = DecodeDBNicknameEntry(entry, &dbentry, nickname);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_FreeArena(tmparena, PR_FALSE);
    return (entry);

loser:
    if (tmparena) {
        PORT_FreeArena(tmparena, PR_FALSE);
    }
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (NULL);
}

/*
 * Encode a nickname entry into byte stream suitable for
 * the database
 */
static SECStatus
WriteDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryNickname *entry)
{
    SECItem dbitem, dbkey;
    PLArenaPool *tmparena = NULL;
    SECStatus rv;

    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (tmparena == NULL) {
        goto loser;
    }

    rv = EncodeDBNicknameEntry(entry, tmparena, &dbitem);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = EncodeDBNicknameKey(entry->nickname, tmparena, &dbkey);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* now write it to the database */
    rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_FreeArena(tmparena, PR_FALSE);
    return (SECSuccess);

loser:
    if (tmparena) {
        PORT_FreeArena(tmparena, PR_FALSE);
    }
    return (SECFailure);
}

static SECStatus
EncodeDBSMimeEntry(certDBEntrySMime *entry, PLArenaPool *arena,
                   SECItem *dbitem)
{
    unsigned char *buf;

    /* allocate space for encoded database record, including space
     * for low level header
     */
    dbitem->len = entry->subjectName.len + entry->smimeOptions.len +
                  entry->optionsDate.len +
                  DB_SMIME_ENTRY_HEADER_LEN + SEC_DB_ENTRY_HEADER_LEN;

    dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
    if (dbitem->data == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* fill in database record */
    buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];

    buf[0] = (PRUint8)(entry->subjectName.len >> 8);
    buf[1] = (PRUint8)(entry->subjectName.len);
    buf[2] = (PRUint8)(entry->smimeOptions.len >> 8);
    buf[3] = (PRUint8)(entry->smimeOptions.len);
    buf[4] = (PRUint8)(entry->optionsDate.len >> 8);
    buf[5] = (PRUint8)(entry->optionsDate.len);

    /* if no smime options, then there should not be an options date either */
    PORT_Assert(!((entry->smimeOptions.len == 0) &&
                  (entry->optionsDate.len != 0)));

    PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN], entry->subjectName.data,
                entry->subjectName.len);
    if (entry->smimeOptions.len) {
        PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN + entry->subjectName.len],
                    entry->smimeOptions.data,
                    entry->smimeOptions.len);
        PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN + entry->subjectName.len +
                         entry->smimeOptions.len],
                    entry->optionsDate.data,
                    entry->optionsDate.len);
    }

    return (SECSuccess);

loser:
    return (SECFailure);
}

/*
 * Encode a database key for a SMIME record
 */
static SECStatus
EncodeDBSMimeKey(char *emailAddr, PLArenaPool *arena,
                 SECItem *dbkey)
{
    unsigned int addrlen;

    addrlen = PORT_Strlen(emailAddr) + 1; /* includes null */

    /* now get the database key and format it */
    dbkey->len = addrlen + SEC_DB_KEY_HEADER_LEN;
    if (dbkey->len > NSS_MAX_LEGACY_DB_KEY_SIZE)
        goto loser;
    dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
    if (dbkey->data == NULL) {
        goto loser;
    }
    PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], emailAddr, addrlen);
    dbkey->data[0] = certDBEntryTypeSMimeProfile;

    return (SECSuccess);

loser:
    return (SECFailure);
}

/*
 * Decode a database SMIME record
 */
static SECStatus
DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr)
{
    int lenDiff;

    /* is record long enough for header? */
    if (dbentry->len < DB_SMIME_ENTRY_HEADER_LEN) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    /* is database entry correct length? */
    entry->subjectName.len = ((dbentry->data[0] << 8) | dbentry->data[1]);
    entry->smimeOptions.len = ((dbentry->data[2] << 8) | dbentry->data[3]);
    entry->optionsDate.len = ((dbentry->data[4] << 8) | dbentry->data[5]);
    lenDiff = dbentry->len - (entry->subjectName.len +
                              entry->smimeOptions.len +
                              entry->optionsDate.len +
                              DB_SMIME_ENTRY_HEADER_LEN);
    if (lenDiff) {
        if (lenDiff < 0 || (lenDiff & 0xffff) != 0) {
            PORT_SetError(SEC_ERROR_BAD_DATABASE);
            goto loser;
        }
        /* The entry size exceeded 64KB.  Reconstruct the correct length. */
        entry->subjectName.len += lenDiff;
    }

    /* copy the subject name */
    entry->subjectName.data =
        (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
                                         entry->subjectName.len);
    if (entry->subjectName.data == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    PORT_Memcpy(entry->subjectName.data,
                &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN],
                entry->subjectName.len);

    /* copy the smime options */
    if (entry->smimeOptions.len) {
        entry->smimeOptions.data =
            (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
                                             entry->smimeOptions.len);
        if (entry->smimeOptions.data == NULL) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
        PORT_Memcpy(entry->smimeOptions.data,
                    &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN +
                                   entry->subjectName.len],
                    entry->smimeOptions.len);
    } else {
        entry->smimeOptions.data = NULL;
    }
    if (entry->optionsDate.len) {
        entry->optionsDate.data =
            (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
                                             entry->optionsDate.len);
        if (entry->optionsDate.data == NULL) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
        PORT_Memcpy(entry->optionsDate.data,
                    &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN +
                                   entry->subjectName.len +
                                   entry->smimeOptions.len],
                    entry->optionsDate.len);
    } else {
        entry->optionsDate.data = NULL;
    }

    /* both options and options date must either exist or not exist */
    if (((entry->optionsDate.len == 0) ||
         (entry->smimeOptions.len == 0)) &&
        entry->smimeOptions.len != entry->optionsDate.len) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    entry->emailAddr = (char *)PORT_ArenaAlloc(entry->common.arena,
                                               PORT_Strlen(emailAddr) + 1);
    if (entry->emailAddr) {
        PORT_Strcpy(entry->emailAddr, emailAddr);
    }

    return (SECSuccess);

loser:
    return (SECFailure);
}

/*
 * create a new SMIME entry
 */
static certDBEntrySMime *
NewDBSMimeEntry(char *emailAddr, SECItem *subjectName, SECItem *smimeOptions,
                SECItem *optionsDate, unsigned int flags)
{
    PLArenaPool *arena = NULL;
    certDBEntrySMime *entry;
    int addrlen;
    SECStatus rv;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena,
                                                sizeof(certDBEntrySMime));
    if (entry == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* init common fields */
    entry->common.arena = arena;
    entry->common.type = certDBEntryTypeSMimeProfile;
    entry->common.version = CERT_DB_FILE_VERSION;
    entry->common.flags = flags;

    /* copy the email addr */
    addrlen = PORT_Strlen(emailAddr) + 1;

    entry->emailAddr = (char *)PORT_ArenaAlloc(arena, addrlen);
    if (entry->emailAddr == NULL) {
        goto loser;
    }

    PORT_Memcpy(entry->emailAddr, emailAddr, addrlen);

    /* copy the subject name */
    rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* copy the smime options */
    if (smimeOptions) {
        rv = SECITEM_CopyItem(arena, &entry->smimeOptions, smimeOptions);
        if (rv != SECSuccess) {
            goto loser;
        }
    } else {
        PORT_Assert(optionsDate == NULL);
        entry->smimeOptions.data = NULL;
        entry->smimeOptions.len = 0;
    }

    /* copy the options date */
    if (optionsDate) {
        rv = SECITEM_CopyItem(arena, &entry->optionsDate, optionsDate);
        if (rv != SECSuccess) {
            goto loser;
        }
    } else {
        PORT_Assert(smimeOptions == NULL);
        entry->optionsDate.data = NULL;
        entry->optionsDate.len = 0;
    }

    return (entry);
loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (NULL);
}

/*
 * delete a SMIME entry
 */
static SECStatus
DeleteDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
{
    PLArenaPool *arena = NULL;
    SECStatus rv;
    SECItem dbkey;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }

    rv = EncodeDBSMimeKey(emailAddr, arena, &dbkey);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = DeleteDBEntry(handle, certDBEntryTypeSMimeProfile, &dbkey);
    if (rv == SECFailure) {
        goto loser;
    }

    PORT_FreeArena(arena, PR_FALSE);
    return (SECSuccess);

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (SECFailure);
}

/*
 * Read a SMIME entry
 */
certDBEntrySMime *
nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
{
    PLArenaPool *arena = NULL;
    PLArenaPool *tmparena = NULL;
    certDBEntrySMime *entry = NULL;
    SECItem dbkey;
    SECItem dbentry;
    SECStatus rv;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (tmparena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    entry = (certDBEntrySMime *)PORT_ArenaZAlloc(arena,
                                                 sizeof(certDBEntrySMime));
    if (entry == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    entry->common.arena = arena;
    entry->common.type = certDBEntryTypeSMimeProfile;

    rv = EncodeDBSMimeKey(emailAddr, tmparena, &dbkey);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
    if (rv == SECFailure) {
        goto loser;
    }

    /* is record long enough for header? */
    if (dbentry.len < DB_SMIME_ENTRY_HEADER_LEN) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    rv = DecodeDBSMimeEntry(entry, &dbentry, emailAddr);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_FreeArena(tmparena, PR_FALSE);
    return (entry);

loser:
    if (tmparena) {
        PORT_FreeArena(tmparena, PR_FALSE);
    }
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (NULL);
}

/*
 * Encode a SMIME entry into byte stream suitable for
 * the database
 */
static SECStatus
WriteDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, certDBEntrySMime *entry)
{
    SECItem dbitem, dbkey;
    PLArenaPool *tmparena = NULL;
    SECStatus rv;

    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (tmparena == NULL) {
        goto loser;
    }

    rv = EncodeDBSMimeEntry(entry, tmparena, &dbitem);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = EncodeDBSMimeKey(entry->emailAddr, tmparena, &dbkey);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* now write it to the database */
    rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_FreeArena(tmparena, PR_FALSE);
    return (SECSuccess);

loser:
    if (tmparena) {
        PORT_FreeArena(tmparena, PR_FALSE);
    }
    return (SECFailure);
}

/*
 * Encode a database subject record
 */
static SECStatus
EncodeDBSubjectEntry(certDBEntrySubject *entry, PLArenaPool *arena,
                     SECItem *dbitem)
{
    unsigned char *buf;
    int len;
    unsigned int ncerts;
    unsigned int i;
    unsigned char *tmpbuf;
    unsigned int nnlen = 0;
    unsigned int eaddrslen = 0;
    int keyidoff;
    SECItem *certKeys = entry->certKeys;
    SECItem *keyIDs = entry->keyIDs;
    ;

    if (entry->nickname) {
        nnlen = PORT_Strlen(entry->nickname) + 1;
    }
    if (entry->emailAddrs) {
        eaddrslen = 2;
        for (i = 0; i < entry->nemailAddrs; i++) {
            eaddrslen += PORT_Strlen(entry->emailAddrs[i]) + 1 + 2;
        }
    }

    ncerts = entry->ncerts;

    /* compute the length of the entry */
    keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen;
    len = keyidoff + (4 * ncerts) + eaddrslen;
    for (i = 0; i < ncerts; i++) {
        if (keyIDs[i].len > 0xffff ||
            (certKeys[i].len > 0xffff)) {
            PORT_SetError(SEC_ERROR_INPUT_LEN);
            goto loser;
        }
        len += certKeys[i].len;
        len += keyIDs[i].len;
    }

    /* allocate space for encoded database record, including space
     * for low level header
     */
    dbitem->len = len + SEC_DB_ENTRY_HEADER_LEN;

    dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
    if (dbitem->data == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* fill in database record */
    buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];

    buf[0] = (PRUint8)(ncerts >> 8);
    buf[1] = (PRUint8)(ncerts);
    buf[2] = (PRUint8)(nnlen >> 8);
    buf[3] = (PRUint8)(nnlen);
    /* v7 email field is NULL in v8 */
    buf[4] = 0;
    buf[5] = 0;

    PORT_Assert(DB_SUBJECT_ENTRY_HEADER_LEN == 6);

    if (entry->nickname) {
        PORT_Memcpy(&buf[DB_SUBJECT_ENTRY_HEADER_LEN], entry->nickname, nnlen);
    }
    tmpbuf = &buf[keyidoff];
    for (i = 0; i < ncerts; i++) {
        tmpbuf[0] = (PRUint8)(certKeys[i].len >> 8);
        tmpbuf[1] = (PRUint8)(certKeys[i].len);
        tmpbuf += 2;
    }
    for (i = 0; i < ncerts; i++) {
        tmpbuf[0] = (PRUint8)(keyIDs[i].len >> 8);
        tmpbuf[1] = (PRUint8)(keyIDs[i].len);
        tmpbuf += 2;
    }

    for (i = 0; i < ncerts; i++) {
        PORT_Memcpy(tmpbuf, certKeys[i].data, certKeys[i].len);
        tmpbuf += certKeys[i].len;
    }
    for (i = 0; i < ncerts; i++) {
        if (keyIDs[i].len) {
            PORT_Memcpy(tmpbuf, keyIDs[i].data, keyIDs[i].len);
            tmpbuf += keyIDs[i].len;
        }
    }

    if (entry->emailAddrs) {
        tmpbuf[0] = (PRUint8)(entry->nemailAddrs >> 8);
        tmpbuf[1] = (PRUint8)(entry->nemailAddrs);
        tmpbuf += 2;
        for (i = 0; i < entry->nemailAddrs; i++) {
            int nameLen = PORT_Strlen(entry->emailAddrs[i]) + 1;
            tmpbuf[0] = (PRUint8)(nameLen >> 8);
            tmpbuf[1] = (PRUint8)(nameLen);
            tmpbuf += 2;
            PORT_Memcpy(tmpbuf, entry->emailAddrs[i], nameLen);
            tmpbuf += nameLen;
        }
    }

    PORT_Assert(tmpbuf == &buf[len]);

    return (SECSuccess);

loser:
    return (SECFailure);
}

/*
 * Encode a database key for a subject record
 */
static SECStatus
EncodeDBSubjectKey(SECItem *derSubject, PLArenaPool *arena,
                   SECItem *dbkey)
{
    dbkey->len = derSubject->len + SEC_DB_KEY_HEADER_LEN;
    if (dbkey->len > NSS_MAX_LEGACY_DB_KEY_SIZE)
        goto loser;
    dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
    if (dbkey->data == NULL) {
        goto loser;
    }
    PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], derSubject->data,
                derSubject->len);
    dbkey->data[0] = certDBEntryTypeSubject;

    return (SECSuccess);

loser:
    return (SECFailure);
}

static SECStatus
DecodeDBSubjectEntry(certDBEntrySubject *entry, SECItem *dbentry,
                     const SECItem *derSubject)
{
    PLArenaPool *arena = entry->common.arena;
    unsigned char *tmpbuf;
    unsigned char *end;
    void *mark = PORT_ArenaMark(arena);
    unsigned int eaddrlen;
    unsigned int i;
    unsigned int keyidoff;
    unsigned int len;
    unsigned int ncerts = 0;
    unsigned int nnlen;
    SECStatus rv;

    rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* is record long enough for header? */
    if (dbentry->len < DB_SUBJECT_ENTRY_HEADER_LEN) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    entry->ncerts = ncerts = ((dbentry->data[0] << 8) | dbentry->data[1]);
    nnlen = ((dbentry->data[2] << 8) | dbentry->data[3]);
    eaddrlen = ((dbentry->data[4] << 8) | dbentry->data[5]);
    keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen;
    len = keyidoff + (4 * ncerts);
    if (dbentry->len < len) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    entry->certKeys = PORT_ArenaNewArray(arena, SECItem, ncerts);
    entry->keyIDs = PORT_ArenaNewArray(arena, SECItem, ncerts);
    if ((entry->certKeys == NULL) || (entry->keyIDs == NULL)) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    if (nnlen > 1) { /* null terminator is stored */
        entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
        if (entry->nickname == NULL) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
        PORT_Memcpy(entry->nickname,
                    &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN],
                    nnlen);
    } else {
        entry->nickname = NULL;
    }

    /* if we have an old style email entry, there is only one */
    entry->nemailAddrs = 0;
    if (eaddrlen > 1) { /* null terminator is stored */
        entry->emailAddrs = PORT_ArenaNewArray(arena, char *, 2);
        if (entry->emailAddrs == NULL) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
        entry->emailAddrs[0] = (char *)PORT_ArenaAlloc(arena, eaddrlen);
        if (entry->emailAddrs[0] == NULL) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
        PORT_Memcpy(entry->emailAddrs[0],
                    &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN + nnlen],
                    eaddrlen);
        entry->nemailAddrs = 1;
    } else {
        entry->emailAddrs = NULL;
    }

    /* collect the lengths of the certKeys and keyIDs, and total the
     * overall length.
     */
    tmpbuf = &dbentry->data[keyidoff];
    for (i = 0; i < ncerts; i++) {
        unsigned int itemlen = (tmpbuf[0] << 8) | tmpbuf[1];
        entry->certKeys[i].len = itemlen;
        len += itemlen;
        tmpbuf += 2;
    }
    for (i = 0; i < ncerts; i++) {
        unsigned int itemlen = (tmpbuf[0] << 8) | tmpbuf[1];
        entry->keyIDs[i].len = itemlen;
        len += itemlen;
        tmpbuf += 2;
    }

    /* is encoded entry large enough ? */
    if (len > dbentry->len) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        goto loser;
    }

    for (i = 0; i < ncerts; i++) {
        unsigned int kLen = entry->certKeys[i].len;
        entry->certKeys[i].data = (unsigned char *)PORT_ArenaAlloc(arena, kLen);
        if (entry->certKeys[i].data == NULL) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
        PORT_Memcpy(entry->certKeys[i].data, tmpbuf, kLen);
        tmpbuf += kLen;
    }
    for (i = 0; i < ncerts; i++) {
        unsigned int iLen = entry->keyIDs[i].len;
        entry->keyIDs[i].data = (unsigned char *)PORT_ArenaAlloc(arena, iLen);
        if (entry->keyIDs[i].data == NULL) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
        PORT_Memcpy(entry->keyIDs[i].data, tmpbuf, iLen);
        tmpbuf += iLen;
    }

    end = dbentry->data + dbentry->len;
    if ((eaddrlen == 0) && (end - tmpbuf > 1)) {
        /* read in the additional email addresses */
        entry->nemailAddrs = (((unsigned int)tmpbuf[0]) << 8) | tmpbuf[1];
        tmpbuf += 2;
        if (end - tmpbuf < 2 * (int)entry->nemailAddrs)
            goto loser;
        entry->emailAddrs = PORT_ArenaNewArray(arena, char *, entry->nemailAddrs);
        if (entry->emailAddrs == NULL) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
        for (i = 0; i < entry->nemailAddrs; i++) {
            int nameLen;
            if (end - tmpbuf < 2) {
                goto loser;
            }
            nameLen = (((int)tmpbuf[0]) << 8) | tmpbuf[1];
            tmpbuf += 2;
            if (end - tmpbuf < nameLen) {
                goto loser;
            }
            entry->emailAddrs[i] = PORT_ArenaAlloc(arena, nameLen);
            if (entry->emailAddrs == NULL) {
                PORT_SetError(SEC_ERROR_NO_MEMORY);
                goto loser;
            }
            PORT_Memcpy(entry->emailAddrs[i], tmpbuf, nameLen);
            tmpbuf += nameLen;
        }
        if (tmpbuf != end)
            goto loser;
    }
    PORT_ArenaUnmark(arena, mark);
    return (SECSuccess);

loser:
    PORT_ArenaRelease(arena, mark); /* discard above allocations */
    return (SECFailure);
}

/*
 * create a new subject entry with a single cert
 */
static certDBEntrySubject *
NewDBSubjectEntry(SECItem *derSubject, SECItem *certKey,
                  SECItem *keyID, char *nickname, char *emailAddr,
                  unsigned int flags)
{
    PLArenaPool *arena = NULL;
    certDBEntrySubject *entry;
    SECStatus rv;
    unsigned int nnlen;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena,
                                                  sizeof(certDBEntrySubject));
    if (entry == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* init common fields */
    entry->common.arena = arena;
    entry->common.type = certDBEntryTypeSubject;
    entry->common.version = CERT_DB_FILE_VERSION;
    entry->common.flags = flags;

    /* copy the subject */
    rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject);
    if (rv != SECSuccess) {
        goto loser;
    }

    entry->ncerts = 1;
    entry->nemailAddrs = 0;
    /* copy nickname */
    if (nickname && (*nickname != '\0')) {
        nnlen = PORT_Strlen(nickname) + 1;
        entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
        if (entry->nickname == NULL) {
            goto loser;
        }

        PORT_Memcpy(entry->nickname, nickname, nnlen);
    } else {
        entry->nickname = NULL;
    }

    /* copy email addr */
    if (emailAddr && (*emailAddr != '\0')) {
        emailAddr = nsslowcert_FixupEmailAddr(emailAddr);
        if (emailAddr == NULL) {
            entry->emailAddrs = NULL;
            goto loser;
        }

        entry->emailAddrs = (char **)PORT_ArenaAlloc(arena, sizeof(char *));
        if (entry->emailAddrs == NULL) {
            PORT_Free(emailAddr);
            goto loser;
        }
        entry->emailAddrs[0] = PORT_ArenaStrdup(arena, emailAddr);
        if (entry->emailAddrs[0]) {
            entry->nemailAddrs = 1;
        }

        PORT_Free(emailAddr);
    } else {
        entry->emailAddrs = NULL;
    }

    /* allocate space for certKeys and keyIDs */
    entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
    entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
    if ((entry->certKeys == NULL) || (entry->keyIDs == NULL)) {
        goto loser;
    }

    /* copy the certKey and keyID */
    rv = SECITEM_CopyItem(arena, &entry->certKeys[0], certKey);
    if (rv != SECSuccess) {
        goto loser;
    }
    rv = SECITEM_CopyItem(arena, &entry->keyIDs[0], keyID);
    if (rv != SECSuccess) {
        goto loser;
    }

    return (entry);
loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (NULL);
}

/*
 * delete a subject entry
 */
static SECStatus
DeleteDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject)
{
    SECItem dbkey;
    PLArenaPool *arena = NULL;
    SECStatus rv;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }

    rv = EncodeDBSubjectKey(derSubject, arena, &dbkey);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = DeleteDBEntry(handle, certDBEntryTypeSubject, &dbkey);
    if (rv == SECFailure) {
        goto loser;
    }

    PORT_FreeArena(arena, PR_FALSE);
    return (SECSuccess);

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (SECFailure);
}

/*
 * Read the subject entry
 */
static certDBEntrySubject *
ReadDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject)
{
    /* |arena| isn't function-bounded, so cannot be a PORTCheapArenaPool. */
    PLArenaPool *arena = NULL;
    PORTCheapArenaPool tmpArena;

    certDBEntrySubject *entry;
    SECItem dbkey;
    SECItem dbentry;
    SECStatus rv;

    PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena,
                                                  sizeof(certDBEntrySubject));
    if (entry == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    entry->common.arena = arena;
    entry->common.type = certDBEntryTypeSubject;

    rv = EncodeDBSubjectKey(derSubject, &tmpArena.arena, &dbkey);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, &tmpArena.arena);
    if (rv == SECFailure) {
        goto loser;
    }

    rv = DecodeDBSubjectEntry(entry, &dbentry, derSubject);
    if (rv == SECFailure) {
        goto loser;
    }

    PORT_DestroyCheapArena(&tmpArena);
    return (entry);

loser:
    PORT_DestroyCheapArena(&tmpArena);
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (NULL);
}

/*
 * Encode a subject name entry into byte stream suitable for
 * the database
 */
static SECStatus
WriteDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, certDBEntrySubject *entry)
{
    SECItem dbitem, dbkey;
    PLArenaPool *tmparena = NULL;
    SECStatus rv;

    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (tmparena == NULL) {
        goto loser;
    }

    rv = EncodeDBSubjectEntry(entry, tmparena, &dbitem);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = EncodeDBSubjectKey(&entry->derSubject, tmparena, &dbkey);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* now write it to the database */
    rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_FreeArena(tmparena, PR_FALSE);
    return (SECSuccess);

loser:
    if (tmparena) {
        PORT_FreeArena(tmparena, PR_FALSE);
    }
    return (SECFailure);
}

typedef enum { nsslowcert_remove,
               nsslowcert_add } nsslowcertUpdateType;

static SECStatus
nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
                                  SECItem *derSubject, char *emailAddr, nsslowcertUpdateType updateType)
{
    certDBEntrySubject *entry = NULL;
    int index = -1, i;
    SECStatus rv;

    if (emailAddr) {
        emailAddr = nsslowcert_FixupEmailAddr(emailAddr);
        if (emailAddr == NULL) {
            return SECFailure;
        }
    } else {
        return SECSuccess;
    }

    entry = ReadDBSubjectEntry(dbhandle, derSubject);
    if (entry == NULL) {
        rv = SECFailure;
        goto done;
    }

    for (i = 0; i < (int)(entry->nemailAddrs); i++) {
        if (PORT_Strcmp(entry->emailAddrs[i], emailAddr) == 0) {
            index = i;
        }
    }

    if (updateType == nsslowcert_remove) {
        if (index == -1) {
            rv = SECSuccess;
            goto done;
        }
        entry->nemailAddrs--;
        for (i = index; i < (int)(entry->nemailAddrs); i++) {
            entry->emailAddrs[i] = entry->emailAddrs[i + 1];
        }
    } else {
        char **newAddrs = NULL;

        if (index != -1) {
            rv = SECSuccess;
            goto done;
        }
        newAddrs = (char **)PORT_ArenaAlloc(entry->common.arena,
                                            (entry->nemailAddrs + 1) * sizeof(char *));
        if (!newAddrs) {
            rv = SECFailure;
            goto done;
        }
        for (i = 0; i < (int)(entry->nemailAddrs); i++) {
            newAddrs[i] = entry->emailAddrs[i];
        }
        newAddrs[entry->nemailAddrs] =
            PORT_ArenaStrdup(entry->common.arena, emailAddr);
        if (!newAddrs[entry->nemailAddrs]) {
            rv = SECFailure;
            goto done;
        }
        entry->emailAddrs = newAddrs;
        entry->nemailAddrs++;
    }

    /* delete the subject entry */
    DeleteDBSubjectEntry(dbhandle, derSubject);

    /* write the new one */
    rv = WriteDBSubjectEntry(dbhandle, entry);

done:
    if (entry)
        DestroyDBEntry((certDBEntry *)entry);
    if (emailAddr)
        PORT_Free(emailAddr);
    return rv;
}

/*
 * writes a nickname to an existing subject entry that does not currently
 * have one
 */
static SECStatus
AddNicknameToSubject(NSSLOWCERTCertDBHandle *dbhandle,
                     NSSLOWCERTCertificate *cert, char *nickname)
{
    certDBEntrySubject *entry;
    SECStatus rv;

    if (nickname == NULL) {
        return (SECFailure);
    }

    entry = ReadDBSubjectEntry(dbhandle, &cert->derSubject);
    PORT_Assert(entry != NULL);
    if (entry == NULL) {
        goto loser;
    }

    PORT_Assert(entry->nickname == NULL);
    if (entry->nickname != NULL) {
        goto loser;
    }

    entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname);

    if (entry->nickname == NULL) {
        goto loser;
    }

    /* delete the subject entry */
    DeleteDBSubjectEntry(dbhandle, &cert->derSubject);

    /* write the new one */
    rv = WriteDBSubjectEntry(dbhandle, entry);
    if (rv != SECSuccess) {
        goto loser;
    }

    DestroyDBEntry((certDBEntry *)entry);
    return (SECSuccess);

loser:
    DestroyDBEntry((certDBEntry *)entry);
    return (SECFailure);
}

/*
 * create a new version entry
 */
static certDBEntryVersion *
NewDBVersionEntry(unsigned int flags)
{
    PLArenaPool *arena = NULL;
    certDBEntryVersion *entry;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena,
                                                  sizeof(certDBEntryVersion));
    if (entry == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    entry->common.arena = arena;
    entry->common.type = certDBEntryTypeVersion;
    entry->common.version = CERT_DB_FILE_VERSION;
    entry->common.flags = flags;

    return (entry);
loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (NULL);
}

/*
 * Read the version entry
 */
static certDBEntryVersion *
ReadDBVersionEntry(NSSLOWCERTCertDBHandle *handle)
{
    PLArenaPool *arena = NULL;
    PLArenaPool *tmparena = NULL;
    certDBEntryVersion *entry;
    SECItem dbkey;
    SECItem dbentry;
    SECStatus rv;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (tmparena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    entry = PORT_ArenaZNew(arena, certDBEntryVersion);
    if (entry == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    entry->common.arena = arena;
    entry->common.type = certDBEntryTypeVersion;

    /* now get the database key and format it */
    dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;
    dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);
    if (dbkey.data == NULL) {
        goto loser;
    }
    PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY,
                SEC_DB_VERSION_KEY_LEN);

    rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_FreeArena(tmparena, PR_FALSE);
    return (entry);

loser:
    if (tmparena) {
        PORT_FreeArena(tmparena, PR_FALSE);
    }
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (NULL);
}

/*
 * Encode a version entry into byte stream suitable for
 * the database
 */
static SECStatus
WriteDBVersionEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryVersion *entry)
{
    SECItem dbitem, dbkey;
    PLArenaPool *tmparena = NULL;
    SECStatus rv;

    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (tmparena == NULL) {
        goto loser;
    }

    /* allocate space for encoded database record, including space
     * for low level header
     */
    dbitem.len = SEC_DB_ENTRY_HEADER_LEN;

    dbitem.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbitem.len);
    if (dbitem.data == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* now get the database key and format it */
    dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;
    dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);
    if (dbkey.data == NULL) {
        goto loser;
    }
    PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY,
                SEC_DB_VERSION_KEY_LEN);

    /* now write it to the database */
    rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_FreeArena(tmparena, PR_FALSE);
    return (SECSuccess);

loser:
    if (tmparena) {
        PORT_FreeArena(tmparena, PR_FALSE);
    }
    return (SECFailure);
}

/*
 * cert is no longer a perm cert, but will remain a temp cert
 */
static SECStatus
RemovePermSubjectNode(NSSLOWCERTCertificate *cert)
{
    certDBEntrySubject *entry;
    unsigned int i;
    SECStatus rv;

    entry = ReadDBSubjectEntry(cert->dbhandle, &cert->derSubject);
    if (entry == NULL) {
        return (SECFailure);
    }

    PORT_Assert(entry->ncerts);
    rv = SECFailure;

    if (entry->ncerts > 1) {
        for (i = 0; i < entry->ncerts; i++) {
            if (SECITEM_CompareItem(&entry->certKeys[i], &cert->certKey) ==
                SECEqual) {
                /* copy rest of list forward one entry */
                for (i = i + 1; i < entry->ncerts; i++) {
                    entry->certKeys[i - 1] = entry->certKeys[i];
                    entry->keyIDs[i - 1] = entry->keyIDs[i];
                }
                entry->ncerts--;
                DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
                rv = WriteDBSubjectEntry(cert->dbhandle, entry);
                break;
            }
        }
    } else {
        /* no entries left, delete the perm entry in the DB */
        if (entry->emailAddrs) {
            /* if the subject had an email record, then delete it too */
            for (i = 0; i < entry->nemailAddrs; i++) {
                DeleteDBSMimeEntry(cert->dbhandle, entry->emailAddrs[i]);
            }
        }
        if (entry->nickname) {
            DeleteDBNicknameEntry(cert->dbhandle, entry->nickname);
        }

        DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
    }
    DestroyDBEntry((certDBEntry *)entry);

    return (rv);
}

/*
 * add a cert to the perm subject list
 */
static SECStatus
AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
                   char *nickname)
{
    SECItem *newCertKeys, *newKeyIDs;
    unsigned int i, new_i;
    SECStatus rv;
    unsigned int ncerts;

    PORT_Assert(entry);
    ncerts = entry->ncerts;

    if (nickname && entry->nickname) {
        /* nicknames must be the same */
        PORT_Assert(PORT_Strcmp(nickname, entry->nickname) == 0);
    }

    if ((entry->nickname == NULL) && (nickname != NULL)) {
        /* copy nickname into the entry */
        entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname);
        if (entry->nickname == NULL) {
            return (SECFailure);
        }
    }

    /* a DB entry already exists, so add this cert */
    newCertKeys = PORT_ArenaZNewArray(entry->common.arena, SECItem, ncerts + 1);
    newKeyIDs = PORT_ArenaZNewArray(entry->common.arena, SECItem, ncerts + 1);

    if ((newCertKeys == NULL) || (newKeyIDs == NULL)) {
        return (SECFailure);
    }

    /* Step 1: copy certs older than "cert" into new entry. */
    for (i = 0, new_i = 0; i < ncerts; i++) {
        NSSLOWCERTCertificate *cmpcert;
        PRBool isNewer;
        cmpcert = nsslowcert_FindCertByKey(cert->dbhandle,
                                           &entry->certKeys[i]);
        /* The entry has been corrupted, remove it from the list */
        if (!cmpcert) {
            continue;
        }

        isNewer = nsslowcert_IsNewer(cert, cmpcert);
        nsslowcert_DestroyCertificate(cmpcert);
        if (isNewer)
            break;
        /* copy this cert entry */
        newCertKeys[new_i] = entry->certKeys[i];
        newKeyIDs[new_i] = entry->keyIDs[i];
        new_i++;
    }

    /* Step 2: Add "cert" to the entry. */
    rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i],
                          &cert->certKey);
    if (rv != SECSuccess) {
        return (SECFailure);
    }
    rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[new_i],
                          &cert->subjectKeyID);
    if (rv != SECSuccess) {
        return (SECFailure);
    }
    new_i++;

    /* Step 3: copy remaining certs (if any) from old entry to new. */
    for (; i < ncerts; i++, new_i++) {
        newCertKeys[new_i] = entry->certKeys[i];
        newKeyIDs[new_i] = entry->keyIDs[i];
    }

    /* update certKeys and keyIDs */
    entry->certKeys = newCertKeys;
    entry->keyIDs = newKeyIDs;

    /* set new count value */
    entry->ncerts = new_i;

    DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
    rv = WriteDBSubjectEntry(cert->dbhandle, entry);
    return (rv);
}

SECStatus
nsslowcert_TraversePermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
                                       SECItem *derSubject,
                                       NSSLOWCERTCertCallback cb, void *cbarg)
{
    certDBEntrySubject *entry;
    unsigned int i;
    NSSLOWCERTCertificate *cert;
    SECStatus rv = SECSuccess;

    entry = ReadDBSubjectEntry(handle, derSubject);

    if (entry == NULL) {
        return (SECFailure);
    }

    for (i = 0; i < entry->ncerts; i++) {
        cert = nsslowcert_FindCertByKey(handle, &entry->certKeys[i]);
        if (!cert) {
            continue;
        }
        rv = (*cb)(cert, cbarg);
        nsslowcert_DestroyCertificate(cert);
        if (rv == SECFailure) {
            break;
        }
    }

    DestroyDBEntry((certDBEntry *)entry);

    return (rv);
}

int
nsslowcert_NumPermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
                                  SECItem *derSubject)
{
    certDBEntrySubject *entry;
    int ret;

    entry = ReadDBSubjectEntry(handle, derSubject);

    if (entry == NULL) {
        return (SECFailure);
    }

    ret = entry->ncerts;

    DestroyDBEntry((certDBEntry *)entry);

    return (ret);
}

SECStatus
nsslowcert_TraversePermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
                                        char *nickname, NSSLOWCERTCertCallback cb, void *cbarg)
{
    certDBEntryNickname *nnentry = NULL;
    certDBEntrySMime *smentry = NULL;
    SECStatus rv;
    SECItem *derSubject = NULL;

    nnentry = ReadDBNicknameEntry(handle, nickname);
    if (nnentry) {
        derSubject = &nnentry->subjectName;
    } else {
        smentry = nsslowcert_ReadDBSMimeEntry(handle, nickname);
        if (smentry) {
            derSubject = &smentry->subjectName;
        }
    }

    if (derSubject) {
        rv = nsslowcert_TraversePermCertsForSubject(handle, derSubject,
                                                    cb, cbarg);
    } else {
        rv = SECFailure;
    }

    if (nnentry) {
        DestroyDBEntry((certDBEntry *)nnentry);
    }
    if (smentry) {
        DestroyDBEntry((certDBEntry *)smentry);
    }

    return (rv);
}

int
nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
                                   char *nickname)
{
    certDBEntryNickname *entry;
    int ret;

    entry = ReadDBNicknameEntry(handle, nickname);

    if (entry) {
        ret = nsslowcert_NumPermCertsForSubject(handle, &entry->subjectName);
        DestroyDBEntry((certDBEntry *)entry);
    } else {
        ret = 0;
    }
    return (ret);
}

/*
 * add a nickname to a cert that doesn't have one
 */
static SECStatus
AddNicknameToPermCert(NSSLOWCERTCertDBHandle *dbhandle,
                      NSSLOWCERTCertificate *cert, char *nickname)
{
    certDBEntryCert *entry;
    int rv;

    entry = cert->dbEntry;
    PORT_Assert(entry != NULL);
    if (entry == NULL) {
        goto loser;
    }

    pkcs11_freeNickname(entry->nickname, entry->nicknameSpace);
    entry->nickname = NULL;
    entry->nickname = pkcs11_copyNickname(nickname, entry->nicknameSpace,
                                          sizeof(entry->nicknameSpace));

    rv = WriteDBCertEntry(dbhandle, entry);
    if (rv) {
        goto loser;
    }

    pkcs11_freeNickname(cert->nickname, cert->nicknameSpace);
    cert->nickname = NULL;
    cert->nickname = pkcs11_copyNickname(nickname, cert->nicknameSpace,
                                         sizeof(cert->nicknameSpace));

    return (SECSuccess);

loser:
    return (SECFailure);
}

/*
 * add a nickname to a cert that is already in the perm database, but doesn't
 * have one yet (it is probably an e-mail cert).
 */
SECStatus
nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle,
                           NSSLOWCERTCertificate *cert, char *nickname)
{
    SECStatus rv = SECFailure;
    certDBEntrySubject *entry = NULL;
    certDBEntryNickname *nicknameEntry = NULL;

    nsslowcert_LockDB(dbhandle);

    entry = ReadDBSubjectEntry(dbhandle, &cert->derSubject);
    if (entry == NULL)
        goto loser;

    if (entry->nickname == NULL) {

        /* no nickname for subject */
        rv = AddNicknameToSubject(dbhandle, cert, nickname);
        if (rv != SECSuccess) {
            goto loser;
        }
        rv = AddNicknameToPermCert(dbhandle, cert, nickname);
        if (rv != SECSuccess) {
            goto loser;
        }
        nicknameEntry = NewDBNicknameEntry(nickname, &cert->derSubject, 0);
        if (nicknameEntry == NULL) {
            goto loser;
        }

        rv = WriteDBNicknameEntry(dbhandle, nicknameEntry);
        if (rv != SECSuccess) {
            goto loser;
        }
    } else {
        /* subject already has a nickname */
        rv = AddNicknameToPermCert(dbhandle, cert, entry->nickname);
        if (rv != SECSuccess) {
            goto loser;
        }
        /* make sure nickname entry exists. If the database was corrupted,
         * we may have lost the nickname entry. Add it back now  */
        nicknameEntry = ReadDBNicknameEntry(dbhandle, entry->nickname);
        if (nicknameEntry == NULL) {
            nicknameEntry = NewDBNicknameEntry(entry->nickname,
                                               &cert->derSubject, 0);
            if (nicknameEntry == NULL) {
                goto loser;
            }

            rv = WriteDBNicknameEntry(dbhandle, nicknameEntry);
            if (rv != SECSuccess) {
                goto loser;
            }
        }
    }
    rv = SECSuccess;

loser:
    if (entry) {
        DestroyDBEntry((certDBEntry *)entry);
    }
    if (nicknameEntry) {
        DestroyDBEntry((certDBEntry *)nicknameEntry);
    }
    nsslowcert_UnlockDB(dbhandle);
    return (rv);
}

static certDBEntryCert *
AddCertToPermDB(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTCertificate *cert,
                char *nickname, NSSLOWCERTCertTrust *trust)
{
    certDBEntryCert *certEntry = NULL;
    certDBEntryNickname *nicknameEntry = NULL;
    certDBEntrySubject *subjectEntry = NULL;
    int state = 0;
    SECStatus rv;
    PRBool donnentry = PR_FALSE;

    if (nickname) {
        donnentry = PR_TRUE;
    }

    subjectEntry = ReadDBSubjectEntry(handle, &cert->derSubject);

    if (subjectEntry && subjectEntry->nickname) {
        donnentry = PR_FALSE;
        nickname = subjectEntry->nickname;
    }

    certEntry = NewDBCertEntry(&cert->derCert, nickname, trust, 0);
    if (certEntry == NULL) {
        goto loser;
    }

    if (donnentry) {
        nicknameEntry = NewDBNicknameEntry(nickname, &cert->derSubject, 0);
        if (nicknameEntry == NULL) {
            goto loser;
        }
    }

    rv = WriteDBCertEntry(handle, certEntry);
    if (rv != SECSuccess) {
        goto loser;
    }
    state = 1;

    if (nicknameEntry) {
        rv = WriteDBNicknameEntry(handle, nicknameEntry);
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    state = 2;

    /* "Change" handles if necessary */
    cert->dbhandle = handle;

    /* add to or create new subject entry */
    if (subjectEntry) {
        /* REWRITE BASED ON SUBJECT ENTRY */
        rv = AddPermSubjectNode(subjectEntry, cert, nickname);
        if (rv != SECSuccess) {
            goto loser;
        }
    } else {
        /* make a new subject entry - this case is only used when updating
         * an old version of the database.  This is OK because the oldnickname
         * db format didn't allow multiple certs with the same subject.
         */
        /* where does subjectKeyID and certKey come from? */
        subjectEntry = NewDBSubjectEntry(&cert->derSubject, &cert->certKey,
                                         &cert->subjectKeyID, nickname,
                                         NULL, 0);
        if (subjectEntry == NULL) {
            goto loser;
        }
        rv = WriteDBSubjectEntry(handle, subjectEntry);
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    state = 3;

    if (nicknameEntry) {
        DestroyDBEntry((certDBEntry *)nicknameEntry);
    }

    if (subjectEntry) {
        DestroyDBEntry((certDBEntry *)subjectEntry);
    }

    return (certEntry);

loser:
    /* don't leave partial entry in the database */
    if (state > 0) {
        DeleteDBCertEntry(handle, &cert->certKey);
    }
    if ((state > 1) && donnentry) {
        DeleteDBNicknameEntry(handle, nickname);
    }
    if (certEntry) {
        DestroyDBEntry((certDBEntry *)certEntry);
    }
    if (nicknameEntry) {
        DestroyDBEntry((certDBEntry *)nicknameEntry);
    }
    if (subjectEntry) {
        DestroyDBEntry((certDBEntry *)subjectEntry);
    }

    return (NULL);
}

/* forward declaration */
static SECStatus
UpdateV7DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb);

/*
 * version 8 uses the same schema as version 7. The only differences are
 * 1) version 8 db uses the blob shim to store data entries > 32k.
 * 2) version 8 db sets the db block size to 32k.
 * both of these are dealt with by the handle.
 */

static SECStatus
UpdateV8DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
{
    return UpdateV7DB(handle, updatedb);
}

/*
 * we could just blindly sequence through reading key data pairs and writing
 * them back out, but some cert.db's have gotten quite large and may have some
 * subtle corruption problems, so instead we cycle through the certs and
 * CRL's and S/MIME profiles and rebuild our subject lists from those records.
 */
static SECStatus
UpdateV7DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
{
    DBT key, data;
    int ret;
    NSSLOWCERTCertificate *cert;
    PRBool isKRL = PR_FALSE;
    certDBEntryType entryType;
    SECItem dbEntry, dbKey;
    certDBEntryRevocation crlEntry;
    certDBEntryCert certEntry;
    certDBEntrySMime smimeEntry;
    SECStatus rv;

    ret = (*updatedb->seq)(updatedb, &key, &data, R_FIRST);

    if (ret) {
        return (SECFailure);
    }

    do {
        unsigned char *dataBuf = (unsigned char *)data.data;
        unsigned char *keyBuf = (unsigned char *)key.data;
        dbEntry.data = &dataBuf[SEC_DB_ENTRY_HEADER_LEN];
        dbEntry.len = data.size - SEC_DB_ENTRY_HEADER_LEN;
        entryType = (certDBEntryType)keyBuf[0];
        dbKey.data = &keyBuf[SEC_DB_KEY_HEADER_LEN];
        dbKey.len = key.size - SEC_DB_KEY_HEADER_LEN;
        if ((dbEntry.len <= 0) || (dbKey.len <= 0)) {
            continue;
        }

        switch (entryType) {
            /* these entries will get regenerated as we read the
             * rest of the data from the database */
            case certDBEntryTypeVersion:
            case certDBEntryTypeSubject:
            case certDBEntryTypeContentVersion:
            case certDBEntryTypeNickname:
            /* smime profiles need entries created after the certs have
             * been imported, loop over them in a second run */
            case certDBEntryTypeSMimeProfile:
                break;

            case certDBEntryTypeCert:
                /* decode Entry */
                certEntry.common.version = (unsigned int)dataBuf[0];
                certEntry.common.type = entryType;
                certEntry.common.flags = (unsigned int)dataBuf[2];
                rv = DecodeDBCertEntry(&certEntry, &dbEntry);
                if (rv != SECSuccess) {
                    break;
                }
                /* should we check for existing duplicates? */
                cert = nsslowcert_DecodeDERCertificate(&certEntry.derCert,
                                                       certEntry.nickname);
                if (cert) {
                    nsslowcert_UpdatePermCert(handle, cert, certEntry.nickname,
                                              &certEntry.trust);
                    nsslowcert_DestroyCertificate(cert);
                }
                /* free any data the decode may have allocated. */
                pkcs11_freeStaticData(certEntry.derCert.data,
                                      certEntry.derCertSpace);
                pkcs11_freeNickname(certEntry.nickname, certEntry.nicknameSpace);
                break;

            case certDBEntryTypeKeyRevocation:
                isKRL = PR_TRUE;
            /* fall through */
            case certDBEntryTypeRevocation:
                crlEntry.common.version = (unsigned int)dataBuf[0];
                crlEntry.common.type = entryType;
                crlEntry.common.flags = (unsigned int)dataBuf[2];
                crlEntry.common.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
                if (crlEntry.common.arena == NULL) {
                    break;
                }
                rv = DecodeDBCrlEntry(&crlEntry, &dbEntry);
                if (rv != SECSuccess) {
                    break;
                }
                nsslowcert_UpdateCrl(handle, &crlEntry.derCrl, &dbKey,
                                     crlEntry.url, isKRL);
                /* free data allocated by the decode */
                PORT_FreeArena(crlEntry.common.arena, PR_FALSE);
                crlEntry.common.arena = NULL;
                break;

            default:
                break;
        }
    } while ((*updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0);

    /* now loop again updating just the SMimeProfile. */
    ret = (*updatedb->seq)(updatedb, &key, &data, R_FIRST);

    if (ret) {
        return (SECFailure);
    }

    do {
        unsigned char *dataBuf = (unsigned char *)data.data;
        unsigned char *keyBuf = (unsigned char *)key.data;
        dbEntry.data = &dataBuf[SEC_DB_ENTRY_HEADER_LEN];
        dbEntry.len = data.size - SEC_DB_ENTRY_HEADER_LEN;
        entryType = (certDBEntryType)keyBuf[0];
        if (entryType != certDBEntryTypeSMimeProfile) {
            continue;
        }
        dbKey.data = &keyBuf[SEC_DB_KEY_HEADER_LEN];
        dbKey.len = key.size - SEC_DB_KEY_HEADER_LEN;
        if ((dbEntry.len <= 0) || (dbKey.len <= 0)) {
            continue;
        }
        smimeEntry.common.version = (unsigned int)dataBuf[0];
        smimeEntry.common.type = entryType;
        smimeEntry.common.flags = (unsigned int)dataBuf[2];
        smimeEntry.common.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        /* decode entry */
        rv = DecodeDBSMimeEntry(&smimeEntry, &dbEntry, (char *)dbKey.data);
        if (rv == SECSuccess) {
            nsslowcert_UpdateSMimeProfile(handle, smimeEntry.emailAddr,
                                          &smimeEntry.subjectName, &smimeEntry.smimeOptions,
                                          &smimeEntry.optionsDate);
        }
        PORT_FreeArena(smimeEntry.common.arena, PR_FALSE);
        smimeEntry.common.arena = NULL;
    } while ((*updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0);

    (*updatedb->close)(updatedb);

    /* a database update is a good time to go back and verify the integrity of
     * the keys and certs */
    handle->dbVerify = PR_TRUE;
    return (SECSuccess);
}

/*
 * NOTE - Version 6 DB did not go out to the real world in a release,
 * so we can remove this function in a later release.
 */
static SECStatus
UpdateV6DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
{
    int ret;
    DBT key, data;
    unsigned char *buf, *tmpbuf = NULL;
    certDBEntryType type;
    certDBEntryNickname *nnEntry = NULL;
    certDBEntrySubject *subjectEntry = NULL;
    certDBEntrySMime *emailEntry = NULL;
    char *nickname;
    char *emailAddr;

    /*
     * Sequence through the old database and copy all of the entries
     * to the new database.  Subject name entries will have the new
     * fields inserted into them (with zero length).
     */
    ret = (*updatedb->seq)(updatedb, &key, &data, R_FIRST);
    if (ret) {
        return (SECFailure);
    }

    do {
        buf = (unsigned char *)data.data;

        if (data.size >= 3) {
            if (buf[0] == 6) { /* version number */
                type = (certDBEntryType)buf[1];
                if (type == certDBEntryTypeSubject) {
                    /* expando subjecto entrieo */
                    tmpbuf = (unsigned char *)PORT_Alloc(data.size + 4);
                    if (tmpbuf) {
                        /* copy header stuff */
                        PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN + 2);
                        /* insert 4 more bytes of zero'd header */
                        PORT_Memset(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 2],
                                    0, 4);
                        /* copy rest of the data */
                        PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6],
                                    &buf[SEC_DB_ENTRY_HEADER_LEN + 2],
                                    data.size - (SEC_DB_ENTRY_HEADER_LEN + 2));

                        data.data = (void *)tmpbuf;
                        data.size += 4;
                        buf = tmpbuf;
                    }
                } else if (type == certDBEntryTypeCert) {
                    /* expando certo entrieo */
                    tmpbuf = (unsigned char *)PORT_Alloc(data.size + 3);
                    if (tmpbuf) {
                        /* copy header stuff */
                        PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN);

                        /* copy trust flage, setting msb's to 0 */
                        tmpbuf[SEC_DB_ENTRY_HEADER_LEN] = 0;
                        tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 1] =
                            buf[SEC_DB_ENTRY_HEADER_LEN];
                        tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 2] = 0;
                        tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 3] =
                            buf[SEC_DB_ENTRY_HEADER_LEN + 1];
                        tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 4] = 0;
                        tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 5] =
                            buf[SEC_DB_ENTRY_HEADER_LEN + 2];

                        /* copy rest of the data */
                        PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6],
                                    &buf[SEC_DB_ENTRY_HEADER_LEN + 3],
                                    data.size - (SEC_DB_ENTRY_HEADER_LEN + 3));

                        data.data = (void *)tmpbuf;
                        data.size += 3;
                        buf = tmpbuf;
                    }
                }

                /* update the record version number */
                buf[0] = CERT_DB_FILE_VERSION;

                /* copy to the new database */
                ret = certdb_Put(handle->permCertDB, &key, &data, 0);
                if (tmpbuf) {
                    PORT_Free(tmpbuf);
                    tmpbuf = NULL;
                }
                if (ret) {
                    return SECFailure;
                }
            }
        }
    } while ((*updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0);

    ret = certdb_Sync(handle->permCertDB, 0);
    if (ret) {
        return SECFailure;
    }

    ret = (*updatedb->seq)(updatedb, &key, &data, R_FIRST);
    if (ret) {
        return (SECFailure);
    }

    do {
        buf = (unsigned char *)data.data;

        if (data.size >= 3) {
            if (buf[0] == CERT_DB_FILE_VERSION) { /* version number */
                type = (certDBEntryType)buf[1];
                if (type == certDBEntryTypeNickname) {
                    nickname = &((char *)key.data)[1];

                    /* get the matching nickname entry in the new DB */
                    nnEntry = ReadDBNicknameEntry(handle, nickname);
                    if (nnEntry == NULL) {
                        goto endloop;
                    }

                    /* find the subject entry pointed to by nickname */
                    subjectEntry = ReadDBSubjectEntry(handle,
                                                      &nnEntry->subjectName);
                    if (subjectEntry == NULL) {
                        goto endloop;
                    }

                    subjectEntry->nickname =
                        (char *)PORT_ArenaAlloc(subjectEntry->common.arena,
                                                key.size - 1);
                    if (subjectEntry->nickname) {
                        PORT_Memcpy(subjectEntry->nickname, nickname,
                                    key.size - 1);
                        (void)WriteDBSubjectEntry(handle, subjectEntry);
                    }
                } else if (type == certDBEntryTypeSMimeProfile) {
                    emailAddr = &((char *)key.data)[1];

                    /* get the matching smime entry in the new DB */
                    emailEntry = nsslowcert_ReadDBSMimeEntry(handle, emailAddr);
                    if (emailEntry == NULL) {
                        goto endloop;
                    }

                    /* find the subject entry pointed to by nickname */
                    subjectEntry = ReadDBSubjectEntry(handle,
                                                      &emailEntry->subjectName);
                    if (subjectEntry == NULL) {
                        goto endloop;
                    }

                    subjectEntry->emailAddrs = (char **)
                        PORT_ArenaAlloc(subjectEntry->common.arena,
                                        sizeof(char *));
                    if (subjectEntry->emailAddrs) {
                        subjectEntry->emailAddrs[0] =
                            (char *)PORT_ArenaAlloc(subjectEntry->common.arena,
                                                    key.size - 1);
                        if (subjectEntry->emailAddrs[0]) {
                            PORT_Memcpy(subjectEntry->emailAddrs[0], emailAddr,
                                        key.size - 1);
                            subjectEntry->nemailAddrs = 1;
                            (void)WriteDBSubjectEntry(handle, subjectEntry);
                        }
                    }
                }

            endloop:
                if (subjectEntry) {
                    DestroyDBEntry((certDBEntry *)subjectEntry);
                    subjectEntry = NULL;
                }
                if (nnEntry) {
                    DestroyDBEntry((certDBEntry *)nnEntry);
                    nnEntry = NULL;
                }
                if (emailEntry) {
                    DestroyDBEntry((certDBEntry *)emailEntry);
                    emailEntry = NULL;
                }
            }
        }
    } while ((*updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0);

    ret = certdb_Sync(handle->permCertDB, 0);
    if (ret) {
        return SECFailure;
    }

    (*updatedb->close)(updatedb);
    return (SECSuccess);
}

static SECStatus
updateV5Callback(NSSLOWCERTCertificate *cert, SECItem *k, void *pdata)
{
    NSSLOWCERTCertDBHandle *handle;
    certDBEntryCert *entry;
    NSSLOWCERTCertTrust *trust;

    handle = (NSSLOWCERTCertDBHandle *)pdata;
    trust = &cert->dbEntry->trust;

    /* SSL user certs can be used for email if they have an email addr */
    if (cert->emailAddr && (trust->sslFlags & CERTDB_USER) &&
        (trust->emailFlags == 0)) {
        trust->emailFlags = CERTDB_USER;
    }
    /* servers didn't set the user flags on the server cert.. */
    if (PORT_Strcmp(cert->dbEntry->nickname, "Server-Cert") == 0) {
        trust->sslFlags |= CERTDB_USER;
    }

    entry = AddCertToPermDB(handle, cert, cert->dbEntry->nickname,
                            &cert->dbEntry->trust);
    if (entry) {
        DestroyDBEntry((certDBEntry *)entry);
    }

    return (SECSuccess);
}

static SECStatus
UpdateV5DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
{
    NSSLOWCERTCertDBHandle updatehandle;

    updatehandle.permCertDB = updatedb;
    updatehandle.dbMon = PZ_NewMonitor(nssILockCertDB);
    updatehandle.dbVerify = 0;
    updatehandle.ref = 1; /* prevent premature close */

    (void)nsslowcert_TraversePermCerts(&updatehandle, updateV5Callback,
                                       (void *)handle);

    PZ_DestroyMonitor(updatehandle.dbMon);

    (*updatedb->close)(updatedb);
    return (SECSuccess);
}

static PRBool
isV4DB(DB *db)
{
    DBT key, data;
    int ret;

    key.data = "Version";
    key.size = 7;

    ret = (*db->get)(db, &key, &data, 0);
    if (ret) {
        return PR_FALSE;
    }

    if ((data.size == 1) && (*(unsigned char *)data.data <= 4)) {
        return PR_TRUE;
    }

    return PR_FALSE;
}

static SECStatus
UpdateV4DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
{
    DBT key, data;
    certDBEntryCert *entry, *entry2;
    int ret;
    NSSLOWCERTCertificate *cert;

    ret = (*updatedb->seq)(updatedb, &key, &data, R_FIRST);

    if (ret) {
        return (SECFailure);
    }

    do {
        if (data.size != 1) { /* skip version number */

            /* decode the old DB entry */
            entry = (certDBEntryCert *)
                DecodeV4DBCertEntry((unsigned char *)data.data, data.size);

            if (entry) {
                cert = nsslowcert_DecodeDERCertificate(&entry->derCert,
                                                       entry->nickname);

                if (cert != NULL) {
                    /* add to new database */
                    entry2 = AddCertToPermDB(handle, cert, entry->nickname,
                                             &entry->trust);

                    nsslowcert_DestroyCertificate(cert);
                    if (entry2) {
                        DestroyDBEntry((certDBEntry *)entry2);
                    }
                }
                DestroyDBEntry((certDBEntry *)entry);
            }
        }
    } while ((*updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0);

    (*updatedb->close)(updatedb);
    return (SECSuccess);
}

/*
 * return true if a database key conflict exists
 */
PRBool
nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle)
{
    SECStatus rv;
    DBT tmpdata;
    DBT namekey;
    int ret;
    SECItem keyitem;
    PLArenaPool *arena = NULL;
    SECItem derKey;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }

    /* get the db key of the cert */
    rv = nsslowcert_KeyFromDERCert(arena, derCert, &derKey);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = EncodeDBCertKey(&derKey, arena, &keyitem);
    if (rv != SECSuccess) {
        goto loser;
    }

    namekey.data = keyitem.data;
    namekey.size = keyitem.len;

    ret = certdb_Get(handle->permCertDB, &namekey, &tmpdata, 0);
    if (ret == 0) {
        goto loser;
    }

    PORT_FreeArena(arena, PR_FALSE);

    return (PR_FALSE);
loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (PR_TRUE);
}

/*
 * return true if a nickname conflict exists
 * NOTE: caller must have already made sure that this exact cert
 * doesn't exist in the DB
 */
static PRBool
nsslowcert_CertNicknameConflict(char *nickname, SECItem *derSubject,
                                NSSLOWCERTCertDBHandle *handle)
{
    PRBool rv;
    certDBEntryNickname *entry;

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

    entry = ReadDBNicknameEntry(handle, nickname);

    if (entry == NULL) {
        /* no entry for this nickname, so no conflict */
        return (PR_FALSE);
    }

    rv = PR_TRUE;
    if (SECITEM_CompareItem(derSubject, &entry->subjectName) == SECEqual) {
        /* if subject names are the same, then no conflict */
        rv = PR_FALSE;
    }

    DestroyDBEntry((certDBEntry *)entry);
    return (rv);
}

#ifdef DBM_USING_NSPR
#define NO_RDONLY PR_RDONLY
#define NO_RDWR PR_RDWR
#define NO_CREATE (PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE)
#else
#define NO_RDONLY O_RDONLY
#define NO_RDWR O_RDWR
#define NO_CREATE (O_RDWR | O_CREAT | O_TRUNC)
#endif

/*
 * open an old database that needs to be updated
 */
static DB *
nsslowcert_openolddb(NSSLOWCERTDBNameFunc namecb, void *cbarg, int version)
{
    char *tmpname;
    DB *updatedb = NULL;

    tmpname = (*namecb)(cbarg, version); /* get v6 db name */
    if (tmpname) {
        updatedb = dbopen(tmpname, NO_RDONLY, 0600, DB_HASH, 0);
        PORT_Free(tmpname);
    }
    return updatedb;
}

static SECStatus
openNewCertDB(const char *appName, const char *prefix, const char *certdbname,
              NSSLOWCERTCertDBHandle *handle, NSSLOWCERTDBNameFunc namecb, void *cbarg)
{
    SECStatus rv;
    certDBEntryVersion *versionEntry = NULL;
    DB *updatedb = NULL;
    int status = RDB_FAIL;

    if (appName) {
        handle->permCertDB = rdbopen(appName, prefix, "cert", NO_CREATE, &status);
    } else {
        handle->permCertDB = dbsopen(certdbname, NO_CREATE, 0600, DB_HASH, 0);
    }

    /* if create fails then we lose */
    if (handle->permCertDB == 0) {
        return status == RDB_RETRY ? SECWouldBlock : SECFailure;
    }

    /* Verify version number; */
    versionEntry = NewDBVersionEntry(0);
    if (versionEntry == NULL) {
        rv = SECFailure;
        goto loser;
    }

    rv = WriteDBVersionEntry(handle, versionEntry);

    DestroyDBEntry((certDBEntry *)versionEntry);

    if (rv != SECSuccess) {
        goto loser;
    }

    /* rv must already be Success here because of previous if statement */
    /* try to upgrade old db here */
    if (appName &&
        (updatedb = dbsopen(certdbname, NO_RDONLY, 0600, DB_HASH, 0)) != NULL) {
        rv = UpdateV8DB(handle, updatedb);
    } else if ((updatedb = nsslowcert_openolddb(namecb, cbarg, 7)) != NULL) {
        rv = UpdateV7DB(handle, updatedb);
    } else if ((updatedb = nsslowcert_openolddb(namecb, cbarg, 6)) != NULL) {
        rv = UpdateV6DB(handle, updatedb);
    } else if ((updatedb = nsslowcert_openolddb(namecb, cbarg, 5)) != NULL) {
        rv = UpdateV5DB(handle, updatedb);
    } else if ((updatedb = nsslowcert_openolddb(namecb, cbarg, 4)) != NULL) {
        /* NES has v5 format db's with v4 db names! */
        if (isV4DB(updatedb)) {
            rv = UpdateV4DB(handle, updatedb);
        } else {
            rv = UpdateV5DB(handle, updatedb);
        }
    }

loser:
    db_InitComplete(handle->permCertDB);
    return rv;
}

static int
nsslowcert_GetVersionNumber(NSSLOWCERTCertDBHandle *handle)
{
    certDBEntryVersion *versionEntry = NULL;
    int version = 0;

    versionEntry = ReadDBVersionEntry(handle);
    if (versionEntry == NULL) {
        return 0;
    }
    version = versionEntry->common.version;
    DestroyDBEntry((certDBEntry *)versionEntry);
    return version;
}

/*
 * Open the certificate database and index databases.  Create them if
 * they are not there or bad.
 */
static SECStatus
nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
                          const char *appName, const char *prefix,
                          NSSLOWCERTDBNameFunc namecb, void *cbarg)
{
    SECStatus rv;
    int openflags;
    char *certdbname;
    int version = 0;

    certdbname = (*namecb)(cbarg, CERT_DB_FILE_VERSION);
    if (certdbname == NULL) {
        return (SECFailure);
    }

    openflags = readOnly ? NO_RDONLY : NO_RDWR;

    /*
     * first open the permanent file based database.
     */
    if (appName) {
        handle->permCertDB = rdbopen(appName, prefix, "cert", openflags, NULL);
    } else {
        handle->permCertDB = dbsopen(certdbname, openflags, 0600, DB_HASH, 0);
    }

    /* check for correct version number */
    if (handle->permCertDB) {
        version = nsslowcert_GetVersionNumber(handle);
        if ((version != CERT_DB_FILE_VERSION) &&
            !(appName && version == CERT_DB_V7_FILE_VERSION)) {
            goto loser;
        }
    } else if (readOnly) {
        /* don't create if readonly */
        /* Try openning a version 7 database */
        handle->permCertDB = nsslowcert_openolddb(namecb, cbarg, 7);
        if (!handle->permCertDB) {
            goto loser;
        }
        if (nsslowcert_GetVersionNumber(handle) != 7) {
            goto loser;
        }
    } else {
        /* if first open fails, try to create a new DB */
        rv = openNewCertDB(appName, prefix, certdbname, handle, namecb, cbarg);
        if (rv == SECWouldBlock) {
            /* only the rdb version can fail with wouldblock */
            handle->permCertDB =
                rdbopen(appName, prefix, "cert", openflags, NULL);

            /* check for correct version number */
            if (!handle->permCertDB) {
                goto loser;
            }
            version = nsslowcert_GetVersionNumber(handle);
            if ((version != CERT_DB_FILE_VERSION) &&
                !(appName && version == CERT_DB_V7_FILE_VERSION)) {
                goto loser;
            }
        } else if (rv != SECSuccess) {
            goto loser;
        }
    }

    PORT_Free(certdbname);

    return (SECSuccess);

loser:

    PORT_SetError(SEC_ERROR_BAD_DATABASE);

    if (handle->permCertDB) {
        certdb_Close(handle->permCertDB);
        handle->permCertDB = 0;
    }

    PORT_Free(certdbname);

    return (SECFailure);
}

/*
 * delete all DB records associated with a particular certificate
 */
static SECStatus
DeletePermCert(NSSLOWCERTCertificate *cert)
{
    SECStatus rv;
    SECStatus ret;

    ret = SECSuccess;

    rv = DeleteDBCertEntry(cert->dbhandle, &cert->certKey);
    if (rv != SECSuccess) {
        ret = SECFailure;
    }

    rv = RemovePermSubjectNode(cert);

    return (ret);
}

/*
 * Delete a certificate from the permanent database.
 */
SECStatus
nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert)
{
    SECStatus rv;

    nsslowcert_LockDB(cert->dbhandle);

    /* delete the records from the permanent database */
    rv = DeletePermCert(cert);

    /* get rid of dbcert and stuff pointing to it */
    DestroyDBEntry((certDBEntry *)cert->dbEntry);
    cert->dbEntry = NULL;
    cert->trust = NULL;

    nsslowcert_UnlockDB(cert->dbhandle);
    return (rv);
}

/*
 * Traverse all of the entries in the database of a particular type
 * call the given function for each one.
 */
SECStatus
nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle,
                             certDBEntryType type,
                             SECStatus (*callback)(SECItem *data, SECItem *key,
                                                   certDBEntryType type, void *pdata),
                             void *udata)
{
    DBT data;
    DBT key;
    SECStatus rv = SECSuccess;
    int ret;
    SECItem dataitem;
    SECItem keyitem;
    unsigned char *buf;
    unsigned char *keybuf;

    ret = certdb_Seq(handle->permCertDB, &key, &data, R_FIRST);
    if (ret) {
        return (SECFailure);
    }
    /* here, ret is zero and rv is SECSuccess.
     * Below here, ret is a count of successful calls to the callback function.
     */
    do {
        buf = (unsigned char *)data.data;

        if (buf[1] == (unsigned char)type) {
            dataitem.len = data.size;
            dataitem.data = buf;
            dataitem.type = siBuffer;
            keyitem.len = key.size - SEC_DB_KEY_HEADER_LEN;
            keybuf = (unsigned char *)key.data;
            keyitem.data = &keybuf[SEC_DB_KEY_HEADER_LEN];
            keyitem.type = siBuffer;
            /* type should equal keybuf[0].  */

            rv = (*callback)(&dataitem, &keyitem, type, udata);
            if (rv == SECSuccess) {
                ++ret;
            }
        }
    } while (certdb_Seq(handle->permCertDB, &key, &data, R_NEXT) == 0);
    /* If any callbacks succeeded, or no calls to callbacks were made,
     * then report success.  Otherwise, report failure.
     */
    return (ret ? SECSuccess : rv);
}
/*
 * Decode a certificate and enter it into the temporary certificate database.
 * Deal with nicknames correctly
 *
 * This is the private entry point.
 */
static NSSLOWCERTCertificate *
DecodeACert(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry)
{
    NSSLOWCERTCertificate *cert = NULL;

    cert = nsslowcert_DecodeDERCertificate(&entry->derCert, entry->nickname);

    if (cert == NULL) {
        goto loser;
    }

    cert->dbhandle = handle;
    cert->dbEntry = entry;
    cert->trust = &entry->trust;

    return (cert);

loser:
    return (0);
}

static NSSLOWCERTTrust *
CreateTrust(void)
{
    NSSLOWCERTTrust *trust = NULL;

    nsslowcert_LockFreeList();
    trust = trustListHead;
    if (trust) {
        trustListCount--;
        trustListHead = trust->next;
    }
    PORT_Assert(trustListCount >= 0);
    nsslowcert_UnlockFreeList();
    if (trust) {
        return trust;
    }

    return PORT_ZNew(NSSLOWCERTTrust);
}

static void
DestroyTrustFreeList(void)
{
    NSSLOWCERTTrust *trust;

    nsslowcert_LockFreeList();
    while (NULL != (trust = trustListHead)) {
        trustListCount--;
        trustListHead = trust->next;
        PORT_Free(trust);
    }
    PORT_Assert(!trustListCount);
    trustListCount = 0;
    nsslowcert_UnlockFreeList();
}

static NSSLOWCERTTrust *
DecodeTrustEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry,
                 const SECItem *dbKey)
{
    NSSLOWCERTTrust *trust = CreateTrust();
    if (trust == NULL) {
        return trust;
    }
    trust->dbhandle = handle;
    trust->dbEntry = entry;
    trust->dbKey.data = pkcs11_copyStaticData(dbKey->data, dbKey->len,
                                              trust->dbKeySpace, sizeof(trust->dbKeySpace));
    if (!trust->dbKey.data) {
        PORT_Free(trust);
        return NULL;
    }
    trust->dbKey.len = dbKey->len;

    trust->trust = &entry->trust;
    trust->derCert = &entry->derCert;

    return (trust);
}

typedef struct {
    PermCertCallback certfunc;
    NSSLOWCERTCertDBHandle *handle;
    void *data;
} PermCertCallbackState;

/*
 * traversal callback to decode certs and call callers callback
 */
static SECStatus
certcallback(SECItem *dbdata, SECItem *dbkey, certDBEntryType type, void *data)
{
    PermCertCallbackState *mystate;
    SECStatus rv;
    certDBEntryCert *entry;
    SECItem entryitem;
    NSSLOWCERTCertificate *cert;
    PLArenaPool *arena = NULL;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }

    entry = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
    if (!entry) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    mystate = (PermCertCallbackState *)data;
    entry->common.version = (unsigned int)dbdata->data[0];
    entry->common.type = (certDBEntryType)dbdata->data[1];
    entry->common.flags = (unsigned int)dbdata->data[2];
    entry->common.arena = arena;

    entryitem.len = dbdata->len - SEC_DB_ENTRY_HEADER_LEN;
    entryitem.data = &dbdata->data[SEC_DB_ENTRY_HEADER_LEN];

    rv = DecodeDBCertEntry(entry, &entryitem);
    if (rv != SECSuccess) {
        goto loser;
    }
    entry->derCert.type = siBuffer;

    /* note: Entry is 'inheritted'.  */
    cert = DecodeACert(mystate->handle, entry);

    rv = (*mystate->certfunc)(cert, dbkey, mystate->data);

    /* arena stored in entry destroyed by nsslowcert_DestroyCertificate */
    nsslowcert_DestroyCertificateNoLocking(cert);

    return (rv);

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return (SECFailure);
}

/*
 * Traverse all of the certificates in the permanent database and
 * call the given function for each one; expect the caller to have lock.
 */
static SECStatus
TraversePermCertsNoLocking(NSSLOWCERTCertDBHandle *handle,
                           SECStatus (*certfunc)(NSSLOWCERTCertificate *cert,
                                                 SECItem *k,
                                                 void *pdata),
                           void *udata)
{
    SECStatus rv;
    PermCertCallbackState mystate;

    mystate.certfunc = certfunc;
    mystate.handle = handle;
    mystate.data = udata;
    rv = nsslowcert_TraverseDBEntries(handle, certDBEntryTypeCert, certcallback,
                                      (void *)&mystate);

    return (rv);
}

/*
 * Traverse all of the certificates in the permanent database and
 * call the given function for each one.
 */
SECStatus
nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle,
                             SECStatus (*certfunc)(NSSLOWCERTCertificate *cert, SECItem *k,
                                                   void *pdata),
                             void *udata)
{
    SECStatus rv;

    nsslowcert_LockDB(handle);
    rv = TraversePermCertsNoLocking(handle, certfunc, udata);
    nsslowcert_UnlockDB(handle);

    return (rv);
}

/*
 * Close the database
 */
void
nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle)
{
    if (handle) {
        if (handle->permCertDB) {
            certdb_Close(handle->permCertDB);
            handle->permCertDB = NULL;
        }
        if (handle->dbMon) {
            PZ_DestroyMonitor(handle->dbMon);
            handle->dbMon = NULL;
        }
        PORT_Free(handle);
    }
    return;
}

/*
 * Get the trust attributes from a certificate
 */
SECStatus
nsslowcert_GetCertTrust(NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust)
{
    SECStatus rv;

    nsslowcert_LockCertTrust(cert);

    if (cert->trust == NULL) {
        rv = SECFailure;
    } else {
        *trust = *cert->trust;
        rv = SECSuccess;
    }

    nsslowcert_UnlockCertTrust(cert);
    return (rv);
}

/*
 * Change the trust attributes of a certificate and make them permanent
 * in the database.
 */
SECStatus
nsslowcert_ChangeCertTrust(NSSLOWCERTCertDBHandle *handle,
                           NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust)
{
    certDBEntryCert *entry;
    int rv;
    SECStatus ret;

    nsslowcert_LockDB(handle);
    nsslowcert_LockCertTrust(cert);
    /* only set the trust on permanent certs */
    if (cert->trust == NULL) {
        ret = SECFailure;
        goto done;
    }

    *cert->trust = *trust;
    if (cert->dbEntry == NULL) {
        ret = SECSuccess; /* not in permanent database */
        goto done;
    }

    entry = cert->dbEntry;
    entry->trust = *trust;

    rv = WriteDBCertEntry(handle, entry);
    if (rv) {
        ret = SECFailure;
        goto done;
    }

    ret = SECSuccess;

done:
    nsslowcert_UnlockCertTrust(cert);
    nsslowcert_UnlockDB(handle);
    return (ret);
}

static SECStatus
nsslowcert_UpdatePermCert(NSSLOWCERTCertDBHandle *dbhandle,
                          NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust)
{
    char *oldnn;
    certDBEntryCert *entry;
    PRBool conflict;
    SECStatus ret;

    PORT_Assert(!cert->dbEntry);

    /* don't add a conflicting nickname */
    conflict = nsslowcert_CertNicknameConflict(nickname, &cert->derSubject,
                                               dbhandle);
    if (conflict) {
        ret = SECFailure;
        goto done;
    }

    /* save old nickname so that we can delete it */
    oldnn = cert->nickname;

    entry = AddCertToPermDB(dbhandle, cert, nickname, trust);

    if (entry == NULL) {
        ret = SECFailure;
        goto done;
    }

    pkcs11_freeNickname(oldnn, cert->nicknameSpace);

    cert->nickname = (entry->nickname) ? pkcs11_copyNickname(entry->nickname,
                                                             cert->nicknameSpace, sizeof(cert->nicknameSpace))
                                       : NULL;
    cert->trust = &entry->trust;
    cert->dbEntry = entry;

    ret = SECSuccess;
done:
    return (ret);
}

SECStatus
nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *dbhandle,
                       NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust)
{
    SECStatus ret;

    nsslowcert_LockDB(dbhandle);

    ret = nsslowcert_UpdatePermCert(dbhandle, cert, nickname, trust);

    nsslowcert_UnlockDB(dbhandle);
    return (ret);
}

/*
 * Open the certificate database and index databases.  Create them if
 * they are not there or bad.
 */
SECStatus
nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
                      const char *appName, const char *prefix,
                      NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile)
{
    int rv;

    certdb_InitDBLock(handle);

    handle->dbMon = PZ_NewMonitor(nssILockCertDB);
    PORT_Assert(handle->dbMon != NULL);
    handle->dbVerify = PR_FALSE;

    rv = nsslowcert_OpenPermCertDB(handle, readOnly, appName, prefix,
                                   namecb, cbarg);
    if (rv) {
        goto loser;
    }

    return (SECSuccess);

loser:
    if (handle->dbMon) {
        PZ_DestroyMonitor(handle->dbMon);
        handle->dbMon = NULL;
    }
    PORT_SetError(SEC_ERROR_BAD_DATABASE);
    return (SECFailure);
}

PRBool
nsslowcert_needDBVerify(NSSLOWCERTCertDBHandle *handle)
{
    if (!handle)
        return PR_FALSE;
    return handle->dbVerify;
}

void
nsslowcert_setDBVerify(NSSLOWCERTCertDBHandle *handle, PRBool value)
{
    handle->dbVerify = value;
}

/*
 * Lookup a certificate in the databases.
 */
static NSSLOWCERTCertificate *
FindCertByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey, PRBool lockdb)
{
    NSSLOWCERTCertificate *cert = NULL;
    certDBEntryCert *entry;
    PRBool locked = PR_FALSE;

    if (lockdb) {
        locked = PR_TRUE;
        nsslowcert_LockDB(handle);
    }

    /* find in perm database */
    entry = ReadDBCertEntry(handle, certKey);

    if (entry == NULL) {
        goto loser;
    }

    /* inherit entry */
    cert = DecodeACert(handle, entry);

loser:
    if (cert == NULL) {
        if (entry) {
            DestroyDBEntry((certDBEntry *)entry);
        }
    }

    if (locked) {
        nsslowcert_UnlockDB(handle);
    }

    return (cert);
}

/*
 * Lookup a certificate in the databases.
 */
static NSSLOWCERTTrust *
FindTrustByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey, PRBool lockdb)
{
    NSSLOWCERTTrust *trust = NULL;
    certDBEntryCert *entry;
    PRBool locked = PR_FALSE;

    if (lockdb) {
        locked = PR_TRUE;
        nsslowcert_LockDB(handle);
    }

    /* find in perm database */
    entry = ReadDBCertEntry(handle, certKey);

    if (entry == NULL) {
        goto loser;
    }

    if (!nsslowcert_hasTrust(&entry->trust)) {
        goto loser;
    }

    /* inherit entry */
    trust = DecodeTrustEntry(handle, entry, certKey);

loser:
    if (trust == NULL) {
        if (entry) {
            DestroyDBEntry((certDBEntry *)entry);
        }
    }

    if (locked) {
        nsslowcert_UnlockDB(handle);
    }

    return (trust);
}

/*
 * Lookup a certificate in the databases without locking
 */
NSSLOWCERTCertificate *
nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey)
{
    return (FindCertByKey(handle, certKey, PR_FALSE));
}

/*
 * Lookup a trust object in the databases without locking
 */
NSSLOWCERTTrust *
nsslowcert_FindTrustByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey)
{
    return (FindTrustByKey(handle, certKey, PR_FALSE));
}

/*
 * Generate a key from an issuerAndSerialNumber, and find the
 * associated cert in the database.
 */
NSSLOWCERTCertificate *
nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN)
{
    SECItem certKey;
    SECItem *sn = &issuerAndSN->serialNumber;
    SECItem *issuer = &issuerAndSN->derIssuer;
    NSSLOWCERTCertificate *cert;
    int data_len = sn->len;
    int index = 0;

    /* automatically detect DER encoded serial numbers and remove the der
     * encoding since the database expects unencoded data.
     * if it's DER encoded, there must be at least 3 bytes, tag, len, data */
    if ((sn->len >= 3) && (sn->data[0] == 0x2)) {
        /* remove the der encoding of the serial number before generating the
         * key.. */
        int data_left = sn->len - 2;
        data_len = sn->data[1];
        index = 2;

        /* extended length ? (not very likely for a serial number) */
        if (data_len & 0x80) {
            int len_count = data_len & 0x7f;

            data_len = 0;
            data_left -= len_count;
            if (data_left > 0) {
                while (len_count--) {
                    data_len = (data_len << 8) | sn->data[index++];
                }
            }
        }
        /* XXX leaving any leading zeros on the serial number for backwards
         * compatibility
         */
        /* not a valid der, must be just an unlucky serial number value */
        if (data_len != data_left) {
            data_len = sn->len;
            index = 0;
        }
    }

    certKey.type = 0;
    certKey.data = (unsigned char *)PORT_Alloc(sn->len + issuer->len);
    certKey.len = data_len + issuer->len;

    if (certKey.data == NULL) {
        return (0);
    }

    /* first try the serial number as hand-decoded above*/
    /* copy the serialNumber */
    PORT_Memcpy(certKey.data, &sn->data[index], data_len);

    /* copy the issuer */
    PORT_Memcpy(&certKey.data[data_len], issuer->data, issuer->len);

    cert = nsslowcert_FindCertByKey(handle, &certKey);
    if (cert) {
        PORT_Free(certKey.data);
        return (cert);
    }

    /* didn't find it, try by der encoded serial number */
    /* copy the serialNumber */
    PORT_Memcpy(certKey.data, sn->data, sn->len);

    /* copy the issuer */
    PORT_Memcpy(&certKey.data[sn->len], issuer->data, issuer->len);
    certKey.len = sn->len + issuer->len;

    cert = nsslowcert_FindCertByKey(handle, &certKey);

    PORT_Free(certKey.data);

    return (cert);
}

/*
 * Generate a key from an issuerAndSerialNumber, and find the
 * associated cert in the database.
 */
NSSLOWCERTTrust *
nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle,
                                  NSSLOWCERTIssuerAndSN *issuerAndSN)
{
    SECItem certKey;
    SECItem *sn = &issuerAndSN->serialNumber;
    SECItem *issuer = &issuerAndSN->derIssuer;
    NSSLOWCERTTrust *trust;
    unsigned char keyBuf[512];
    int data_len = sn->len;
    int index = 0;
    int len;

    /* automatically detect DER encoded serial numbers and remove the der
     * encoding since the database expects unencoded data.
     * if it's DER encoded, there must be at least 3 bytes, tag, len, data */
    if ((sn->len >= 3) && (sn->data[0] == 0x2)) {
        /* remove the der encoding of the serial number before generating the
         * key.. */
        int data_left = sn->len - 2;
        data_len = sn->data[1];
        index = 2;

        /* extended length ? (not very likely for a serial number) */
        if (data_len & 0x80) {
            int len_count = data_len & 0x7f;

            data_len = 0;
            data_left -= len_count;
            if (data_left > 0) {
                while (len_count--) {
                    data_len = (data_len << 8) | sn->data[index++];
                }
            }
        }
        /* XXX leaving any leading zeros on the serial number for backwards
         * compatibility
         */
        /* not a valid der, must be just an unlucky serial number value */
        if (data_len != data_left) {
            data_len = sn->len;
            index = 0;
        }
    }

    certKey.type = 0;
    certKey.len = data_len + issuer->len;
    len = sn->len + issuer->len;
    if (len > sizeof(keyBuf)) {
        certKey.data = (unsigned char *)PORT_Alloc(len);
    } else {
        certKey.data = keyBuf;
    }

    if (certKey.data == NULL) {
        return (0);
    }

    /* first try the serial number as hand-decoded above*/
    /* copy the serialNumber */
    PORT_Memcpy(certKey.data, &sn->data[index], data_len);

    /* copy the issuer */
    PORT_Memcpy(&certKey.data[data_len], issuer->data, issuer->len);

    trust = nsslowcert_FindTrustByKey(handle, &certKey);
    if (trust) {
        pkcs11_freeStaticData(certKey.data, keyBuf);
        return (trust);
    }

    if (index == 0) {
        pkcs11_freeStaticData(certKey.data, keyBuf);
        return NULL;
    }

    /* didn't find it, try by der encoded serial number */
    /* copy the serialNumber */
    PORT_Memcpy(certKey.data, sn->data, sn->len);

    /* copy the issuer */
    PORT_Memcpy(&certKey.data[sn->len], issuer->data, issuer->len);
    certKey.len = sn->len + issuer->len;

    trust = nsslowcert_FindTrustByKey(handle, &certKey);

    pkcs11_freeStaticData(certKey.data, keyBuf);

    return (trust);
}

/*
 * look for the given DER certificate in the database
 */
NSSLOWCERTCertificate *
nsslowcert_FindCertByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCert)
{
    PLArenaPool *arena;
    SECItem certKey;
    SECStatus rv;
    NSSLOWCERTCertificate *cert = NULL;

    /* create a scratch arena */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        return (NULL);
    }

    /* extract the database key from the cert */
    rv = nsslowcert_KeyFromDERCert(arena, derCert, &certKey);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* find the certificate */
    cert = nsslowcert_FindCertByKey(handle, &certKey);

loser:
    PORT_FreeArena(arena, PR_FALSE);
    return (cert);
}

static void
DestroyCertificate(NSSLOWCERTCertificate *cert, PRBool lockdb)
{
    int refCount;
    NSSLOWCERTCertDBHandle *handle;

    if (cert) {

        handle = cert->dbhandle;

        /*
         * handle may be NULL, for example if the cert was created with
         * nsslowcert_DecodeDERCertificate.
         */
        if (lockdb && handle) {
            nsslowcert_LockDB(handle);
        }

        nsslowcert_LockCertRefCount(cert);
        PORT_Assert(cert->referenceCount > 0);
        refCount = --cert->referenceCount;
        nsslowcert_UnlockCertRefCount(cert);

        if (refCount == 0) {
            certDBEntryCert *entry = cert->dbEntry;

            if (entry) {
                DestroyDBEntry((certDBEntry *)entry);
            }

            pkcs11_freeNickname(cert->nickname, cert->nicknameSpace);
            pkcs11_freeNickname(cert->emailAddr, cert->emailAddrSpace);
            pkcs11_freeStaticData(cert->certKey.data, cert->certKeySpace);
            cert->certKey.data = NULL;
            cert->nickname = NULL;

            /* zero cert before freeing. Any stale references to this cert
             * after this point will probably cause an exception.  */
            PORT_Memset(cert, 0, sizeof *cert);

            /* use reflock to protect the free list */
            nsslowcert_LockFreeList();
            if (certListCount > MAX_CERT_LIST_COUNT) {
                PORT_Free(cert);
            } else {
                certListCount++;
                cert->next = certListHead;
                certListHead = cert;
            }
            nsslowcert_UnlockFreeList();
            cert = NULL;
        }
        if (lockdb && handle) {
            nsslowcert_UnlockDB(handle);
        }
    }

    return;
}

NSSLOWCERTCertificate *
nsslowcert_CreateCert(void)
{
    NSSLOWCERTCertificate *cert;
    nsslowcert_LockFreeList();
    cert = certListHead;
    if (cert) {
        certListHead = cert->next;
        certListCount--;
    }
    PORT_Assert(certListCount >= 0);
    nsslowcert_UnlockFreeList();
    if (cert) {
        return cert;
    }
    return PORT_ZNew(NSSLOWCERTCertificate);
}

static void
DestroyCertFreeList(void)
{
    NSSLOWCERTCertificate *cert;

    nsslowcert_LockFreeList();
    while (NULL != (cert = certListHead)) {
        certListCount--;
        certListHead = cert->next;
        PORT_Free(cert);
    }
    PORT_Assert(!certListCount);
    certListCount = 0;
    nsslowcert_UnlockFreeList();
}

void
nsslowcert_DestroyTrust(NSSLOWCERTTrust *trust)
{
    certDBEntryCert *entry = trust->dbEntry;

    if (entry) {
        DestroyDBEntry((certDBEntry *)entry);
    }
    pkcs11_freeStaticData(trust->dbKey.data, trust->dbKeySpace);
    PORT_Memset(trust, 0, sizeof(*trust));

    nsslowcert_LockFreeList();
    if (trustListCount > MAX_TRUST_LIST_COUNT) {
        PORT_Free(trust);
    } else {
        trustListCount++;
        trust->next = trustListHead;
        trustListHead = trust;
    }
    nsslowcert_UnlockFreeList();

    return;
}

void
nsslowcert_DestroyCertificate(NSSLOWCERTCertificate *cert)
{
    DestroyCertificate(cert, PR_TRUE);
    return;
}

static void
nsslowcert_DestroyCertificateNoLocking(NSSLOWCERTCertificate *cert)
{
    DestroyCertificate(cert, PR_FALSE);
    return;
}

/*
 * Lookup a CRL in the databases. We mirror the same fast caching data base
 *  caching stuff used by certificates....?
 */
certDBEntryRevocation *
nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle,
                        SECItem *crlKey, PRBool isKRL)
{
    SECItem keyitem;
    SECStatus rv;
    PLArenaPool *arena = NULL;
    certDBEntryRevocation *entry = NULL;
    certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
                                    : certDBEntryTypeRevocation;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }

    rv = EncodeDBGenericKey(crlKey, arena, &keyitem, crlType);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* find in perm database */
    entry = ReadDBCrlEntry(handle, crlKey, crlType);

    if (entry == NULL) {
        goto loser;
    }

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return entry;
}

/*
 * replace the existing URL in the data base with a new one
 */
static SECStatus
nsslowcert_UpdateCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
                     SECItem *crlKey, char *url, PRBool isKRL)
{
    SECStatus rv = SECFailure;
    certDBEntryRevocation *entry = NULL;
    certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
                                    : certDBEntryTypeRevocation;
    DeleteDBCrlEntry(handle, crlKey, crlType);

    /* Write the new entry into the data base */
    entry = NewDBCrlEntry(derCrl, url, crlType, 0);
    if (entry == NULL)
        goto done;

    rv = WriteDBCrlEntry(handle, entry, crlKey);
    if (rv != SECSuccess)
        goto done;

done:
    if (entry) {
        DestroyDBEntry((certDBEntry *)entry);
    }
    return rv;
}

SECStatus
nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
                  SECItem *crlKey, char *url, PRBool isKRL)
{
    SECStatus rv;

    rv = nsslowcert_UpdateCrl(handle, derCrl, crlKey, url, isKRL);

    return rv;
}

SECStatus
nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle, const SECItem *derName,
                         PRBool isKRL)
{
    SECStatus rv;
    certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
                                    : certDBEntryTypeRevocation;

    rv = DeleteDBCrlEntry(handle, derName, crlType);
    if (rv != SECSuccess)
        goto done;

done:
    return rv;
}

PRBool
nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust)
{
    if (trust == NULL) {
        return PR_FALSE;
    }
    return !((trust->sslFlags & CERTDB_TRUSTED_UNKNOWN) &&
             (trust->emailFlags & CERTDB_TRUSTED_UNKNOWN) &&
             (trust->objectSigningFlags & CERTDB_TRUSTED_UNKNOWN));
}

/*
 * This function has the logic that decides if another person's cert and
 * email profile from an S/MIME message should be saved.  It can deal with
 * the case when there is no profile.
 */
static SECStatus
nsslowcert_UpdateSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle,
                              char *emailAddr, SECItem *derSubject, SECItem *emailProfile,
                              SECItem *profileTime)
{
    certDBEntrySMime *entry = NULL;
    SECStatus rv = SECFailure;
    ;

    /* find our existing entry */
    entry = nsslowcert_ReadDBSMimeEntry(dbhandle, emailAddr);

    if (entry) {
        /* keep our old db entry consistant for old applications. */
        if (!SECITEM_ItemsAreEqual(derSubject, &entry->subjectName)) {
            nsslowcert_UpdateSubjectEmailAddr(dbhandle, &entry->subjectName,
                                              emailAddr, nsslowcert_remove);
        }
        DestroyDBEntry((certDBEntry *)entry);
        entry = NULL;
    }

    /* now save the entry */
    entry = NewDBSMimeEntry(emailAddr, derSubject, emailProfile,
                            profileTime, 0);
    if (entry == NULL) {
        rv = SECFailure;
        goto loser;
    }

    nsslowcert_LockDB(dbhandle);

    rv = DeleteDBSMimeEntry(dbhandle, emailAddr);
    /* if delete fails, try to write new entry anyway... */

    /* link subject entry back here */
    rv = nsslowcert_UpdateSubjectEmailAddr(dbhandle, derSubject, emailAddr,
                                           nsslowcert_add);
    if (rv != SECSuccess) {
        nsslowcert_UnlockDB(dbhandle);
        goto loser;
    }

    rv = WriteDBSMimeEntry(dbhandle, entry);
    if (rv != SECSuccess) {
        nsslowcert_UnlockDB(dbhandle);
        goto loser;
    }

    nsslowcert_UnlockDB(dbhandle);

    rv = SECSuccess;

loser:
    if (entry) {
        DestroyDBEntry((certDBEntry *)entry);
    }
    return (rv);
}

SECStatus
nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr,
                            SECItem *derSubject, SECItem *emailProfile, SECItem *profileTime)
{
    SECStatus rv = SECFailure;
    ;

    rv = nsslowcert_UpdateSMimeProfile(dbhandle, emailAddr,
                                       derSubject, emailProfile, profileTime);

    return (rv);
}

void
nsslowcert_DestroyFreeLists(void)
{
    if (freeListLock == NULL) {
        return;
    }
    DestroyCertEntryFreeList();
    DestroyTrustFreeList();
    DestroyCertFreeList();
    SKIP_AFTER_FORK(PZ_DestroyLock(freeListLock));
    freeListLock = NULL;
}

void
nsslowcert_DestroyGlobalLocks(void)
{
    if (dbLock) {
        SKIP_AFTER_FORK(PZ_DestroyLock(dbLock));
        dbLock = NULL;
    }
    if (certRefCountLock) {
        SKIP_AFTER_FORK(PZ_DestroyLock(certRefCountLock));
        certRefCountLock = NULL;
    }
    if (certTrustLock) {
        SKIP_AFTER_FORK(PZ_DestroyLock(certTrustLock));
        certTrustLock = NULL;
    }
}

certDBEntry *
nsslowcert_DecodeAnyDBEntry(SECItem *dbData, const SECItem *dbKey,
                            certDBEntryType entryType, void *pdata)
{
    PLArenaPool *arena = NULL;
    certDBEntry *entry;
    SECStatus rv;
    SECItem dbEntry;

    if ((dbData->len < SEC_DB_ENTRY_HEADER_LEN) || (dbKey->len == 0)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        goto loser;
    }
    dbEntry.data = &dbData->data[SEC_DB_ENTRY_HEADER_LEN];
    dbEntry.len = dbData->len - SEC_DB_ENTRY_HEADER_LEN;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        goto loser;
    }
    entry = PORT_ArenaZNew(arena, certDBEntry);
    if (!entry)
        goto loser;

    entry->common.version = (unsigned int)dbData->data[0];
    entry->common.flags = (unsigned int)dbData->data[2];
    entry->common.type = entryType;
    entry->common.arena = arena;

    switch (entryType) {
        case certDBEntryTypeContentVersion: /* This type appears to be unused */
        case certDBEntryTypeVersion:        /* This type has only the common hdr */
            rv = SECSuccess;
            break;

        case certDBEntryTypeSubject:
            rv = DecodeDBSubjectEntry(&entry->subject, &dbEntry, dbKey);
            break;

        case certDBEntryTypeNickname:
            rv = DecodeDBNicknameEntry(&entry->nickname, &dbEntry,
                                       (char *)dbKey->data);
            break;

        /* smime profiles need entries created after the certs have
         * been imported, loop over them in a second run */
        case certDBEntryTypeSMimeProfile:
            rv = DecodeDBSMimeEntry(&entry->smime, &dbEntry, (char *)dbKey->data);
            break;

        case certDBEntryTypeCert:
            rv = DecodeDBCertEntry(&entry->cert, &dbEntry);
            break;

        case certDBEntryTypeKeyRevocation:
        case certDBEntryTypeRevocation:
            rv = DecodeDBCrlEntry(&entry->revocation, &dbEntry);
            break;

        default:
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            rv = SECFailure;
    }

    if (rv == SECSuccess)
        return entry;

loser:
    if (arena)
        PORT_FreeArena(arena, PR_FALSE);
    return NULL;
}
