/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "lowkeyi.h"
#include "secasn1.h"
#include "secder.h"
#include "secoid.h"
#include "blapi.h"
#include "secitem.h"
#include "pcert.h"
#include "mcom_db.h"
#include "secerr.h"

#include "keydbi.h"
#include "lgdb.h"

/*
 * Record keys for keydb
 */
#define SALT_STRING "global-salt"
#define VERSION_STRING "Version"
#define KEYDB_PW_CHECK_STRING "password-check"
#define KEYDB_PW_CHECK_LEN 14
#define KEYDB_FAKE_PW_CHECK_STRING "fake-password-check"
#define KEYDB_FAKE_PW_CHECK_LEN 19

/* Size of the global salt for key database */
#define SALT_LENGTH 16

SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)

const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(NSSLOWKEYEncryptedPrivateKeyInfo) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(NSSLOWKEYEncryptedPrivateKeyInfo, algorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_OCTET_STRING,
      offsetof(NSSLOWKEYEncryptedPrivateKeyInfo, encryptedData) },
    { 0 }
};

const SEC_ASN1Template nsslowkey_PointerToEncryptedPrivateKeyInfoTemplate[] = {
    { SEC_ASN1_POINTER, 0, nsslowkey_EncryptedPrivateKeyInfoTemplate }
};

/* ====== Default key databse encryption algorithm ====== */
static void
sec_destroy_dbkey(NSSLOWKEYDBKey *dbkey)
{
    if (dbkey && dbkey->arena) {
        PORT_FreeArena(dbkey->arena, PR_FALSE);
    }
}

static void
free_dbt(DBT *dbt)
{
    if (dbt) {
        PORT_Free(dbt->data);
        PORT_Free(dbt);
    }

    return;
}

static int keydb_Get(NSSLOWKEYDBHandle *db, DBT *key, DBT *data,
                     unsigned int flags);
static int keydb_Put(NSSLOWKEYDBHandle *db, DBT *key, DBT *data,
                     unsigned int flags);
static int keydb_Sync(NSSLOWKEYDBHandle *db, unsigned int flags);
static int keydb_Del(NSSLOWKEYDBHandle *db, DBT *key, unsigned int flags);
static int keydb_Seq(NSSLOWKEYDBHandle *db, DBT *key, DBT *data,
                     unsigned int flags);
static void keydb_Close(NSSLOWKEYDBHandle *db);

/*
 * format of key database entries for version 3 of database:
 *  byte offset field
 *  ----------- -----
 *  0       version
 *  1       salt-len
 *  2       nn-len
 *  3..     salt-data
 *  ...     nickname
 *  ...     encrypted-key-data
 */
static DBT *
encode_dbkey(NSSLOWKEYDBKey *dbkey, unsigned char version)
{
    DBT *bufitem = NULL;
    unsigned char *buf;
    int nnlen;
    char *nn;

    bufitem = (DBT *)PORT_ZAlloc(sizeof(DBT));
    if (bufitem == NULL) {
        goto loser;
    }

    if (dbkey->nickname) {
        nn = dbkey->nickname;
        nnlen = PORT_Strlen(nn) + 1;
    } else {
        nn = "";
        nnlen = 1;
    }

    /* compute the length of the record */
    /* 1 + 1 + 1 == version number header + salt length + nn len */
    bufitem->size = dbkey->salt.len + nnlen + dbkey->derPK.len + 1 + 1 + 1;

    bufitem->data = (void *)PORT_ZAlloc(bufitem->size);
    if (bufitem->data == NULL) {
        goto loser;
    }

    buf = (unsigned char *)bufitem->data;

    /* set version number */
    buf[0] = version;

    /* set length of salt */
    PORT_Assert(dbkey->salt.len < 256);
    buf[1] = dbkey->salt.len;

    /* set length of nickname */
    PORT_Assert(nnlen < 256);
    buf[2] = nnlen;

    /* copy salt */
    if (dbkey->salt.len > 0) {
        PORT_Memcpy(&buf[3], dbkey->salt.data, dbkey->salt.len);
    }

    /* copy nickname */
    PORT_Memcpy(&buf[3 + dbkey->salt.len], nn, nnlen);

    /* copy encrypted key */
    PORT_Memcpy(&buf[3 + dbkey->salt.len + nnlen], dbkey->derPK.data,
                dbkey->derPK.len);

    return (bufitem);

loser:
    if (bufitem) {
        free_dbt(bufitem);
    }

    return (NULL);
}

static NSSLOWKEYDBKey *
decode_dbkey(DBT *bufitem, int expectedVersion)
{
    NSSLOWKEYDBKey *dbkey;
    PLArenaPool *arena = NULL;
    unsigned char *buf;
    int version;
    int keyoff;
    int nnlen;
    int saltoff;

    buf = (unsigned char *)bufitem->data;

    version = buf[0];

    if (version != expectedVersion) {
        goto loser;
    }

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

    dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey));
    if (dbkey == NULL) {
        goto loser;
    }

    dbkey->arena = arena;
    dbkey->salt.data = NULL;
    dbkey->derPK.data = NULL;

    dbkey->salt.len = buf[1];
    dbkey->salt.data = (unsigned char *)PORT_ArenaZAlloc(arena, dbkey->salt.len);
    if (dbkey->salt.data == NULL) {
        goto loser;
    }

    saltoff = 2;
    keyoff = 2 + dbkey->salt.len;

    if (expectedVersion >= 3) {
        nnlen = buf[2];
        if (nnlen) {
            dbkey->nickname = (char *)PORT_ArenaZAlloc(arena, nnlen + 1);
            if (dbkey->nickname) {
                PORT_Memcpy(dbkey->nickname, &buf[keyoff + 1], nnlen);
            }
        }
        keyoff += (nnlen + 1);
        saltoff = 3;
    }

    PORT_Memcpy(dbkey->salt.data, &buf[saltoff], dbkey->salt.len);

    dbkey->derPK.len = bufitem->size - keyoff;
    dbkey->derPK.data = (unsigned char *)PORT_ArenaZAlloc(arena, dbkey->derPK.len);
    if (dbkey->derPK.data == NULL) {
        goto loser;
    }

    PORT_Memcpy(dbkey->derPK.data, &buf[keyoff], dbkey->derPK.len);

    return (dbkey);

loser:

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

    return (NULL);
}

static NSSLOWKEYDBKey *
get_dbkey(NSSLOWKEYDBHandle *handle, DBT *index)
{
    NSSLOWKEYDBKey *dbkey;
    DBT entry;
    int ret;

    /* get it from the database */
    ret = keydb_Get(handle, index, &entry, 0);
    if (ret) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        return NULL;
    }

    /* set up dbkey struct */

    dbkey = decode_dbkey(&entry, handle->version);

    return (dbkey);
}

static SECStatus
put_dbkey(NSSLOWKEYDBHandle *handle, DBT *index, NSSLOWKEYDBKey *dbkey, PRBool update)
{
    DBT *keydata = NULL;
    int status;

    keydata = encode_dbkey(dbkey, handle->version);
    if (keydata == NULL) {
        goto loser;
    }

    /* put it in the database */
    if (update) {
        status = keydb_Put(handle, index, keydata, 0);
    } else {
        status = keydb_Put(handle, index, keydata, R_NOOVERWRITE);
    }

    if (status) {
        goto loser;
    }

    /* sync the database */
    status = keydb_Sync(handle, 0);
    if (status) {
        goto loser;
    }

    free_dbt(keydata);
    return (SECSuccess);

loser:
    if (keydata) {
        free_dbt(keydata);
    }

    return (SECFailure);
}

SECStatus
nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
                       SECStatus (*keyfunc)(DBT *k, DBT *d, void *pdata),
                       void *udata)
{
    DBT data;
    DBT key;
    SECStatus status;
    int ret;

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

    ret = keydb_Seq(handle, &key, &data, R_FIRST);
    if (ret) {
        return (SECFailure);
    }

    do {
        /* skip version record */
        if (data.size > 1) {
            if (key.size == (sizeof(SALT_STRING) - 1)) {
                if (PORT_Memcmp(key.data, SALT_STRING, key.size) == 0) {
                    continue;
                }
            }

            /* skip password check */
            if (key.size == KEYDB_PW_CHECK_LEN) {
                if (PORT_Memcmp(key.data, KEYDB_PW_CHECK_STRING,
                                KEYDB_PW_CHECK_LEN) == 0) {
                    continue;
                }
            }

            status = (*keyfunc)(&key, &data, udata);
            if (status != SECSuccess) {
                return (status);
            }
        }
    } while (keydb_Seq(handle, &key, &data, R_NEXT) == 0);

    return (SECSuccess);
}

#ifdef notdef
typedef struct keyNode {
    struct keyNode *next;
    DBT key;
} keyNode;

typedef struct {
    PLArenaPool *arena;
    keyNode *head;
} keyList;

static SECStatus
sec_add_key_to_list(DBT *key, DBT *data, void *arg)
{
    keyList *keylist;
    keyNode *node;
    void *keydata;

    keylist = (keyList *)arg;

    /* allocate the node struct */
    node = (keyNode *)PORT_ArenaZAlloc(keylist->arena, sizeof(keyNode));
    if (node == NULL) {
        return (SECFailure);
    }

    /* allocate room for key data */
    keydata = PORT_ArenaZAlloc(keylist->arena, key->size);
    if (keydata == NULL) {
        return (SECFailure);
    }

    /* link node into list */
    node->next = keylist->head;
    keylist->head = node;

    /* copy key into node */
    PORT_Memcpy(keydata, key->data, key->size);
    node->key.size = key->size;
    node->key.data = keydata;

    return (SECSuccess);
}
#endif

static SECItem *
decodeKeyDBGlobalSalt(DBT *saltData)
{
    SECItem *saltitem;

    saltitem = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
    if (saltitem == NULL) {
        return (NULL);
    }

    saltitem->data = (unsigned char *)PORT_ZAlloc(saltData->size);
    if (saltitem->data == NULL) {
        PORT_Free(saltitem);
        return (NULL);
    }

    saltitem->len = saltData->size;
    PORT_Memcpy(saltitem->data, saltData->data, saltitem->len);

    return (saltitem);
}

static SECItem *
GetKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle)
{
    DBT saltKey;
    DBT saltData;
    int ret;

    saltKey.data = SALT_STRING;
    saltKey.size = sizeof(SALT_STRING) - 1;

    ret = keydb_Get(handle, &saltKey, &saltData, 0);
    if (ret) {
        return (NULL);
    }

    return (decodeKeyDBGlobalSalt(&saltData));
}

static SECStatus
StoreKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle, SECItem *salt)
{
    DBT saltKey;
    DBT saltData;
    int status;

    saltKey.data = SALT_STRING;
    saltKey.size = sizeof(SALT_STRING) - 1;

    saltData.data = (void *)salt->data;
    saltData.size = salt->len;

    /* put global salt into the database now */
    status = keydb_Put(handle, &saltKey, &saltData, 0);
    if (status) {
        return (SECFailure);
    }

    return (SECSuccess);
}

static SECStatus
makeGlobalVersion(NSSLOWKEYDBHandle *handle)
{
    unsigned char version;
    DBT versionData;
    DBT versionKey;
    int status;

    version = NSSLOWKEY_DB_FILE_VERSION;
    versionData.data = &version;
    versionData.size = 1;
    versionKey.data = VERSION_STRING;
    versionKey.size = sizeof(VERSION_STRING) - 1;

    /* put version string into the database now */
    status = keydb_Put(handle, &versionKey, &versionData, 0);
    if (status) {
        return (SECFailure);
    }
    handle->version = version;

    return (SECSuccess);
}

static SECStatus
makeGlobalSalt(NSSLOWKEYDBHandle *handle)
{
    DBT saltKey;
    DBT saltData;
    unsigned char saltbuf[16];
    int status;

    saltKey.data = SALT_STRING;
    saltKey.size = sizeof(SALT_STRING) - 1;

    saltData.data = (void *)saltbuf;
    saltData.size = sizeof(saltbuf);
    RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf));

    /* put global salt into the database now */
    status = keydb_Put(handle, &saltKey, &saltData, 0);
    if (status) {
        return (SECFailure);
    }

    return (SECSuccess);
}

static SECStatus
encodePWCheckEntry(PLArenaPool *arena, SECItem *entry, SECOidTag alg,
                   SECItem *encCheck);

static unsigned char
nsslowkey_version(NSSLOWKEYDBHandle *handle)
{
    DBT versionKey;
    DBT versionData;
    int ret;
    versionKey.data = VERSION_STRING;
    versionKey.size = sizeof(VERSION_STRING) - 1;

    if (handle->db == NULL) {
        return 255;
    }

    /* lookup version string in database */
    ret = keydb_Get(handle, &versionKey, &versionData, 0);

    /* error accessing the database */
    if (ret < 0) {
        return 255;
    }

    if (ret >= 1) {
        return 0;
    }
    return *((unsigned char *)versionData.data);
}

static PRBool
seckey_HasAServerKey(NSSLOWKEYDBHandle *handle)
{
    DBT key;
    DBT data;
    int ret;
    PRBool found = PR_FALSE;

    ret = keydb_Seq(handle, &key, &data, R_FIRST);
    if (ret) {
        return PR_FALSE;
    }

    do {
        /* skip version record */
        if (data.size > 1) {
            /* skip salt */
            if (key.size == (sizeof(SALT_STRING) - 1)) {
                if (PORT_Memcmp(key.data, SALT_STRING, key.size) == 0) {
                    continue;
                }
            }
            /* skip pw check entry */
            if (key.size == KEYDB_PW_CHECK_LEN) {
                if (PORT_Memcmp(key.data, KEYDB_PW_CHECK_STRING,
                                KEYDB_PW_CHECK_LEN) == 0) {
                    continue;
                }
            }

            /* keys stored by nickname will have 0 as the last byte of the
             * db key.  Other keys must be stored by modulus.  We will not
             * update those because they are left over from a keygen that
             * never resulted in a cert.
             */
            if (((unsigned char *)key.data)[key.size - 1] != 0) {
                continue;
            }

            if (PORT_Strcmp(key.data, "Server-Key") == 0) {
                found = PR_TRUE;
                break;
            }
        }
    } while (keydb_Seq(handle, &key, &data, R_NEXT) == 0);

    return found;
}

/* forward declare local create function */
static NSSLOWKEYDBHandle *nsslowkey_NewHandle(DB *dbHandle);

/*
 * currently updates key database from v2 to v3
 */
static SECStatus
nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
{
    SECStatus rv;
    DBT checkKey;
    DBT checkData;
    DBT saltKey;
    DBT saltData;
    DBT key;
    DBT data;
    unsigned char version;
    NSSLOWKEYDBKey *dbkey = NULL;
    NSSLOWKEYDBHandle *update = NULL;
    SECItem *oldSalt = NULL;
    int ret;
    SECItem checkitem;

    if (handle->updatedb == NULL) {
        return SECSuccess;
    }

    /* create a full DB Handle for our update so we
     * can use the correct locks for the db primatives */
    update = nsslowkey_NewHandle(handle->updatedb);
    if (update == NULL) {
        return SECSuccess;
    }

    /* update has now inherited the database handle */
    handle->updatedb = NULL;

    /*
     * check the version record
     */
    version = nsslowkey_version(update);
    if (version != 2) {
        goto done;
    }

    saltKey.data = SALT_STRING;
    saltKey.size = sizeof(SALT_STRING) - 1;

    ret = keydb_Get(update, &saltKey, &saltData, 0);
    if (ret) {
        /* no salt in old db, so it is corrupted */
        goto done;
    }

    oldSalt = decodeKeyDBGlobalSalt(&saltData);
    if (oldSalt == NULL) {
        /* bad salt in old db, so it is corrupted */
        goto done;
    }

    /*
     * look for a pw check entry
     */
    checkKey.data = KEYDB_PW_CHECK_STRING;
    checkKey.size = KEYDB_PW_CHECK_LEN;

    ret = keydb_Get(update, &checkKey, &checkData, 0);
    if (ret) {
        /*
     * if we have a key, but no KEYDB_PW_CHECK_STRING, then this must
     * be an old server database, and it does have a password associated
     * with it. Put a fake entry in so we can identify this db when we do
     * get the password for it.
     */
        if (seckey_HasAServerKey(update)) {
            DBT fcheckKey;
            DBT fcheckData;

            /*
         * include a fake string
         */
            fcheckKey.data = KEYDB_FAKE_PW_CHECK_STRING;
            fcheckKey.size = KEYDB_FAKE_PW_CHECK_LEN;
            fcheckData.data = "1";
            fcheckData.size = 1;
            /* put global salt into the new database now */
            ret = keydb_Put(handle, &saltKey, &saltData, 0);
            if (ret) {
                goto done;
            }
            ret = keydb_Put(handle, &fcheckKey, &fcheckData, 0);
            if (ret) {
                goto done;
            }
        } else {
            goto done;
        }
    } else {
        /* put global salt into the new database now */
        ret = keydb_Put(handle, &saltKey, &saltData, 0);
        if (ret) {
            goto done;
        }

        dbkey = decode_dbkey(&checkData, 2);
        if (dbkey == NULL) {
            goto done;
        }
        checkitem = dbkey->derPK;
        dbkey->derPK.data = NULL;

        /* format the new pw check entry */
        rv = encodePWCheckEntry(NULL, &dbkey->derPK, SEC_OID_RC4, &checkitem);
        if (rv != SECSuccess) {
            goto done;
        }

        rv = put_dbkey(handle, &checkKey, dbkey, PR_TRUE);
        if (rv != SECSuccess) {
            goto done;
        }

        /* free the dbkey */
        sec_destroy_dbkey(dbkey);
        dbkey = NULL;
    }

    /* now traverse the database */
    ret = keydb_Seq(update, &key, &data, R_FIRST);
    if (ret) {
        goto done;
    }

    do {
        /* skip version record */
        if (data.size > 1) {
            /* skip salt */
            if (key.size == (sizeof(SALT_STRING) - 1)) {
                if (PORT_Memcmp(key.data, SALT_STRING, key.size) == 0) {
                    continue;
                }
            }
            /* skip pw check entry */
            if (key.size == checkKey.size) {
                if (PORT_Memcmp(key.data, checkKey.data, key.size) == 0) {
                    continue;
                }
            }

            /* keys stored by nickname will have 0 as the last byte of the
             * db key.  Other keys must be stored by modulus.  We will not
             * update those because they are left over from a keygen that
             * never resulted in a cert.
             */
            if (((unsigned char *)key.data)[key.size - 1] != 0) {
                continue;
            }

            dbkey = decode_dbkey(&data, 2);
            if (dbkey == NULL) {
                continue;
            }

            /* This puts the key into the new database with the same
             * index (nickname) that it had before.  The second pass
             * of the update will have the password.  It will decrypt
             * and re-encrypt the entries using a new algorithm.
             */
            dbkey->nickname = (char *)key.data;
            rv = put_dbkey(handle, &key, dbkey, PR_FALSE);
            dbkey->nickname = NULL;

            sec_destroy_dbkey(dbkey);
        }
    } while (keydb_Seq(update, &key, &data, R_NEXT) == 0);

    dbkey = NULL;

done:
    /* sync the database */
    ret = keydb_Sync(handle, 0);

    nsslowkey_CloseKeyDB(update);

    if (oldSalt) {
        SECITEM_FreeItem(oldSalt, PR_TRUE);
    }

    if (dbkey) {
        sec_destroy_dbkey(dbkey);
    }

    return (SECSuccess);
}

static SECStatus
openNewDB(const char *appName, const char *prefix, const char *dbname,
          NSSLOWKEYDBHandle *handle, NSSLOWKEYDBNameFunc namecb, void *cbarg)
{
    SECStatus rv = SECFailure;
    int status = RDB_FAIL;
    char *updname = NULL;
    DB *updatedb = NULL;
    PRBool updated = PR_FALSE;
    int ret;

    if (appName) {
        handle->db = rdbopen(appName, prefix, "key", NO_CREATE, &status);
    } else {
        handle->db = dbopen(dbname, NO_CREATE, 0600, DB_HASH, 0);
    }
    /* if create fails then we lose */
    if (handle->db == NULL) {
        return (status == RDB_RETRY) ? SECWouldBlock : SECFailure;
    }

    /* force a transactional read, which will verify that one and only one
     * process attempts the update. */
    if (nsslowkey_version(handle) == NSSLOWKEY_DB_FILE_VERSION) {
        /* someone else has already updated the database for us */
        db_InitComplete(handle->db);
        return SECSuccess;
    }

    /*
     * if we are creating a multiaccess database, see if there is a
     * local database we can update from.
     */
    if (appName) {
        NSSLOWKEYDBHandle *updateHandle;
        updatedb = dbopen(dbname, NO_RDONLY, 0600, DB_HASH, 0);
        if (!updatedb) {
            goto noupdate;
        }

        /* nsslowkey_version needs a full handle because it calls
         * the kdb_Get() function, which needs to lock.
         */
        updateHandle = nsslowkey_NewHandle(updatedb);
        if (!updateHandle) {
            updatedb->close(updatedb);
            goto noupdate;
        }

        handle->version = nsslowkey_version(updateHandle);
        if (handle->version != NSSLOWKEY_DB_FILE_VERSION) {
            nsslowkey_CloseKeyDB(updateHandle);
            goto noupdate;
        }

        /* copy the new DB from the old one */
        db_Copy(handle->db, updatedb);
        nsslowkey_CloseKeyDB(updateHandle);
        db_InitComplete(handle->db);
        return SECSuccess;
    }
noupdate:

    /* update the version number */
    rv = makeGlobalVersion(handle);
    if (rv != SECSuccess) {
        goto loser;
    }

    /*
     * try to update from v2 db
     */
    updname = (*namecb)(cbarg, 2);
    if (updname != NULL) {
        handle->updatedb = dbopen(updname, NO_RDONLY, 0600, DB_HASH, 0);
        PORT_Free(updname);

        if (handle->updatedb) {
            /*
             * Try to update the db using a null password.  If the db
             * doesn't have a password, then this will work.  If it does
             * have a password, then this will fail and we will do the
             * update later
             */
            rv = nsslowkey_UpdateKeyDBPass1(handle);
            if (rv == SECSuccess) {
                updated = PR_TRUE;
            }
        }
    }

    /* we are using the old salt if we updated from an old db */
    if (!updated) {
        rv = makeGlobalSalt(handle);
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    /* sync the database */
    ret = keydb_Sync(handle, 0);
    if (ret) {
        rv = SECFailure;
        goto loser;
    }
    rv = SECSuccess;

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

static DB *
openOldDB(const char *appName, const char *prefix, const char *dbname,
          PRBool openflags)
{
    DB *db = NULL;

    if (appName) {
        db = rdbopen(appName, prefix, "key", openflags, NULL);
    } else {
        db = dbopen(dbname, openflags, 0600, DB_HASH, 0);
    }

    return db;
}

/* check for correct version number */
static PRBool
verifyVersion(NSSLOWKEYDBHandle *handle)
{
    int version = nsslowkey_version(handle);

    handle->version = version;
    if (version != NSSLOWKEY_DB_FILE_VERSION) {
        if (handle->db) {
            keydb_Close(handle);
            handle->db = NULL;
        }
    }
    return handle->db != NULL;
}

static NSSLOWKEYDBHandle *
nsslowkey_NewHandle(DB *dbHandle)
{
    NSSLOWKEYDBHandle *handle;
    handle = (NSSLOWKEYDBHandle *)PORT_ZAlloc(sizeof(NSSLOWKEYDBHandle));
    if (handle == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    handle->appname = NULL;
    handle->dbname = NULL;
    handle->global_salt = NULL;
    handle->updatedb = NULL;
    handle->db = dbHandle;
    handle->ref = 1;
    handle->lock = PZ_NewLock(nssILockKeyDB);

    return handle;
}

NSSLOWKEYDBHandle *
nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix,
                    NSSLOWKEYDBNameFunc namecb, void *cbarg)
{
    NSSLOWKEYDBHandle *handle = NULL;
    SECStatus rv;
    int openflags;
    char *dbname = NULL;

    handle = nsslowkey_NewHandle(NULL);

    openflags = readOnly ? NO_RDONLY : NO_RDWR;

    dbname = (*namecb)(cbarg, NSSLOWKEY_DB_FILE_VERSION);
    if (dbname == NULL) {
        goto loser;
    }
    handle->appname = appName ? PORT_Strdup(appName) : NULL;
    handle->dbname = (appName == NULL) ? PORT_Strdup(dbname) : (prefix ? PORT_Strdup(prefix) : NULL);
    handle->readOnly = readOnly;

    handle->db = openOldDB(appName, prefix, dbname, openflags);
    if (handle->db) {
        verifyVersion(handle);
        if (handle->version == 255) {
            goto loser;
        }
    }

    /* if first open fails, try to create a new DB */
    if (handle->db == NULL) {
        if (readOnly) {
            goto loser;
        }

        rv = openNewDB(appName, prefix, dbname, handle, namecb, cbarg);
        /* two processes started to initialize the database at the same time.
         * The multiprocess code blocked the second one, then had it retry to
         * see if it can just open the database normally */
        if (rv == SECWouldBlock) {
            handle->db = openOldDB(appName, prefix, dbname, openflags);
            verifyVersion(handle);
            if (handle->db == NULL) {
                goto loser;
            }
        } else if (rv != SECSuccess) {
            goto loser;
        }
    }

    handle->global_salt = GetKeyDBGlobalSalt(handle);
    if (dbname)
        PORT_Free(dbname);
    return handle;

loser:

    if (dbname)
        PORT_Free(dbname);
    PORT_SetError(SEC_ERROR_BAD_DATABASE);
    nsslowkey_CloseKeyDB(handle);
    return NULL;
}

/*
 * Close the database
 */
void
nsslowkey_CloseKeyDB(NSSLOWKEYDBHandle *handle)
{
    if (handle != NULL) {
        if (handle->db != NULL) {
            keydb_Close(handle);
        }
        if (handle->updatedb) {
            handle->updatedb->close(handle->updatedb);
        }
        if (handle->dbname)
            PORT_Free(handle->dbname);
        if (handle->appname)
            PORT_Free(handle->appname);
        if (handle->global_salt) {
            SECITEM_FreeItem(handle->global_salt, PR_TRUE);
        }
        if (handle->lock != NULL) {
            SKIP_AFTER_FORK(PZ_DestroyLock(handle->lock));
        }

        PORT_Free(handle);
    }
}

/* Get the key database version */
int
nsslowkey_GetKeyDBVersion(NSSLOWKEYDBHandle *handle)
{
    PORT_Assert(handle != NULL);

    return handle->version;
}

/*
 * Delete a private key that was stored in the database
 */
SECStatus
nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle, const SECItem *pubkey)
{
    DBT namekey;
    int ret;

    if (handle == NULL) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        return (SECFailure);
    }

    /* set up db key and data */
    namekey.data = pubkey->data;
    namekey.size = pubkey->len;

    /* delete it from the database */
    ret = keydb_Del(handle, &namekey, 0);
    if (ret) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        return (SECFailure);
    }

    /* sync the database */
    ret = keydb_Sync(handle, 0);
    if (ret) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        return (SECFailure);
    }

    return (SECSuccess);
}

/*
 * Store a key in the database, indexed by its public key modulus.(value!)
 */
SECStatus
nsslowkey_StoreKeyByPublicKey(NSSLOWKEYDBHandle *handle,
                              NSSLOWKEYPrivateKey *privkey,
                              SECItem *pubKeyData,
                              char *nickname,
                              SDB *sdb)
{
    return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData,
                                            nickname, sdb, PR_FALSE);
}

SECStatus
nsslowkey_UpdateNickname(NSSLOWKEYDBHandle *handle,
                         NSSLOWKEYPrivateKey *privkey,
                         SECItem *pubKeyData,
                         char *nickname,
                         SDB *sdb)
{
    return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData,
                                            nickname, sdb, PR_TRUE);
}

/* see if the symetric CKA_ID already Exists.
 */
PRBool
nsslowkey_KeyForIDExists(NSSLOWKEYDBHandle *handle, SECItem *id)
{
    DBT namekey;
    DBT dummy;
    int status;

    namekey.data = (char *)id->data;
    namekey.size = id->len;
    status = keydb_Get(handle, &namekey, &dummy, 0);
    if (status) {
        return PR_FALSE;
    }

    return PR_TRUE;
}

/* see if the public key for this cert is in the database filed
 * by modulus
 */
PRBool
nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cert)
{
    NSSLOWKEYPublicKey *pubkey = NULL;
    DBT namekey;
    DBT dummy;
    int status;

    /* get cert's public key */
    pubkey = nsslowcert_ExtractPublicKey(cert);
    if (pubkey == NULL) {
        return PR_FALSE;
    }

    /* TNH - make key from NSSLOWKEYPublicKey */
    switch (pubkey->keyType) {
        case NSSLOWKEYRSAKey:
            namekey.data = pubkey->u.rsa.modulus.data;
            namekey.size = pubkey->u.rsa.modulus.len;
            break;
        case NSSLOWKEYDSAKey:
            namekey.data = pubkey->u.dsa.publicValue.data;
            namekey.size = pubkey->u.dsa.publicValue.len;
            break;
        case NSSLOWKEYDHKey:
            namekey.data = pubkey->u.dh.publicValue.data;
            namekey.size = pubkey->u.dh.publicValue.len;
            break;
        case NSSLOWKEYECKey:
            namekey.data = pubkey->u.ec.publicValue.data;
            namekey.size = pubkey->u.ec.publicValue.len;
            break;
        default:
            /* XXX We don't do Fortezza or DH yet. */
            return PR_FALSE;
    }

    if (handle->version != 3) {
        unsigned char buf[SHA1_LENGTH];
        SHA1_HashBuf(buf, namekey.data, namekey.size);
        /* NOTE: don't use pubkey after this! it's now thrashed */
        PORT_Memcpy(namekey.data, buf, sizeof(buf));
        namekey.size = sizeof(buf);
    }

    status = keydb_Get(handle, &namekey, &dummy, 0);
    /* some databases have the key stored as a signed value */
    if (status) {
        unsigned char *buf = (unsigned char *)PORT_Alloc(namekey.size + 1);
        if (buf) {
            PORT_Memcpy(&buf[1], namekey.data, namekey.size);
            buf[0] = 0;
            namekey.data = buf;
            namekey.size++;
            status = keydb_Get(handle, &namekey, &dummy, 0);
            PORT_Free(buf);
        }
    }
    lg_nsslowkey_DestroyPublicKey(pubkey);
    if (status) {
        return PR_FALSE;
    }

    return PR_TRUE;
}

typedef struct NSSLowPasswordDataParamStr {
    SECItem salt;
    SECItem iter;
} NSSLowPasswordDataParam;

static const SEC_ASN1Template NSSLOWPasswordParamTemplate[] =
    {
      { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLowPasswordDataParam) },
      { SEC_ASN1_OCTET_STRING, offsetof(NSSLowPasswordDataParam, salt) },
      { SEC_ASN1_INTEGER, offsetof(NSSLowPasswordDataParam, iter) },
      { 0 }
    };
struct LGEncryptedDataInfoStr {
    SECAlgorithmID algorithm;
    SECItem encryptedData;
};
typedef struct LGEncryptedDataInfoStr LGEncryptedDataInfo;

const SEC_ASN1Template lg_EncryptedDataInfoTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(LGEncryptedDataInfo) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(LGEncryptedDataInfo, algorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_OCTET_STRING,
      offsetof(LGEncryptedDataInfo, encryptedData) },
    { 0 }
};

static SECItem *
nsslowkey_EncodePW(SECOidTag alg, const SECItem *salt, SECItem *data)
{
    NSSLowPasswordDataParam param;
    LGEncryptedDataInfo edi;
    PLArenaPool *arena;
    unsigned char one = 1;
    SECItem *epw = NULL;
    SECItem *encParam;
    int iterLen = 0;
    int saltLen;
    SECStatus rv;

    param.salt = *salt;
    param.iter.type = siBuffer; /* encode as signed integer */
    param.iter.data = &one;
    param.iter.len = 1;
    edi.encryptedData = *data;

    iterLen = salt->len > 1 ? salt->data[salt->len - 1] : 2;
    saltLen = (salt->len - iterLen) - 1;
    /* if the resulting saltLen is a sha hash length, then assume that
     * the iteration count is tacked on the end of the buffer */
    if ((saltLen == SHA1_LENGTH) || (saltLen == SHA256_LENGTH) || (saltLen == SHA384_LENGTH) || (saltLen == SHA224_LENGTH) ||
        (saltLen == SHA512_LENGTH)) {
        param.iter.data = &salt->data[saltLen];
        param.iter.len = iterLen;
        param.salt.len = saltLen;
    }

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        return NULL;
    }

    encParam = SEC_ASN1EncodeItem(arena, NULL, &param,
                                  NSSLOWPasswordParamTemplate);
    if (encParam == NULL) {
        goto loser;
    }
    rv = SECOID_SetAlgorithmID(arena, &edi.algorithm, alg, encParam);
    if (rv != SECSuccess) {
        goto loser;
    }
    epw = SEC_ASN1EncodeItem(NULL, NULL, &edi, lg_EncryptedDataInfoTemplate);

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

static SECItem *
nsslowkey_DecodePW(const SECItem *derData, SECOidTag *alg, SECItem *salt)
{
    NSSLowPasswordDataParam param;
    LGEncryptedDataInfo edi;
    PLArenaPool *arena;
    SECItem *pwe = NULL;
    SECStatus rv;

    salt->data = NULL;
    param.iter.type = siBuffer; /* decode as signed integer */

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        return NULL;
    }

    rv = SEC_QuickDERDecodeItem(arena, &edi, lg_EncryptedDataInfoTemplate,
                                derData);
    if (rv != SECSuccess) {
        goto loser;
    }
    *alg = SECOID_GetAlgorithmTag(&edi.algorithm);
    rv = SEC_QuickDERDecodeItem(arena, &param, NSSLOWPasswordParamTemplate,
                                &edi.algorithm.parameters);
    if (rv != SECSuccess) {
        goto loser;
    }
    /* if the iteration count isn't one, tack it at the end of the salt */
    if (!((param.iter.len == 1) && (param.iter.data[0] == 1))) {
        int total_len = param.salt.len + param.iter.len + 1;
        salt->data = PORT_Alloc(total_len);
        if (salt->data == NULL) {
            goto loser;
        }
        PORT_Memcpy(salt->data, param.salt.data, param.salt.len);
        PORT_Memcpy(&salt->data[param.salt.len], param.iter.data,
                    param.iter.len);
        salt->data[total_len - 1] = param.iter.len;
        salt->len = total_len;
    } else {
        rv = SECITEM_CopyItem(NULL, salt, &param.salt);
        if (rv != SECSuccess) {
            goto loser;
        }
    }
    pwe = SECITEM_DupItem(&edi.encryptedData);

loser:
    if (!pwe && salt->data) {
        PORT_Free(salt->data);
        salt->data = NULL;
    }
    PORT_FreeArena(arena, PR_FALSE);
    return pwe;
}

/*
 * check to see if the user has a password
 */
static SECStatus
nsslowkey_GetPWCheckEntry(NSSLOWKEYDBHandle *handle, NSSLOWKEYPasswordEntry *entry)
{
    DBT checkkey; /*, checkdata; */
    NSSLOWKEYDBKey *dbkey = NULL;
    SECItem *global_salt = NULL;
    SECItem *item = NULL;
    SECItem entryData, oid;
    SECItem none = { siBuffer, NULL, 0 };
    SECStatus rv = SECFailure;
    SECOidTag algorithm;

    if (handle == NULL) {
        /* PORT_SetError */
        return (SECFailure);
    }

    global_salt = GetKeyDBGlobalSalt(handle);
    if (!global_salt) {
        global_salt = &none;
    }
    if (global_salt->len > sizeof(entry->data)) {
        /* PORT_SetError */
        goto loser;
    }

    PORT_Memcpy(entry->data, global_salt->data, global_salt->len);
    entry->salt.data = entry->data;
    entry->salt.len = global_salt->len;
    entry->value.data = &entry->data[entry->salt.len];

    checkkey.data = KEYDB_PW_CHECK_STRING;
    checkkey.size = KEYDB_PW_CHECK_LEN;
    dbkey = get_dbkey(handle, &checkkey);
    if (dbkey == NULL) {
        /* handle 'FAKE' check here */
        goto loser;
    }

    oid.len = dbkey->derPK.data[0];
    oid.data = &dbkey->derPK.data[1];

    if (dbkey->derPK.len < (KEYDB_PW_CHECK_LEN + 1 + oid.len)) {
        goto loser;
    }
    algorithm = SECOID_FindOIDTag(&oid);
    entryData.type = siBuffer;
    entryData.len = dbkey->derPK.len - (oid.len + 1);
    entryData.data = &dbkey->derPK.data[oid.len + 1];

    item = nsslowkey_EncodePW(algorithm, &dbkey->salt, &entryData);
    if (!item || (item->len + entry->salt.len) > sizeof(entry->data)) {
        goto loser;
    }
    PORT_Memcpy(entry->value.data, item->data, item->len);
    entry->value.len = item->len;
    rv = SECSuccess;

loser:
    if (item) {
        SECITEM_FreeItem(item, PR_TRUE);
    }
    if (dbkey) {
        sec_destroy_dbkey(dbkey);
    }
    if (global_salt != &none) {
        SECITEM_FreeItem(global_salt, PR_TRUE);
    }
    return rv;
}

/*
 * check to see if the user has a password
 */
static SECStatus
nsslowkey_PutPWCheckEntry(NSSLOWKEYDBHandle *handle, NSSLOWKEYPasswordEntry *entry)
{
    DBT checkkey;
    NSSLOWKEYDBKey *dbkey = NULL;
    SECItem *item = NULL;
    SECItem salt;
    SECOidTag algid = SEC_OID_UNKNOWN;
    SECStatus rv = SECFailure;
    PLArenaPool *arena;
    int ret;

    if (handle == NULL) {
        /* PORT_SetError */
        return (SECFailure);
    }

    checkkey.data = KEYDB_PW_CHECK_STRING;
    checkkey.size = KEYDB_PW_CHECK_LEN;

    salt.data = NULL;
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        return SECFailure;
    }

    item = nsslowkey_DecodePW(&entry->value, &algid, &salt);
    if (item == NULL) {
        goto loser;
    }

    dbkey = PORT_ArenaZNew(arena, NSSLOWKEYDBKey);
    if (dbkey == NULL) {
        goto loser;
    }

    dbkey->arena = arena;

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

    rv = encodePWCheckEntry(arena, &dbkey->derPK, algid, item);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = put_dbkey(handle, &checkkey, dbkey, PR_TRUE);
    if (rv != SECSuccess) {
        goto loser;
    }

    if (handle->global_salt) {
        SECITEM_FreeItem(handle->global_salt, PR_TRUE);
        handle->global_salt = NULL;
    }
    rv = StoreKeyDBGlobalSalt(handle, &entry->salt);
    if (rv != SECSuccess) {
        goto loser;
    }
    ret = keydb_Sync(handle, 0);
    if (ret) {
        rv = SECFailure;
        goto loser;
    }
    handle->global_salt = GetKeyDBGlobalSalt(handle);

loser:
    if (item) {
        SECITEM_FreeItem(item, PR_TRUE);
    }
    if (arena) {
        PORT_FreeArena(arena, PR_TRUE);
    }
    if (salt.data) {
        PORT_Free(salt.data);
    }
    return rv;
}

#ifdef EC_DEBUG
#define SEC_PRINT(str1, str2, num, sitem)             \
    printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \
           str1, str2, num, sitem->len);              \
    for (i = 0; i < sitem->len; i++) {                \
        printf("%02x:", sitem->data[i]);              \
    }                                                 \
    printf("\n")
#else
#define SEC_PRINT(a, b, c, d)
#endif /* EC_DEBUG */

SECStatus
seckey_encrypt_private_key(PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk,
                           SDB *sdbpw, SECItem *result)
{
    NSSLOWKEYPrivateKeyInfo *pki = NULL;
    SECStatus rv = SECFailure;
    PLArenaPool *temparena = NULL;
    SECItem *der_item = NULL;
    SECItem *cipherText = NULL;
    SECItem *dummy = NULL;
#ifdef EC_DEBUG
    SECItem *fordebug = NULL;
#endif
    int savelen;

    temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if (temparena == NULL)
        goto loser;

    /* allocate structures */
    pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
                                                      sizeof(NSSLOWKEYPrivateKeyInfo));
    der_item = (SECItem *)PORT_ArenaZAlloc(temparena, sizeof(SECItem));
    if ((pki == NULL) || (der_item == NULL))
        goto loser;

    /* setup private key info */
    dummy = SEC_ASN1EncodeInteger(temparena, &(pki->version),
                                  NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
    if (dummy == NULL)
        goto loser;

    /* Encode the key, and set the algorithm (with params) */
    switch (pk->keyType) {
        case NSSLOWKEYRSAKey:
            lg_prepare_low_rsa_priv_key_for_asn1(pk);
            dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
                                       lg_nsslowkey_RSAPrivateKeyTemplate);
            if (dummy == NULL) {
                rv = SECFailure;
                goto loser;
            }

            rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm),
                                       SEC_OID_PKCS1_RSA_ENCRYPTION, 0);
            if (rv == SECFailure) {
                goto loser;
            }

            break;
        case NSSLOWKEYDSAKey:
            lg_prepare_low_dsa_priv_key_for_asn1(pk);
            dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
                                       lg_nsslowkey_DSAPrivateKeyTemplate);
            if (dummy == NULL) {
                rv = SECFailure;
                goto loser;
            }

            lg_prepare_low_pqg_params_for_asn1(&pk->u.dsa.params);
            dummy = SEC_ASN1EncodeItem(temparena, NULL, &pk->u.dsa.params,
                                       lg_nsslowkey_PQGParamsTemplate);
            if (dummy == NULL) {
                rv = SECFailure;
                goto loser;
            }

            rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm),
                                       SEC_OID_ANSIX9_DSA_SIGNATURE, dummy);
            if (rv == SECFailure) {
                goto loser;
            }

            break;
        case NSSLOWKEYDHKey:
            lg_prepare_low_dh_priv_key_for_asn1(pk);
            dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
                                       lg_nsslowkey_DHPrivateKeyTemplate);
            if (dummy == NULL) {
                rv = SECFailure;
                goto loser;
            }

            rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm),
                                       SEC_OID_X942_DIFFIE_HELMAN_KEY, dummy);
            if (rv == SECFailure) {
                goto loser;
            }
            break;
        case NSSLOWKEYECKey:
            lg_prepare_low_ec_priv_key_for_asn1(pk);
            /* Public value is encoded as a bit string so adjust length
             * to be in bits before ASN encoding and readjust
             * immediately after.
             *
             * Since the SECG specification recommends not including the
             * parameters as part of ECPrivateKey, we zero out the curveOID
             * length before encoding and restore it later.
             */
            pk->u.ec.publicValue.len <<= 3;
            savelen = pk->u.ec.ecParams.curveOID.len;
            pk->u.ec.ecParams.curveOID.len = 0;
            dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
                                       lg_nsslowkey_ECPrivateKeyTemplate);
            pk->u.ec.ecParams.curveOID.len = savelen;
            pk->u.ec.publicValue.len >>= 3;

            if (dummy == NULL) {
                rv = SECFailure;
                goto loser;
            }

            dummy = &pk->u.ec.ecParams.DEREncoding;

            /* At this point dummy should contain the encoded params */
            rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm),
                                       SEC_OID_ANSIX962_EC_PUBLIC_KEY, dummy);

            if (rv == SECFailure) {
                goto loser;
            }

#ifdef EC_DEBUG
            fordebug = &(pki->privateKey);
            SEC_PRINT("seckey_encrypt_private_key()", "PrivateKey",
                      pk->keyType, fordebug);
#endif

            break;
        default:
            /* We don't support DH or Fortezza private keys yet */
            PORT_Assert(PR_FALSE);
            break;
    }

    /* setup encrypted private key info */
    dummy = SEC_ASN1EncodeItem(temparena, der_item, pki,
                               lg_nsslowkey_PrivateKeyInfoTemplate);

    SEC_PRINT("seckey_encrypt_private_key()", "PrivateKeyInfo",
              pk->keyType, der_item);

    if (dummy == NULL) {
        rv = SECFailure;
        goto loser;
    }

    rv = lg_util_encrypt(temparena, sdbpw, dummy, &cipherText);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = SECITEM_CopyItem(permarena, result, cipherText);

loser:

    if (temparena != NULL)
        PORT_FreeArena(temparena, PR_TRUE);

    return rv;
}

static SECStatus
seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SDB *sdbpw,
                       NSSLOWKEYPrivateKey *pk, char *nickname, PRBool update)
{
    NSSLOWKEYDBKey *dbkey = NULL;
    PLArenaPool *arena = NULL;
    SECStatus rv = SECFailure;

    if ((keydb == NULL) || (index == NULL) || (sdbpw == NULL) ||
        (pk == NULL))
        return SECFailure;

    arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if (arena == NULL)
        return SECFailure;

    dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey));
    if (dbkey == NULL)
        goto loser;
    dbkey->arena = arena;
    dbkey->nickname = nickname;

    rv = seckey_encrypt_private_key(arena, pk, sdbpw, &dbkey->derPK);
    if (rv != SECSuccess)
        goto loser;

    rv = put_dbkey(keydb, index, dbkey, update);

/* let success fall through */
loser:
    if (arena != NULL)
        PORT_FreeArena(arena, PR_TRUE);

    return rv;
}

/*
 * Store a key in the database, indexed by its public key modulus.
 * Note that the nickname is optional.  It was only used by keyutil.
 */
SECStatus
nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
                                 NSSLOWKEYPrivateKey *privkey,
                                 SECItem *pubKeyData,
                                 char *nickname,
                                 SDB *sdbpw,
                                 PRBool update)
{
    DBT namekey;
    SECStatus rv;

    if (handle == NULL) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        return (SECFailure);
    }

    /* set up db key and data */
    namekey.data = pubKeyData->data;
    namekey.size = pubKeyData->len;

    /* encrypt the private key */
    rv = seckey_put_private_key(handle, &namekey, sdbpw, privkey, nickname,
                                update);

    return (rv);
}

static NSSLOWKEYPrivateKey *
seckey_decrypt_private_key(SECItem *epki,
                           SDB *sdbpw)
{
    NSSLOWKEYPrivateKey *pk = NULL;
    NSSLOWKEYPrivateKeyInfo *pki = NULL;
    SECStatus rv = SECFailure;
    PLArenaPool *temparena = NULL, *permarena = NULL;
    SECItem *dest = NULL;
#ifdef EC_DEBUG
    SECItem *fordebug = NULL;
#endif

    if ((epki == NULL) || (sdbpw == NULL))
        goto loser;

    temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    permarena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if ((temparena == NULL) || (permarena == NULL))
        goto loser;

    /* allocate temporary items */
    pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
                                                      sizeof(NSSLOWKEYPrivateKeyInfo));

    /* allocate permanent arena items */
    pk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(permarena,
                                                 sizeof(NSSLOWKEYPrivateKey));

    if ((pk == NULL) || (pki == NULL))
        goto loser;

    pk->arena = permarena;

    rv = lg_util_decrypt(sdbpw, epki, &dest);
    if (rv != SECSuccess) {
        goto loser;
    }

    if (dest != NULL) {
        SECItem newPrivateKey;
        SECItem newAlgParms;

        SEC_PRINT("seckey_decrypt_private_key()", "PrivateKeyInfo", -1,
                  dest);

        rv = SEC_QuickDERDecodeItem(temparena, pki,
                                    lg_nsslowkey_PrivateKeyInfoTemplate, dest);
        if (rv == SECSuccess) {
            switch (SECOID_GetAlgorithmTag(&pki->algorithm)) {
                case SEC_OID_X500_RSA_ENCRYPTION:
                case SEC_OID_PKCS1_RSA_ENCRYPTION:
                    pk->keyType = NSSLOWKEYRSAKey;
                    lg_prepare_low_rsa_priv_key_for_asn1(pk);
                    if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey,
                                                       &pki->privateKey))
                        break;
                    rv = SEC_QuickDERDecodeItem(permarena, pk,
                                                lg_nsslowkey_RSAPrivateKeyTemplate,
                                                &newPrivateKey);
                    if (rv == SECSuccess) {
                        break;
                    }
                    /* Try decoding with the alternative template, but only allow
                     * a zero-length modulus for a secret key object.
                     * See bug 715073.
                     */
                    rv = SEC_QuickDERDecodeItem(permarena, pk,
                                                lg_nsslowkey_RSAPrivateKeyTemplate2,
                                                &newPrivateKey);
                    /* A publicExponent of 0 is the defining property of a secret
                     * key disguised as an RSA key. When decoding with the
                     * alternative template, only accept a secret key with an
                     * improperly encoded modulus and a publicExponent of 0.
                     */
                    if (rv == SECSuccess) {
                        if (pk->u.rsa.modulus.len == 2 &&
                            pk->u.rsa.modulus.data[0] == SEC_ASN1_INTEGER &&
                            pk->u.rsa.modulus.data[1] == 0 &&
                            pk->u.rsa.publicExponent.len == 1 &&
                            pk->u.rsa.publicExponent.data[0] == 0) {
                            /* Fix the zero-length integer by setting it to 0. */
                            pk->u.rsa.modulus.data = pk->u.rsa.publicExponent.data;
                            pk->u.rsa.modulus.len = pk->u.rsa.publicExponent.len;
                        } else {
                            PORT_SetError(SEC_ERROR_BAD_DER);
                            rv = SECFailure;
                        }
                    }
                    break;
                case SEC_OID_ANSIX9_DSA_SIGNATURE:
                    pk->keyType = NSSLOWKEYDSAKey;
                    lg_prepare_low_dsa_priv_key_for_asn1(pk);
                    if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey,
                                                       &pki->privateKey))
                        break;
                    rv = SEC_QuickDERDecodeItem(permarena, pk,
                                                lg_nsslowkey_DSAPrivateKeyTemplate,
                                                &newPrivateKey);
                    if (rv != SECSuccess)
                        goto loser;
                    lg_prepare_low_pqg_params_for_asn1(&pk->u.dsa.params);
                    if (SECSuccess != SECITEM_CopyItem(permarena, &newAlgParms,
                                                       &pki->algorithm.parameters))
                        break;
                    rv = SEC_QuickDERDecodeItem(permarena, &pk->u.dsa.params,
                                                lg_nsslowkey_PQGParamsTemplate,
                                                &newAlgParms);
                    break;
                case SEC_OID_X942_DIFFIE_HELMAN_KEY:
                    pk->keyType = NSSLOWKEYDHKey;
                    lg_prepare_low_dh_priv_key_for_asn1(pk);
                    if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey,
                                                       &pki->privateKey))
                        break;
                    rv = SEC_QuickDERDecodeItem(permarena, pk,
                                                lg_nsslowkey_DHPrivateKeyTemplate,
                                                &newPrivateKey);
                    break;
                case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
                    pk->keyType = NSSLOWKEYECKey;
                    lg_prepare_low_ec_priv_key_for_asn1(pk);

#ifdef EC_DEBUG
                    fordebug = &pki->privateKey;
                    SEC_PRINT("seckey_decrypt_private_key()", "PrivateKey",
                              pk->keyType, fordebug);
#endif
                    if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey,
                                                       &pki->privateKey))
                        break;
                    rv = SEC_QuickDERDecodeItem(permarena, pk,
                                                lg_nsslowkey_ECPrivateKeyTemplate,
                                                &newPrivateKey);
                    if (rv != SECSuccess)
                        goto loser;

                    lg_prepare_low_ecparams_for_asn1(&pk->u.ec.ecParams);

                    rv = SECITEM_CopyItem(permarena,
                                          &pk->u.ec.ecParams.DEREncoding,
                                          &pki->algorithm.parameters);

                    if (rv != SECSuccess)
                        goto loser;

                    /* Fill out the rest of EC params */
                    rv = LGEC_FillParams(permarena, &pk->u.ec.ecParams.DEREncoding,
                                         &pk->u.ec.ecParams);

                    if (rv != SECSuccess)
                        goto loser;

                    if (pk->u.ec.publicValue.len != 0) {
                        pk->u.ec.publicValue.len >>= 3;
                    }

                    break;
                default:
                    rv = SECFailure;
                    break;
            }
        } else if (PORT_GetError() == SEC_ERROR_BAD_DER) {
            PORT_SetError(SEC_ERROR_BAD_PASSWORD);
            goto loser;
        }
    }

/* let success fall through */
loser:
    if (temparena != NULL)
        PORT_FreeArena(temparena, PR_TRUE);
    if (dest != NULL)
        SECITEM_ZfreeItem(dest, PR_TRUE);

    if (rv != SECSuccess) {
        if (permarena != NULL)
            PORT_FreeArena(permarena, PR_TRUE);
        pk = NULL;
    }

    return pk;
}

static NSSLOWKEYPrivateKey *
seckey_decode_encrypted_private_key(NSSLOWKEYDBKey *dbkey, SDB *sdbpw)
{
    if ((dbkey == NULL) || (sdbpw == NULL)) {
        return NULL;
    }

    return seckey_decrypt_private_key(&(dbkey->derPK), sdbpw);
}

static NSSLOWKEYPrivateKey *
seckey_get_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, char **nickname,
                       SDB *sdbpw)
{
    NSSLOWKEYDBKey *dbkey = NULL;
    NSSLOWKEYPrivateKey *pk = NULL;

    if ((keydb == NULL) || (index == NULL) || (sdbpw == NULL)) {
        return NULL;
    }

    dbkey = get_dbkey(keydb, index);
    if (dbkey == NULL) {
        goto loser;
    }

    if (nickname) {
        if (dbkey->nickname && (dbkey->nickname[0] != 0)) {
            *nickname = PORT_Strdup(dbkey->nickname);
        } else {
            *nickname = NULL;
        }
    }

    pk = seckey_decode_encrypted_private_key(dbkey, sdbpw);

/* let success fall through */
loser:

    if (dbkey != NULL) {
        sec_destroy_dbkey(dbkey);
    }

    return pk;
}

/*
 * Find a key in the database, indexed by its public key modulus
 * This is used to find keys that have been stored before their
 * certificate arrives.  Once the certificate arrives the key
 * is looked up by the public modulus in the certificate, and the
 * re-stored by its nickname.
 */
NSSLOWKEYPrivateKey *
nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
                             SDB *sdbpw)
{
    DBT namekey;
    NSSLOWKEYPrivateKey *pk = NULL;

    if (handle == NULL) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        return NULL;
    }

    /* set up db key */
    namekey.data = modulus->data;
    namekey.size = modulus->len;

    pk = seckey_get_private_key(handle, &namekey, NULL, sdbpw);

    /* no need to free dbkey, since its on the stack, and the data it
     * points to is owned by the database
     */
    return (pk);
}

char *
nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle,
                                     SECItem *modulus, SDB *sdbpw)
{
    DBT namekey;
    NSSLOWKEYPrivateKey *pk = NULL;
    char *nickname = NULL;

    if (handle == NULL) {
        PORT_SetError(SEC_ERROR_BAD_DATABASE);
        return NULL;
    }

    /* set up db key */
    namekey.data = modulus->data;
    namekey.size = modulus->len;

    pk = seckey_get_private_key(handle, &namekey, &nickname, sdbpw);
    if (pk) {
        lg_nsslowkey_DestroyPrivateKey(pk);
    }

    /* no need to free dbkey, since its on the stack, and the data it
     * points to is owned by the database
     */
    return (nickname);
}
/* ===== ENCODING ROUTINES ===== */

static SECStatus
encodePWCheckEntry(PLArenaPool *arena, SECItem *entry, SECOidTag alg,
                   SECItem *encCheck)
{
    SECOidData *oidData;

    oidData = SECOID_FindOIDByTag(alg);
    if (oidData == NULL) {
        return SECFailure;
    }

    entry->len = 1 + oidData->oid.len + encCheck->len;
    if (arena) {
        entry->data = (unsigned char *)PORT_ArenaAlloc(arena, entry->len);
    } else {
        entry->data = (unsigned char *)PORT_Alloc(entry->len);
    }

    if (entry->data == NULL) {
        return SECFailure;
    }

    /* first length of oid */
    entry->data[0] = (unsigned char)oidData->oid.len;
    /* next oid itself */
    PORT_Memcpy(&entry->data[1], oidData->oid.data, oidData->oid.len);
    /* finally the encrypted check string */
    PORT_Memcpy(&entry->data[1 + oidData->oid.len], encCheck->data,
                encCheck->len);

    return SECSuccess;
}

#define MAX_DB_SIZE 0xffff
/*
 * Clear out all the keys in the existing database
 */
static SECStatus
nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle)
{
    SECStatus rv;
    int errors = 0;

    if (handle->db == NULL) {
        return (SECSuccess);
    }

    if (handle->readOnly) {
        /* set an error code */
        return SECFailure;
    }

    if (handle->appname == NULL && handle->dbname == NULL) {
        return SECFailure;
    }

    keydb_Close(handle);
    if (handle->appname) {
        handle->db =
            rdbopen(handle->appname, handle->dbname, "key", NO_CREATE, NULL);
    } else {
        handle->db = dbopen(handle->dbname, NO_CREATE, 0600, DB_HASH, 0);
    }
    if (handle->db == NULL) {
        /* set an error code */
        return SECFailure;
    }

    rv = makeGlobalVersion(handle);
    if (rv != SECSuccess) {
        errors++;
        goto done;
    }

    if (handle->global_salt) {
        rv = StoreKeyDBGlobalSalt(handle, handle->global_salt);
    } else {
        rv = makeGlobalSalt(handle);
        if (rv == SECSuccess) {
            handle->global_salt = GetKeyDBGlobalSalt(handle);
        }
    }
    if (rv != SECSuccess) {
        errors++;
    }

done:
    /* sync the database */
    (void)keydb_Sync(handle, 0);
    db_InitComplete(handle->db);

    return (errors == 0 ? SECSuccess : SECFailure);
}

static int
keydb_Get(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
{
    int ret;
    PRLock *kdbLock = kdb->lock;
    DB *db = kdb->db;

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

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

    (void)PZ_Unlock(kdbLock);

    return (ret);
}

static int
keydb_Put(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
{
    int ret = 0;
    PRLock *kdbLock = kdb->lock;
    DB *db = kdb->db;

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

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

    (void)PZ_Unlock(kdbLock);

    return (ret);
}

static int
keydb_Sync(NSSLOWKEYDBHandle *kdb, unsigned int flags)
{
    int ret;
    PRLock *kdbLock = kdb->lock;
    DB *db = kdb->db;

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

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

    (void)PZ_Unlock(kdbLock);

    return (ret);
}

static int
keydb_Del(NSSLOWKEYDBHandle *kdb, DBT *key, unsigned int flags)
{
    int ret;
    PRLock *kdbLock = kdb->lock;
    DB *db = kdb->db;

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

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

    (void)PZ_Unlock(kdbLock);

    return (ret);
}

static int
keydb_Seq(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
{
    int ret;
    PRLock *kdbLock = kdb->lock;
    DB *db = kdb->db;

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

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

    (void)PZ_Unlock(kdbLock);

    return (ret);
}

static void
keydb_Close(NSSLOWKEYDBHandle *kdb)
{
    PRLock *kdbLock = kdb->lock;
    DB *db = kdb->db;

    PORT_Assert(kdbLock != NULL);
    SKIP_AFTER_FORK(PZ_Lock(kdbLock));

    (*db->close)(db);

    SKIP_AFTER_FORK(PZ_Unlock(kdbLock));

    return;
}

/*
 * SDB Entry Points for the Key DB
 */

CK_RV
lg_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2)
{
    NSSLOWKEYDBHandle *keydb;
    NSSLOWKEYPasswordEntry entry;
    SECStatus rv;

    keydb = lg_getKeyDB(sdb);
    if (keydb == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }
    if (PORT_Strcmp(id, "password") != 0) {
        /* shouldn't happen */
        return CKR_GENERAL_ERROR; /* no extra data stored */
    }
    rv = nsslowkey_GetPWCheckEntry(keydb, &entry);
    if (rv != SECSuccess) {
        return CKR_GENERAL_ERROR;
    }
    item1->len = entry.salt.len;
    PORT_Memcpy(item1->data, entry.salt.data, item1->len);
    item2->len = entry.value.len;
    PORT_Memcpy(item2->data, entry.value.data, item2->len);
    return CKR_OK;
}

CK_RV
lg_PutMetaData(SDB *sdb, const char *id,
               const SECItem *item1, const SECItem *item2)
{
    NSSLOWKEYDBHandle *keydb;
    NSSLOWKEYPasswordEntry entry;
    SECStatus rv;

    keydb = lg_getKeyDB(sdb);
    if (keydb == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }
    if (PORT_Strcmp(id, "password") != 0) {
        /* shouldn't happen */
        return CKR_GENERAL_ERROR; /* no extra data stored */
    }
    entry.salt = *item1;
    entry.value = *item2;
    rv = nsslowkey_PutPWCheckEntry(keydb, &entry);
    if (rv != SECSuccess) {
        return CKR_GENERAL_ERROR;
    }
    return CKR_OK;
}

CK_RV
lg_DestroyMetaData(SDB *db, const char *id)
{
    return CKR_GENERAL_ERROR; /* no extra data stored */
}

CK_RV
lg_Reset(SDB *sdb)
{
    NSSLOWKEYDBHandle *keydb;
    SECStatus rv;

    keydb = lg_getKeyDB(sdb);
    if (keydb == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }
    rv = nsslowkey_ResetKeyDB(keydb);
    if (rv != SECSuccess) {
        return CKR_GENERAL_ERROR;
    }
    return CKR_OK;
}
