/* 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;
    SECStatus rv;

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

    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;
    }
    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_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;
}
