/* 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/. */
/*
 *  The following code handles the storage of PKCS 11 modules used by the
 * NSS. For the rest of NSS, only one kind of database handle exists:
 *
 *     SFTKDBHandle
 *
 * There is one SFTKDBHandle for the each key database and one for each cert
 * database. These databases are opened as associated pairs, one pair per
 * slot. SFTKDBHandles are reference counted objects.
 *
 * Each SFTKDBHandle points to a low level database handle (SDB). This handle
 * represents the underlying physical database. These objects are not
 * reference counted, an are 'owned' by their respective SFTKDBHandles.
 *
 *
 */
#include "sftkdb.h"
#include "sftkdbti.h"
#include "pkcs11t.h"
#include "pkcs11i.h"
#include "sdb.h"
#include "prprf.h"
#include "secasn1.h"
#include "pratom.h"
#include "blapi.h"
#include "secoid.h"
#include "lowpbe.h"
#include "secdert.h"
#include "prsystem.h"
#include "lgglue.h"
#include "secerr.h"
#include "softoken.h"

static const int NSS_MP_PBE_ITERATION_COUNT = 10000;

static int
getPBEIterationCount(void)
{
    int c = NSS_MP_PBE_ITERATION_COUNT;

    char *val = getenv("NSS_MIN_MP_PBE_ITERATION_COUNT");
    if (val) {
        int minimum = atoi(val);
        if (c < minimum) {
            c = minimum;
        }
    }

    val = getenv("NSS_MAX_MP_PBE_ITERATION_COUNT");
    if (val) {
        int maximum = atoi(val);
        if (c > maximum) {
            c = maximum;
        }
    }

    return c;
}

PRBool
sftk_isLegacyIterationCountAllowed(void)
{
    static const char *legacyCountEnvVar =
        "NSS_ALLOW_LEGACY_DBM_ITERATION_COUNT";
    char *iterEnv = getenv(legacyCountEnvVar);
    return (iterEnv && strcmp("0", iterEnv) != 0);
}

/******************************************************************
 *
 * Key DB password handling functions
 *
 * These functions manage the key db password (set, reset, initialize, use).
 *
 * The key is managed on 'this side' of the database. All private data is
 * encrypted before it is sent to the database itself. Besides PBE's, the
 * database management code can also mix in various fixed keys so the data
 * in the database is no longer considered 'plain text'.
 */

/* take string password and turn it into a key. The key is dependent
 * on a global salt entry acquired from the database. This salted
 * value will be based to a pkcs5 pbe function before it is used
 * in an actual encryption */
static SECStatus
sftkdb_passwordToKey(SFTKDBHandle *keydb, SECItem *salt,
                     const char *pw, SECItem *key)
{
    SHA1Context *cx = NULL;
    SECStatus rv = SECFailure;

    if (!pw) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    key->data = PORT_Alloc(SHA1_LENGTH);
    if (key->data == NULL) {
        goto loser;
    }
    key->len = SHA1_LENGTH;

    cx = SHA1_NewContext();
    if (cx == NULL) {
        goto loser;
    }
    SHA1_Begin(cx);
    if (salt && salt->data) {
        SHA1_Update(cx, salt->data, salt->len);
    }
    SHA1_Update(cx, (unsigned char *)pw, PORT_Strlen(pw));
    SHA1_End(cx, key->data, &key->len, key->len);
    rv = SECSuccess;

loser:
    if (cx) {
        SHA1_DestroyContext(cx, PR_TRUE);
    }
    if (rv != SECSuccess) {
        if (key->data != NULL) {
            PORT_ZFree(key->data, key->len);
        }
        key->data = NULL;
    }
    return rv;
}

/*
 * Cipher text stored in the database contains 3 elements:
 * 1) an identifier describing the encryption algorithm.
 * 2) an entry specific salt value.
 * 3) the encrypted value.
 *
 * The following data structure represents the encrypted data in a decoded
 * (but still encrypted) form.
 */
typedef struct sftkCipherValueStr sftkCipherValue;
struct sftkCipherValueStr {
    PLArenaPool *arena;
    SECOidTag alg;
    NSSPKCS5PBEParameter *param;
    SECItem salt;
    SECItem value;
};

#define SFTK_CIPHERTEXT_VERSION 3

struct SFTKDBEncryptedDataInfoStr {
    SECAlgorithmID algorithm;
    SECItem encryptedData;
};
typedef struct SFTKDBEncryptedDataInfoStr SFTKDBEncryptedDataInfo;

SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)

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

/*
 * This parses the cipherText into cipher value. NOTE: cipherValue will point
 * to data in cipherText, if cipherText is freed, cipherValue will be invalid.
 */
static SECStatus
sftkdb_decodeCipherText(const SECItem *cipherText, sftkCipherValue *cipherValue)
{
    PLArenaPool *arena = NULL;
    SFTKDBEncryptedDataInfo edi;
    SECStatus rv;

    PORT_Assert(cipherValue);
    cipherValue->arena = NULL;
    cipherValue->param = NULL;

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

    rv = SEC_QuickDERDecodeItem(arena, &edi, sftkdb_EncryptedDataInfoTemplate,
                                cipherText);
    if (rv != SECSuccess) {
        goto loser;
    }
    cipherValue->alg = SECOID_GetAlgorithmTag(&edi.algorithm);
    cipherValue->param = nsspkcs5_AlgidToParam(&edi.algorithm);
    if (cipherValue->param == NULL) {
        goto loser;
    }
    cipherValue->value = edi.encryptedData;
    cipherValue->arena = arena;

    return SECSuccess;
loser:
    if (cipherValue->param) {
        nsspkcs5_DestroyPBEParameter(cipherValue->param);
        cipherValue->param = NULL;
    }
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return SECFailure;
}

/*
 * unlike decode, Encode actually allocates a SECItem the caller must free
 * The caller can pass an optional arena to to indicate where to place
 * the resultant cipherText.
 */
static SECStatus
sftkdb_encodeCipherText(PLArenaPool *arena, sftkCipherValue *cipherValue,
                        SECItem **cipherText)
{
    SFTKDBEncryptedDataInfo edi;
    SECAlgorithmID *algid;
    SECStatus rv;
    PLArenaPool *localArena = NULL;

    localArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (localArena == NULL) {
        return SECFailure;
    }

    algid = nsspkcs5_CreateAlgorithmID(localArena, cipherValue->alg,
                                       cipherValue->param);
    if (algid == NULL) {
        rv = SECFailure;
        goto loser;
    }
    rv = SECOID_CopyAlgorithmID(localArena, &edi.algorithm, algid);
    SECOID_DestroyAlgorithmID(algid, PR_TRUE);
    if (rv != SECSuccess) {
        goto loser;
    }
    edi.encryptedData = cipherValue->value;

    *cipherText = SEC_ASN1EncodeItem(arena, NULL, &edi,
                                     sftkdb_EncryptedDataInfoTemplate);
    if (*cipherText == NULL) {
        rv = SECFailure;
    }

loser:
    if (localArena) {
        PORT_FreeArena(localArena, PR_TRUE);
    }

    return rv;
}

/*
 * Use our key to decode a cipherText block from the database.
 *
 * plain text is allocated by nsspkcs5_CipherData and must be freed
 * with SECITEM_FreeItem by the caller.
 */
SECStatus
sftkdb_DecryptAttribute(SFTKDBHandle *handle, SECItem *passKey,
                        CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type,
                        SECItem *cipherText, SECItem **plain)
{
    SECStatus rv;
    sftkCipherValue cipherValue;

    /* First get the cipher type */
    *plain = NULL;
    rv = sftkdb_decodeCipherText(cipherText, &cipherValue);
    if (rv != SECSuccess) {
        goto loser;
    }

    *plain = nsspkcs5_CipherData(cipherValue.param, passKey, &cipherValue.value,
                                 PR_FALSE, NULL);
    if (*plain == NULL) {
        rv = SECFailure;
        goto loser;
    }

    /* If we are using aes 256, we need to check authentication as well.*/
    if ((type != CKT_INVALID_TYPE) &&
        (cipherValue.alg == SEC_OID_PKCS5_PBES2) &&
        (cipherValue.param->encAlg == SEC_OID_AES_256_CBC)) {
        SECItem signature;
        unsigned char signData[SDB_MAX_META_DATA_LEN];
        CK_RV crv;

        /* if we get here from the old legacy db, there is clearly an
         * error, don't return the plaintext */
        if (handle == NULL) {
            rv = SECFailure;
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            goto loser;
        }

        signature.data = signData;
        signature.len = sizeof(signData);
        rv = SECFailure;
        /* sign sftkdb_GetAttriibuteSignature returns a crv, not an rv */
        crv = sftkdb_GetAttributeSignature(handle, handle, id, type,
                                           &signature);
        if (crv == CKR_OK) {
            rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE,
                                        type, *plain, &signature);
        }
        if (rv != SECSuccess) {
            /*  handle bug 1720226 where old versions of NSS misfiled the signature
             *  attribute on password update */
            id |= SFTK_KEYDB_TYPE | SFTK_TOKEN_TYPE;
            signature.len = sizeof(signData);
            crv = sftkdb_GetAttributeSignature(handle, handle, id, type,
                                               &signature);
            if (crv != CKR_OK) {
                rv = SECFailure;
                PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
                goto loser;
            }
            rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE,
                                        type, *plain, &signature);
        }
    }

loser:
    if (cipherValue.param) {
        nsspkcs5_DestroyPBEParameter(cipherValue.param);
    }
    if (cipherValue.arena) {
        PORT_FreeArena(cipherValue.arena, PR_FALSE);
    }
    /* Item decrypted, but failed integrity, clear it out */
    if (*plain && rv != SECSuccess) {
        SECITEM_ZfreeItem(*plain, PR_TRUE);
        *plain = NULL;
    }
    return rv;
}

/* If the database can't store the integrity check, it's a non-FIPS database
 * and we use the old encryption scheme for it */
static PRBool
sftkdb_useLegacyEncryption(SFTKDBHandle *handle, SDB *db)
{
    if ((handle == NULL) || (db == NULL)) {
        /* this is the case where the legacy db is calling back to us to
         * encrypt or decrypt attributes inside the lower level db code.
         * This is because the legacy db stored keys as pkcs #8 encrypted
         * blobs rather than individual encrypted attributes */
        return PR_TRUE;
    }
    /* currently, only the legacy db can't store meta data, but if we
     * add a new db that also can't store meta data, then it to wouldn't
     * be able to do the integrity checks. In both cases use the old encryption
     * algorithms. */
    if ((db->sdb_flags & SDB_HAS_META) == 0) {
        return PR_TRUE;
    }
    return PR_FALSE;
}

/*
 * encrypt a block. This function returned the encrypted ciphertext which
 * the caller must free. If the caller provides an arena, cipherText will
 * be allocated out of that arena. This also generated the per entry
 * salt automatically.
 */
SECStatus
sftkdb_EncryptAttribute(PLArenaPool *arena, SFTKDBHandle *handle, SDB *db,
                        SECItem *passKey, int iterationCount,
                        CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type,
                        SECItem *plainText, SECItem **cipherText)
{
    SECStatus rv;
    sftkCipherValue cipherValue;
    SECItem *cipher = NULL;
    NSSPKCS5PBEParameter *param = NULL;
    unsigned char saltData[HASH_LENGTH_MAX];
    SECItem *signature = NULL;
    HASH_HashType hashType = HASH_AlgNULL;

    if (sftkdb_useLegacyEncryption(handle, db)) {
        cipherValue.alg = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC;
        cipherValue.salt.len = SHA1_LENGTH;
        hashType = HASH_AlgSHA1;
    } else {
        cipherValue.alg = SEC_OID_AES_256_CBC;
        cipherValue.salt.len = SHA256_LENGTH;
        hashType = HASH_AlgSHA256;
    }
    cipherValue.salt.data = saltData;
    RNG_GenerateGlobalRandomBytes(saltData, cipherValue.salt.len);

    param = nsspkcs5_NewParam(cipherValue.alg, hashType, &cipherValue.salt,
                              iterationCount);
    if (param == NULL) {
        rv = SECFailure;
        goto loser;
    }
    cipher = nsspkcs5_CipherData(param, passKey, plainText, PR_TRUE, NULL);
    if (cipher == NULL) {
        rv = SECFailure;
        goto loser;
    }
    cipherValue.value = *cipher;
    cipherValue.param = param;

    rv = sftkdb_encodeCipherText(arena, &cipherValue, cipherText);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* If we are using aes 256, we need to add authentication as well */
    if ((type != CKT_INVALID_TYPE) &&
        (cipherValue.param->encAlg == SEC_OID_AES_256_CBC)) {
        rv = sftkdb_SignAttribute(arena, handle, db, passKey, iterationCount,
                                  CK_INVALID_HANDLE, type, plainText,
                                  &signature);
        if (rv != SECSuccess) {
            goto loser;
        }
        rv = sftkdb_PutAttributeSignature(handle, db, id, type,
                                          signature);
        if (rv != SECSuccess) {
            goto loser;
        }
    }

loser:
    if ((arena == NULL) && signature) {
        SECITEM_ZfreeItem(signature, PR_TRUE);
    }
    if (cipher) {
        SECITEM_FreeItem(cipher, PR_TRUE);
    }
    if (param) {
        nsspkcs5_DestroyPBEParameter(param);
    }
    return rv;
}

/*
 * use the password and the pbe parameters to generate an HMAC for the
 * given plain text data. This is used by sftkdb_VerifyAttribute and
 * sftkdb_SignAttribute. Signature is returned in signData. The caller
 * must preallocate the space in the secitem.
 */
static SECStatus
sftkdb_pbehash(SECOidTag sigOid, SECItem *passKey,
               NSSPKCS5PBEParameter *param,
               CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType,
               SECItem *plainText, SECItem *signData)
{
    SECStatus rv = SECFailure;
    SECItem *key = NULL;
    HMACContext *hashCx = NULL;
    HASH_HashType hashType = HASH_AlgNULL;
    const SECHashObject *hashObj;
    unsigned char addressData[SDB_ULONG_SIZE];

    hashType = HASH_FromHMACOid(param->encAlg);
    if (hashType == HASH_AlgNULL) {
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
        return SECFailure;
    }

    hashObj = HASH_GetRawHashObject(hashType);
    if (hashObj == NULL) {
        goto loser;
    }

    key = nsspkcs5_ComputeKeyAndIV(param, passKey, NULL, PR_FALSE);
    if (!key) {
        goto loser;
    }

    hashCx = HMAC_Create(hashObj, key->data, key->len, PR_TRUE);
    if (!hashCx) {
        goto loser;
    }
    HMAC_Begin(hashCx);
    /* Tie this value to a particular object. This is most important for
     * the trust attributes, where and attacker could copy a value for
     * 'validCA' from another cert in the database */
    sftk_ULong2SDBULong(addressData, objectID);
    HMAC_Update(hashCx, addressData, SDB_ULONG_SIZE);
    sftk_ULong2SDBULong(addressData, attrType);
    HMAC_Update(hashCx, addressData, SDB_ULONG_SIZE);

    HMAC_Update(hashCx, plainText->data, plainText->len);
    rv = HMAC_Finish(hashCx, signData->data, &signData->len, signData->len);

loser:
    if (hashCx) {
        HMAC_Destroy(hashCx, PR_TRUE);
    }
    if (key) {
        SECITEM_ZfreeItem(key, PR_TRUE);
    }
    return rv;
}

/*
 * Use our key to verify a signText block from the database matches
 * the plainText from the database. The signText is a PKCS 5 v2 pbe.
 * plainText is the plainText of the attribute.
 */
SECStatus
sftkdb_VerifyAttribute(SFTKDBHandle *handle,
                       SECItem *passKey, CK_OBJECT_HANDLE objectID,
                       CK_ATTRIBUTE_TYPE attrType,
                       SECItem *plainText, SECItem *signText)
{
    SECStatus rv;
    sftkCipherValue signValue;
    SECItem signature;
    unsigned char signData[HASH_LENGTH_MAX];

    /* First get the cipher type */
    rv = sftkdb_decodeCipherText(signText, &signValue);
    if (rv != SECSuccess) {
        goto loser;
    }
    signature.data = signData;
    signature.len = sizeof(signData);

    rv = sftkdb_pbehash(signValue.alg, passKey, signValue.param,
                        objectID, attrType, plainText, &signature);
    if (rv != SECSuccess) {
        goto loser;
    }
    if (SECITEM_CompareItem(&signValue.value, &signature) != 0) {
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
        rv = SECFailure;
    }

loser:
    PORT_Memset(signData, 0, sizeof signData);
    if (signValue.param) {
        nsspkcs5_DestroyPBEParameter(signValue.param);
    }
    if (signValue.arena) {
        PORT_FreeArena(signValue.arena, PR_TRUE);
    }
    return rv;
}

/*
 * Use our key to create a signText block the plain text of an
 * attribute. The signText is a PKCS 5 v2 pbe.
 */
SECStatus
sftkdb_SignAttribute(PLArenaPool *arena, SFTKDBHandle *keyDB, SDB *db,
                     SECItem *passKey, int iterationCount,
                     CK_OBJECT_HANDLE objectID,
                     CK_ATTRIBUTE_TYPE attrType,
                     SECItem *plainText, SECItem **signature)
{
    SECStatus rv;
    sftkCipherValue signValue;
    NSSPKCS5PBEParameter *param = NULL;
    unsigned char saltData[HASH_LENGTH_MAX];
    unsigned char signData[HASH_LENGTH_MAX];
    SECOidTag hmacAlg = SEC_OID_HMAC_SHA256; /* hash for authentication */
    SECOidTag prfAlg = SEC_OID_HMAC_SHA256;  /* hash for pb key generation */
    HASH_HashType prfType;
    unsigned int hmacLength;
    unsigned int prfLength;

    /* this code allows us to fetch the lengths and hashes on the fly
     * by simply changing the OID above */
    prfType = HASH_FromHMACOid(prfAlg);
    PORT_Assert(prfType != HASH_AlgNULL);
    prfLength = HASH_GetRawHashObject(prfType)->length;
    PORT_Assert(prfLength <= HASH_LENGTH_MAX);

    hmacLength = HASH_GetRawHashObject(HASH_FromHMACOid(hmacAlg))->length;
    PORT_Assert(hmacLength <= HASH_LENGTH_MAX);

    /* initialize our CipherValue structure */
    signValue.alg = SEC_OID_PKCS5_PBMAC1;
    signValue.salt.len = prfLength;
    signValue.salt.data = saltData;
    signValue.value.data = signData;
    signValue.value.len = hmacLength;
    RNG_GenerateGlobalRandomBytes(saltData, prfLength);

    /* initialize our pkcs5 parameter */
    param = nsspkcs5_NewParam(signValue.alg, HASH_AlgSHA1, &signValue.salt,
                              iterationCount);
    if (param == NULL) {
        rv = SECFailure;
        goto loser;
    }
    param->keyID = pbeBitGenIntegrityKey;
    /* set the PKCS 5 v2 parameters, not extractable from the
     * data passed into nsspkcs5_NewParam */
    param->encAlg = hmacAlg;
    param->hashType = prfType;
    param->keyLen = hmacLength;
    rv = SECOID_SetAlgorithmID(param->poolp, &param->prfAlg, prfAlg, NULL);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* calculate the mac */
    rv = sftkdb_pbehash(signValue.alg, passKey, param, objectID, attrType,
                        plainText, &signValue.value);
    if (rv != SECSuccess) {
        goto loser;
    }
    signValue.param = param;

    /* write it out */
    rv = sftkdb_encodeCipherText(arena, &signValue, signature);
    if (rv != SECSuccess) {
        goto loser;
    }

loser:
    PORT_Memset(signData, 0, sizeof signData);
    if (param) {
        nsspkcs5_DestroyPBEParameter(param);
    }
    return rv;
}

/*
 * safely swith the passed in key for the one caches in the keydb handle
 *
 * A key attached to the handle tells us the the token is logged in.
 * We can used the key attached to the handle in sftkdb_EncryptAttribute
 *  and sftkdb_DecryptAttribute calls.
 */
static void
sftkdb_switchKeys(SFTKDBHandle *keydb, SECItem *passKey, int iterationCount)
{
    unsigned char *data;
    int len;

    if (keydb->passwordLock == NULL) {
        PORT_Assert(keydb->type != SFTK_KEYDB_TYPE);
        return;
    }

    /* an atomic pointer set would be nice */
    SKIP_AFTER_FORK(PZ_Lock(keydb->passwordLock));
    data = keydb->passwordKey.data;
    len = keydb->passwordKey.len;
    keydb->passwordKey.data = passKey->data;
    keydb->passwordKey.len = passKey->len;
    keydb->defaultIterationCount = iterationCount;
    passKey->data = data;
    passKey->len = len;
    SKIP_AFTER_FORK(PZ_Unlock(keydb->passwordLock));
}

/*
 * returns true if we are in a middle of a merge style update.
 */
PRBool
sftkdb_InUpdateMerge(SFTKDBHandle *keydb)
{
    return keydb->updateID ? PR_TRUE : PR_FALSE;
}

/*
 * returns true if we are looking for the password for the user's old source
 * database as part of a merge style update.
 */
PRBool
sftkdb_NeedUpdateDBPassword(SFTKDBHandle *keydb)
{
    if (!sftkdb_InUpdateMerge(keydb)) {
        return PR_FALSE;
    }
    if (keydb->updateDBIsInit && !keydb->updatePasswordKey) {
        return PR_TRUE;
    }
    return PR_FALSE;
}

/*
 * fetch an update password key from a handle.
 */
SECItem *
sftkdb_GetUpdatePasswordKey(SFTKDBHandle *handle)
{
    SECItem *key = NULL;

    /* if we're a cert db, fetch it from our peer key db */
    if (handle->type == SFTK_CERTDB_TYPE) {
        handle = handle->peerDB;
    }

    /* don't have one */
    if (!handle) {
        return NULL;
    }

    PZ_Lock(handle->passwordLock);
    if (handle->updatePasswordKey) {
        key = SECITEM_DupItem(handle->updatePasswordKey);
    }
    PZ_Unlock(handle->passwordLock);

    return key;
}

/*
 * free the update password key from a handle.
 */
void
sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *handle)
{
    SECItem *key = NULL;

    /* don't have one */
    if (!handle) {
        return;
    }

    /* if we're a cert db, we don't have one */
    if (handle->type == SFTK_CERTDB_TYPE) {
        return;
    }

    PZ_Lock(handle->passwordLock);
    if (handle->updatePasswordKey) {
        key = handle->updatePasswordKey;
        handle->updatePasswordKey = NULL;
    }
    PZ_Unlock(handle->passwordLock);

    if (key) {
        SECITEM_ZfreeItem(key, PR_TRUE);
    }

    return;
}

/*
 * what password db we use depends heavily on the update state machine
 *
 *  1) no update db, return the normal database.
 *  2) update db and no merge return the update db.
 *  3) update db and in merge:
 *      return the update db if we need the update db's password,
 *      otherwise return our normal datbase.
 */
static SDB *
sftk_getPWSDB(SFTKDBHandle *keydb)
{
    if (!keydb->update) {
        return keydb->db;
    }
    if (!sftkdb_InUpdateMerge(keydb)) {
        return keydb->update;
    }
    if (sftkdb_NeedUpdateDBPassword(keydb)) {
        return keydb->update;
    }
    return keydb->db;
}

/*
 * return success if we have a valid password entry.
 * This is will show up outside of PKCS #11 as CKF_USER_PIN_INIT
 * in the token flags.
 */
SECStatus
sftkdb_HasPasswordSet(SFTKDBHandle *keydb)
{
    SECItem salt, value;
    unsigned char saltData[SDB_MAX_META_DATA_LEN];
    unsigned char valueData[SDB_MAX_META_DATA_LEN];
    CK_RV crv;
    SDB *db;

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

    db = sftk_getPWSDB(keydb);
    if (db == NULL) {
        return SECFailure;
    }

    salt.data = saltData;
    salt.len = sizeof(saltData);
    value.data = valueData;
    value.len = sizeof(valueData);
    crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value);

    /* If no password is set, we can update right away */
    if (((keydb->db->sdb_flags & SDB_RDONLY) == 0) && keydb->update && crv != CKR_OK) {
        /* update the peer certdb if it exists */
        if (keydb->peerDB) {
            sftkdb_Update(keydb->peerDB, NULL);
        }
        sftkdb_Update(keydb, NULL);
    }
    return (crv == CKR_OK) ? SECSuccess : SECFailure;
}

/* pull out the common final part of checking a password */
SECStatus
sftkdb_finishPasswordCheck(SFTKDBHandle *keydb, SECItem *key,
                           const char *pw, SECItem *value,
                           PRBool *tokenRemoved);

/*
 * check to see if we have the NULL password set.
 * We special case the NULL password so that if you have no password set, you
 * don't do thousands of hash rounds. This allows us to startup and get
 * webpages without slowdown in normal mode.
 */
SECStatus
sftkdb_CheckPasswordNull(SFTKDBHandle *keydb, PRBool *tokenRemoved)
{
    /* just like sftkdb_CheckPassowd, we get the salt and value, and
     * create a dbkey */
    SECStatus rv;
    SECItem salt, value;
    unsigned char saltData[SDB_MAX_META_DATA_LEN];
    unsigned char valueData[SDB_MAX_META_DATA_LEN];
    SECItem key;
    SDB *db;
    CK_RV crv;
    sftkCipherValue cipherValue;

    cipherValue.param = NULL;
    cipherValue.arena = NULL;

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

    db = sftk_getPWSDB(keydb);
    if (db == NULL) {
        return SECFailure;
    }

    key.data = NULL;
    key.len = 0;

    /* get the entry from the database */
    salt.data = saltData;
    salt.len = sizeof(saltData);
    value.data = valueData;
    value.len = sizeof(valueData);
    crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value);
    if (crv != CKR_OK) {
        rv = SECFailure;
        goto done;
    }

    /* get our intermediate key based on the entry salt value */
    rv = sftkdb_passwordToKey(keydb, &salt, "", &key);
    if (rv != SECSuccess) {
        goto done;
    }

    /* First get the cipher type */
    rv = sftkdb_decodeCipherText(&value, &cipherValue);
    if (rv != SECSuccess) {
        goto done;
    }

    if (cipherValue.param->iter != 1) {
        rv = SECFailure;
        goto done;
    }

    rv = sftkdb_finishPasswordCheck(keydb, &key, "", &value, tokenRemoved);

done:
    if (key.data) {
        PORT_ZFree(key.data, key.len);
    }
    if (cipherValue.param) {
        nsspkcs5_DestroyPBEParameter(cipherValue.param);
    }
    if (cipherValue.arena) {
        PORT_FreeArena(cipherValue.arena, PR_FALSE);
    }
    return rv;
}

#define SFTK_PW_CHECK_STRING "password-check"
#define SFTK_PW_CHECK_LEN 14

/*
 * check if the supplied password is valid
 */
SECStatus
sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved)
{
    SECStatus rv;
    SECItem salt, value;
    unsigned char saltData[SDB_MAX_META_DATA_LEN];
    unsigned char valueData[SDB_MAX_META_DATA_LEN];
    SECItem key;
    SDB *db;
    CK_RV crv;

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

    db = sftk_getPWSDB(keydb);
    if (db == NULL) {
        return SECFailure;
    }

    key.data = NULL;
    key.len = 0;

    if (pw == NULL)
        pw = "";

    /* get the entry from the database */
    salt.data = saltData;
    salt.len = sizeof(saltData);
    value.data = valueData;
    value.len = sizeof(valueData);
    crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value);
    if (crv != CKR_OK) {
        rv = SECFailure;
        goto done;
    }

    /* get our intermediate key based on the entry salt value */
    rv = sftkdb_passwordToKey(keydb, &salt, pw, &key);
    if (rv != SECSuccess) {
        goto done;
    }

    rv = sftkdb_finishPasswordCheck(keydb, &key, pw, &value, tokenRemoved);

done:
    if (key.data) {
        PORT_ZFree(key.data, key.len);
    }
    return rv;
}

/* we need to pass iterationCount in case we are updating a new database
 * and from an old one. */
SECStatus
sftkdb_finishPasswordCheck(SFTKDBHandle *keydb, SECItem *key, const char *pw,
                           SECItem *value, PRBool *tokenRemoved)
{
    SECItem *result = NULL;
    SECStatus rv;
    int iterationCount = getPBEIterationCount();

    if (*pw == 0) {
        iterationCount = 1;
    } else if (keydb->usesLegacyStorage && !sftk_isLegacyIterationCountAllowed()) {
        iterationCount = 1;
    }

    /* decrypt the entry value */
    rv = sftkdb_DecryptAttribute(keydb, key, CK_INVALID_HANDLE,
                                 CKT_INVALID_TYPE, value, &result);
    if (rv != SECSuccess) {
        goto done;
    }

    /* if it's what we expect, update our key in the database handle and
     * return Success */
    if ((result->len == SFTK_PW_CHECK_LEN) &&
        PORT_Memcmp(result->data, SFTK_PW_CHECK_STRING, SFTK_PW_CHECK_LEN) == 0) {
        /*
         * We have a password, now lets handle any potential update cases..
         *
         * First, the normal case: no update. In this case we only need the
         *  the password for our only DB, which we now have, we switch
         *  the keys and fall through.
         * Second regular (non-merge) update: The target DB does not yet have
         *  a password initialized, we now have the password for the source DB,
         *  so we can switch the keys and simply update the target database.
         * Merge update case: This one is trickier.
         *   1) If we need the source DB password, then we just got it here.
         *       We need to save that password,
         *       then we need to check to see if we need or have the target
         *         database password.
         *       If we have it (it's the same as the source), or don't need
         *         it (it's not set or is ""), we can start the update now.
         *       If we don't have it, we need the application to get it from
         *         the user. Clear our sessions out to simulate a token
         *         removal. C_GetTokenInfo will change the token description
         *         and the token will still appear to be logged out.
         *   2) If we already have the source DB  password, this password is
         *         for the target database. We can now move forward with the
         *         update, as we now have both required passwords.
         *
         */
        PZ_Lock(keydb->passwordLock);
        if (sftkdb_NeedUpdateDBPassword(keydb)) {
            /* Squirrel this special key away.
             * This has the side effect of turning sftkdb_NeedLegacyPW off,
             * as well as changing which database is returned from
             * SFTK_GET_PW_DB (thus effecting both sftkdb_CheckPassword()
             * and sftkdb_HasPasswordSet()) */
            keydb->updatePasswordKey = SECITEM_DupItem(key);
            PZ_Unlock(keydb->passwordLock);
            if (keydb->updatePasswordKey == NULL) {
                /* PORT_Error set by SECITEM_DupItem */
                rv = SECFailure;
                goto done;
            }

            /* Simulate a token removal -- we need to do this any
             * any case at this point so the token name is correct. */
            *tokenRemoved = PR_TRUE;

            /*
             * OK, we got the update DB password, see if we need a password
             * for the target...
             */
            if (sftkdb_HasPasswordSet(keydb) == SECSuccess) {
                /* We have a password, do we know what the password is?
                 *  check 1) for the password the user supplied for the
                 *           update DB,
                 *    and 2) for the null password.
                 *
                 * RECURSION NOTE: we are calling ourselves here. This means
                 *  any updates, switchKeys, etc will have been completed
                 *  if these functions return successfully, in those cases
                 *  just exit returning Success. We don't recurse infinitely
                 *  because we are making this call from a NeedUpdateDBPassword
                 *  block and we've already set that update password at this
                 *  point.  */
                rv = sftkdb_CheckPassword(keydb, pw, tokenRemoved);
                if (rv == SECSuccess) {
                    /* source and target databases have the same password, we
                     * are good to go */
                    goto done;
                }
                sftkdb_CheckPasswordNull(keydb, tokenRemoved);

                /*
                 * Important 'NULL' code here. At this point either we
                 * succeeded in logging in with "" or we didn't.
                 *
                 *  If we did succeed at login, our machine state will be set
                 * to logged in appropriately. The application will find that
                 * it's logged in as soon as it opens a new session. We have
                 * also completed the update. Life is good.
                 *
                 *  If we did not succeed, well the user still successfully
                 * logged into the update database, since we faked the token
                 * removal it's just like the user logged into his smart card
                 * then removed it. the actual login work, so we report that
                 * success back to the user, but we won't actually be
                 * logged in. The application will find this out when it
                 * checks it's login state, thus triggering another password
                 * prompt so we can get the real target DB password.
                 *
                 * summary, we exit from here with SECSuccess no matter what.
                 */
                rv = SECSuccess;
                goto done;
            } else {
                /* there is no password, just fall through to update.
                 * update will write the source DB's password record
                 * into the target DB just like it would in a non-merge
                 * update case. */
            }
        } else {
            PZ_Unlock(keydb->passwordLock);
        }
        /* load the keys, so the keydb can parse it's key set */
        sftkdb_switchKeys(keydb, key, iterationCount);

        /* we need to update, do it now */
        if (((keydb->db->sdb_flags & SDB_RDONLY) == 0) && keydb->update) {
            /* update the peer certdb if it exists */
            if (keydb->peerDB) {
                sftkdb_Update(keydb->peerDB, key);
            }
            sftkdb_Update(keydb, key);
        }
    } else {
        rv = SECFailure;
        /*PORT_SetError( bad password); */
    }

done:
    if (result) {
        SECITEM_ZfreeItem(result, PR_TRUE);
    }
    return rv;
}

/*
 * return Success if the there is a cached password key.
 */
SECStatus
sftkdb_PWCached(SFTKDBHandle *keydb)
{
    return keydb->passwordKey.data ? SECSuccess : SECFailure;
}

static CK_RV
sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle,
                CK_OBJECT_HANDLE id, SECItem *newKey, int iterationCount)
{
    SFTKDBHandle *keyHandle = handle;
    SDB *keyTarget = NULL;
    if (handle->type != SFTK_KEYDB_TYPE) {
        keyHandle = handle->peerDB;
    }
    if (keyHandle == NULL) {
        return CKR_OK;
    }
    // Old DBs don't have metadata, so we can return early here.
    keyTarget = SFTK_GET_SDB(keyHandle);
    if ((keyTarget->sdb_flags & SDB_HAS_META) == 0) {
        return CKR_OK;
    }

    id &= SFTK_OBJ_ID_MASK;

    CK_ATTRIBUTE_TYPE authAttrTypes[] = {
        CKA_MODULUS,
        CKA_PUBLIC_EXPONENT,
        CKA_CERT_SHA1_HASH,
        CKA_CERT_MD5_HASH,
        CKA_TRUST_SERVER_AUTH,
        CKA_TRUST_CLIENT_AUTH,
        CKA_TRUST_EMAIL_PROTECTION,
        CKA_TRUST_CODE_SIGNING,
        CKA_TRUST_STEP_UP_APPROVED,
        CKA_NSS_OVERRIDE_EXTENSIONS,
    };
    const CK_ULONG authAttrTypeCount = sizeof(authAttrTypes) / sizeof(authAttrTypes[0]);

    // We don't know what attributes this object has, so we update them one at a
    // time.
    unsigned int i;
    for (i = 0; i < authAttrTypeCount; i++) {
        CK_ATTRIBUTE authAttr = { authAttrTypes[i], NULL, 0 };
        CK_RV rv = sftkdb_GetAttributeValue(handle, id, &authAttr, 1);
        if (rv != CKR_OK) {
            continue;
        }
        if ((authAttr.ulValueLen == -1) || (authAttr.ulValueLen == 0)) {
            continue;
        }
        authAttr.pValue = PORT_ArenaAlloc(arena, authAttr.ulValueLen);
        if (authAttr.pValue == NULL) {
            return CKR_HOST_MEMORY;
        }
        rv = sftkdb_GetAttributeValue(handle, id, &authAttr, 1);
        if (rv != CKR_OK) {
            return rv;
        }
        if ((authAttr.ulValueLen == -1) || (authAttr.ulValueLen == 0)) {
            return CKR_GENERAL_ERROR;
        }
        // GetAttributeValue just verified the old macs, so it is safe to write
        // them out now.
        if (authAttr.ulValueLen == sizeof(CK_ULONG) &&
            sftkdb_isULONGAttribute(authAttr.type)) {
            CK_ULONG value = *(CK_ULONG *)authAttr.pValue;
            sftk_ULong2SDBULong(authAttr.pValue, value);
            authAttr.ulValueLen = SDB_ULONG_SIZE;
        }
        SECItem *signText;
        SECItem plainText;
        plainText.data = authAttr.pValue;
        plainText.len = authAttr.ulValueLen;
        if (sftkdb_SignAttribute(arena, handle, keyTarget, newKey,
                                 iterationCount, id, authAttr.type,
                                 &plainText, &signText) != SECSuccess) {
            return CKR_GENERAL_ERROR;
        }
        if (sftkdb_PutAttributeSignature(handle, keyTarget, id, authAttr.type,
                                         signText) != SECSuccess) {
            return CKR_GENERAL_ERROR;
        }
    }

    return CKR_OK;
}

static CK_RV
sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb,
                     CK_OBJECT_HANDLE id, SECItem *newKey, int iterationCount)
{
    CK_ATTRIBUTE_TYPE privAttrTypes[] = {
        CKA_VALUE,
        CKA_PRIVATE_EXPONENT,
        CKA_PRIME_1,
        CKA_PRIME_2,
        CKA_EXPONENT_1,
        CKA_EXPONENT_2,
        CKA_COEFFICIENT,
    };
    const CK_ULONG privAttrCount = sizeof(privAttrTypes) / sizeof(privAttrTypes[0]);

    // We don't know what attributes this object has, so we update them one at a
    // time.
    unsigned int i;
    for (i = 0; i < privAttrCount; i++) {
        // Read the old attribute in the clear.
        CK_OBJECT_HANDLE sdbId = id & SFTK_OBJ_ID_MASK;
        CK_ATTRIBUTE privAttr = { privAttrTypes[i], NULL, 0 };
        CK_RV crv = sftkdb_GetAttributeValue(keydb, id, &privAttr, 1);
        if (crv != CKR_OK) {
            continue;
        }
        if ((privAttr.ulValueLen == -1) || (privAttr.ulValueLen == 0)) {
            continue;
        }
        privAttr.pValue = PORT_ArenaAlloc(arena, privAttr.ulValueLen);
        if (privAttr.pValue == NULL) {
            return CKR_HOST_MEMORY;
        }
        crv = sftkdb_GetAttributeValue(keydb, id, &privAttr, 1);
        if (crv != CKR_OK) {
            return crv;
        }
        if ((privAttr.ulValueLen == -1) || (privAttr.ulValueLen == 0)) {
            return CKR_GENERAL_ERROR;
        }
        SECItem plainText;
        SECItem *result;
        plainText.data = privAttr.pValue;
        plainText.len = privAttr.ulValueLen;
        if (sftkdb_EncryptAttribute(arena, keydb, keydb->db, newKey,
                                    iterationCount, sdbId, privAttr.type,
                                    &plainText, &result) != SECSuccess) {
            return CKR_GENERAL_ERROR;
        }
        privAttr.pValue = result->data;
        privAttr.ulValueLen = result->len;
        // Clear sensitive data.
        PORT_Memset(plainText.data, 0, plainText.len);

        // Write the newly encrypted attributes out directly.
        keydb->newKey = newKey;
        keydb->newDefaultIterationCount = iterationCount;
        crv = (*keydb->db->sdb_SetAttributeValue)(keydb->db, sdbId, &privAttr, 1);
        keydb->newKey = NULL;
        if (crv != CKR_OK) {
            return crv;
        }
    }

    return CKR_OK;
}

static CK_RV
sftk_convertAttributes(SFTKDBHandle *handle, CK_OBJECT_HANDLE id,
                       SECItem *newKey, int iterationCount)
{
    CK_RV crv = CKR_OK;
    PLArenaPool *arena = NULL;

    /* get a new arena to simplify cleanup */
    arena = PORT_NewArena(1024);
    if (!arena) {
        return CKR_HOST_MEMORY;
    }

    /*
     * first handle the MACS
     */
    crv = sftk_updateMacs(arena, handle, id, newKey, iterationCount);
    if (crv != CKR_OK) {
        goto loser;
    }

    if (handle->type == SFTK_KEYDB_TYPE) {
        crv = sftk_updateEncrypted(arena, handle, id, newKey,
                                   iterationCount);
        if (crv != CKR_OK) {
            goto loser;
        }
    }

    /* free up our mess */
    PORT_FreeArena(arena, PR_TRUE);
    return CKR_OK;

loser:
    /* there may be unencrypted data, clear it out down */
    PORT_FreeArena(arena, PR_TRUE);
    return crv;
}

/*
 * must be called with the old key active.
 */
CK_RV
sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template,
                      CK_ULONG count, SECItem *newKey, int iterationCount)
{
    SDBFind *find = NULL;
    CK_ULONG idCount = SFTK_MAX_IDS;
    CK_OBJECT_HANDLE ids[SFTK_MAX_IDS];
    CK_RV crv, crv2;
    unsigned int i;

    crv = sftkdb_FindObjectsInit(handle, template, count, &find);

    if (crv != CKR_OK) {
        return crv;
    }
    while ((crv == CKR_OK) && (idCount == SFTK_MAX_IDS)) {
        crv = sftkdb_FindObjects(handle, find, ids, SFTK_MAX_IDS, &idCount);
        for (i = 0; (crv == CKR_OK) && (i < idCount); i++) {
            crv = sftk_convertAttributes(handle, ids[i], newKey,
                                         iterationCount);
        }
    }
    crv2 = sftkdb_FindObjectsFinal(handle, find);
    if (crv == CKR_OK)
        crv = crv2;

    return crv;
}

/*
 * change the database password.
 */
SECStatus
sftkdb_ChangePassword(SFTKDBHandle *keydb,
                      char *oldPin, char *newPin, PRBool *tokenRemoved)
{
    SECStatus rv = SECSuccess;
    SECItem plainText;
    SECItem newKey;
    SECItem *result = NULL;
    SECItem salt, value;
    SFTKDBHandle *certdb;
    unsigned char saltData[SDB_MAX_META_DATA_LEN];
    unsigned char valueData[SDB_MAX_META_DATA_LEN];
    int iterationCount = getPBEIterationCount();
    CK_RV crv;
    SDB *db;

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

    db = SFTK_GET_SDB(keydb);
    if (db == NULL) {
        return SECFailure;
    }

    newKey.data = NULL;

    /* make sure we have a valid old pin */
    crv = (*keydb->db->sdb_Begin)(keydb->db);
    if (crv != CKR_OK) {
        rv = SECFailure;
        goto loser;
    }
    salt.data = saltData;
    salt.len = sizeof(saltData);
    value.data = valueData;
    value.len = sizeof(valueData);
    crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value);
    if (crv == CKR_OK) {
        rv = sftkdb_CheckPassword(keydb, oldPin, tokenRemoved);
        if (rv == SECFailure) {
            goto loser;
        }
    } else {
        salt.len = SHA1_LENGTH;
        RNG_GenerateGlobalRandomBytes(salt.data, salt.len);
    }

    if (newPin && *newPin == 0) {
        iterationCount = 1;
    } else if (keydb->usesLegacyStorage && !sftk_isLegacyIterationCountAllowed()) {
        iterationCount = 1;
    }

    rv = sftkdb_passwordToKey(keydb, &salt, newPin, &newKey);
    if (rv != SECSuccess) {
        goto loser;
    }

    /*
     * convert encrypted entries here.
     */
    crv = sftkdb_convertObjects(keydb, NULL, 0, &newKey, iterationCount);
    if (crv != CKR_OK) {
        rv = SECFailure;
        goto loser;
    }
    /* fix up certdb macs */
    certdb = keydb->peerDB;
    if (certdb) {
        CK_ATTRIBUTE objectType = { CKA_CLASS, 0, sizeof(CK_OBJECT_CLASS) };
        CK_OBJECT_CLASS myClass = CKO_NSS_TRUST;

        objectType.pValue = &myClass;
        crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey,
                                    iterationCount);
        if (crv != CKR_OK) {
            rv = SECFailure;
            goto loser;
        }
        myClass = CKO_PUBLIC_KEY;
        crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey,
                                    iterationCount);
        if (crv != CKR_OK) {
            rv = SECFailure;
            goto loser;
        }
    }

    plainText.data = (unsigned char *)SFTK_PW_CHECK_STRING;
    plainText.len = SFTK_PW_CHECK_LEN;

    rv = sftkdb_EncryptAttribute(NULL, keydb, keydb->db, &newKey,
                                 iterationCount, CK_INVALID_HANDLE,
                                 CKT_INVALID_TYPE, &plainText, &result);
    if (rv != SECSuccess) {
        goto loser;
    }
    value.data = result->data;
    value.len = result->len;
    crv = (*keydb->db->sdb_PutMetaData)(keydb->db, "password", &salt, &value);
    if (crv != CKR_OK) {
        rv = SECFailure;
        goto loser;
    }
    crv = (*keydb->db->sdb_Commit)(keydb->db);
    if (crv != CKR_OK) {
        rv = SECFailure;
        goto loser;
    }

    keydb->newKey = NULL;

    sftkdb_switchKeys(keydb, &newKey, iterationCount);

loser:
    if (newKey.data) {
        PORT_ZFree(newKey.data, newKey.len);
    }
    if (result) {
        SECITEM_FreeItem(result, PR_TRUE);
    }
    if (rv != SECSuccess) {
        (*keydb->db->sdb_Abort)(keydb->db);
    }

    return rv;
}

/*
 * lose our cached password
 */
SECStatus
sftkdb_ClearPassword(SFTKDBHandle *keydb)
{
    SECItem oldKey;
    oldKey.data = NULL;
    oldKey.len = 0;
    sftkdb_switchKeys(keydb, &oldKey, 1);
    if (oldKey.data) {
        PORT_ZFree(oldKey.data, oldKey.len);
    }
    return SECSuccess;
}
