/* 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 "secitem.h"
#include "pkcs11.h"
#include "lgdb.h"
#include "pcert.h"
#include "lowkeyi.h"
#include "blapi.h"
#include "secder.h"
#include "secasn1.h"

#include "keydbi.h"

/*
 * ******************** Object Creation Utilities ***************************
 */

/*
 * check the consistancy and initialize a Certificate Object
 */
static CK_RV
lg_createCertObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
                    const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    SECItem derCert;
    NSSLOWCERTCertificate *cert;
    NSSLOWCERTCertTrust *trust = NULL;
    NSSLOWCERTCertTrust userTrust = { CERTDB_USER, CERTDB_USER, CERTDB_USER };
    NSSLOWCERTCertTrust defTrust = { CERTDB_TRUSTED_UNKNOWN,
                                     CERTDB_TRUSTED_UNKNOWN, CERTDB_TRUSTED_UNKNOWN };
    char *label = NULL;
    char *email = NULL;
    SECStatus rv;
    CK_RV crv;
    PRBool inDB = PR_TRUE;
    NSSLOWCERTCertDBHandle *certHandle = lg_getCertDB(sdb);
    NSSLOWKEYDBHandle *keyHandle = NULL;
    CK_CERTIFICATE_TYPE type;
    const CK_ATTRIBUTE *attribute;

    /* we can't store any certs private */
    if (lg_isTrue(CKA_PRIVATE, templ, count)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    /* We only support X.509 Certs for now */
    crv = lg_GetULongAttribute(CKA_CERTIFICATE_TYPE, templ, count, &type);
    if (crv != CKR_OK) {
        return crv;
    }

    if (type != CKC_X_509) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    /* X.509 Certificate */

    if (certHandle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    /* get the der cert */
    attribute = lg_FindAttribute(CKA_VALUE, templ, count);
    if (!attribute) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    derCert.type = 0;
    derCert.data = (unsigned char *)attribute->pValue;
    derCert.len = attribute->ulValueLen;

    label = lg_getString(CKA_LABEL, templ, count);

    cert = nsslowcert_FindCertByDERCert(certHandle, &derCert);
    if (cert == NULL) {
        cert = nsslowcert_DecodeDERCertificate(&derCert, label);
        inDB = PR_FALSE;
    }
    if (cert == NULL) {
        if (label)
            PORT_Free(label);
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    keyHandle = lg_getKeyDB(sdb);
    if (keyHandle) {
        if (nsslowkey_KeyForCertExists(keyHandle, cert)) {
            trust = &userTrust;
        }
    }

    if (!inDB) {
        if (!trust)
            trust = &defTrust;
        rv = nsslowcert_AddPermCert(certHandle, cert, label, trust);
    } else {
        rv = trust ? nsslowcert_ChangeCertTrust(certHandle, cert, trust) : SECSuccess;
    }

    if (label)
        PORT_Free(label);

    if (rv != SECSuccess) {
        nsslowcert_DestroyCertificate(cert);
        return CKR_DEVICE_ERROR;
    }

    /*
     * Add a NULL S/MIME profile if necessary.
     */
    email = lg_getString(CKA_NSS_EMAIL, templ, count);
    if (email) {
        certDBEntrySMime *entry;

        entry = nsslowcert_ReadDBSMimeEntry(certHandle, email);
        if (!entry) {
            nsslowcert_SaveSMimeProfile(certHandle, email,
                                        &cert->derSubject, NULL, NULL);
        } else {
            nsslowcert_DestroyDBEntry((certDBEntry *)entry);
        }
        PORT_Free(email);
    }
    *handle = lg_mkHandle(sdb, &cert->certKey, LG_TOKEN_TYPE_CERT);
    nsslowcert_DestroyCertificate(cert);

    return CKR_OK;
}

unsigned int
lg_MapTrust(CK_TRUST trust, PRBool clientAuth)
{
    unsigned int trustCA = clientAuth ? CERTDB_TRUSTED_CLIENT_CA : CERTDB_TRUSTED_CA;
    switch (trust) {
        case CKT_NSS_TRUSTED:
            return CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
        case CKT_NSS_TRUSTED_DELEGATOR:
            return CERTDB_VALID_CA | trustCA;
        case CKT_NSS_MUST_VERIFY_TRUST:
            return CERTDB_MUST_VERIFY;
        case CKT_NSS_NOT_TRUSTED:
            return CERTDB_TERMINAL_RECORD;
        case CKT_NSS_VALID_DELEGATOR: /* implies must verify */
            return CERTDB_VALID_CA;
        default:
            break;
    }
    return CERTDB_TRUSTED_UNKNOWN;
}

/*
 * check the consistancy and initialize a Trust Object
 */
static CK_RV
lg_createTrustObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
                     const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    const CK_ATTRIBUTE *issuer = NULL;
    const CK_ATTRIBUTE *serial = NULL;
    NSSLOWCERTCertificate *cert = NULL;
    const CK_ATTRIBUTE *trust;
    CK_TRUST sslTrust = CKT_NSS_TRUST_UNKNOWN;
    CK_TRUST clientTrust = CKT_NSS_TRUST_UNKNOWN;
    CK_TRUST emailTrust = CKT_NSS_TRUST_UNKNOWN;
    CK_TRUST signTrust = CKT_NSS_TRUST_UNKNOWN;
    CK_BBOOL stepUp;
    NSSLOWCERTCertTrust dbTrust = { 0 };
    SECStatus rv;
    NSSLOWCERTCertDBHandle *certHandle = lg_getCertDB(sdb);
    NSSLOWCERTIssuerAndSN issuerSN;

    /* we can't store any certs private */
    if (lg_isTrue(CKA_PRIVATE, templ, count)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    if (certHandle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    issuer = lg_FindAttribute(CKA_ISSUER, templ, count);
    serial = lg_FindAttribute(CKA_SERIAL_NUMBER, templ, count);

    if (issuer && serial) {
        issuerSN.derIssuer.data = (unsigned char *)issuer->pValue;
        issuerSN.derIssuer.len = issuer->ulValueLen;

        issuerSN.serialNumber.data = (unsigned char *)serial->pValue;
        issuerSN.serialNumber.len = serial->ulValueLen;

        cert = nsslowcert_FindCertByIssuerAndSN(certHandle, &issuerSN);
    }

    if (cert == NULL) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    lg_GetULongAttribute(CKA_TRUST_SERVER_AUTH, templ, count, &sslTrust);
    lg_GetULongAttribute(CKA_TRUST_CLIENT_AUTH, templ, count, &clientTrust);
    lg_GetULongAttribute(CKA_TRUST_EMAIL_PROTECTION, templ, count, &emailTrust);
    lg_GetULongAttribute(CKA_TRUST_CODE_SIGNING, templ, count, &signTrust);
    stepUp = CK_FALSE;
    trust = lg_FindAttribute(CKA_TRUST_STEP_UP_APPROVED, templ, count);
    if (trust) {
        if (trust->ulValueLen == sizeof(CK_BBOOL)) {
            stepUp = *(CK_BBOOL *)trust->pValue;
        }
    }

    /* preserve certain old fields */
    if (cert->trust) {
        dbTrust.sslFlags = cert->trust->sslFlags & CERTDB_PRESERVE_TRUST_BITS;
        dbTrust.emailFlags =
            cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS;
        dbTrust.objectSigningFlags =
            cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS;
    }

    dbTrust.sslFlags |= lg_MapTrust(sslTrust, PR_FALSE);
    dbTrust.sslFlags |= lg_MapTrust(clientTrust, PR_TRUE);
    dbTrust.emailFlags |= lg_MapTrust(emailTrust, PR_FALSE);
    dbTrust.objectSigningFlags |= lg_MapTrust(signTrust, PR_FALSE);
    if (stepUp) {
        dbTrust.sslFlags |= CERTDB_GOVT_APPROVED_CA;
    }

    rv = nsslowcert_ChangeCertTrust(certHandle, cert, &dbTrust);
    *handle = lg_mkHandle(sdb, &cert->certKey, LG_TOKEN_TYPE_TRUST);
    nsslowcert_DestroyCertificate(cert);
    if (rv != SECSuccess) {
        return CKR_DEVICE_ERROR;
    }

    return CKR_OK;
}

/*
 * check the consistancy and initialize a Trust Object
 */
static CK_RV
lg_createSMimeObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
                     const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    SECItem derSubj, rawProfile, rawTime, emailKey;
    SECItem *pRawProfile = NULL;
    SECItem *pRawTime = NULL;
    char *email = NULL;
    const CK_ATTRIBUTE *subject = NULL,
                       *profile = NULL,
                       *time = NULL;
    SECStatus rv;
    NSSLOWCERTCertDBHandle *certHandle;
    CK_RV ck_rv = CKR_OK;

    /* we can't store any certs private */
    if (lg_isTrue(CKA_PRIVATE, templ, count)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    certHandle = lg_getCertDB(sdb);
    if (certHandle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    /* lookup SUBJECT */
    subject = lg_FindAttribute(CKA_SUBJECT, templ, count);
    PORT_Assert(subject);
    if (!subject) {
        ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }

    derSubj.data = (unsigned char *)subject->pValue;
    derSubj.len = subject->ulValueLen;
    derSubj.type = 0;

    /* lookup VALUE */
    profile = lg_FindAttribute(CKA_VALUE, templ, count);
    if (profile) {
        rawProfile.data = (unsigned char *)profile->pValue;
        rawProfile.len = profile->ulValueLen;
        rawProfile.type = siBuffer;
        pRawProfile = &rawProfile;
    }

    /* lookup Time */
    time = lg_FindAttribute(CKA_NSS_SMIME_TIMESTAMP, templ, count);
    if (time) {
        rawTime.data = (unsigned char *)time->pValue;
        rawTime.len = time->ulValueLen;
        rawTime.type = siBuffer;
        pRawTime = &rawTime;
    }

    email = lg_getString(CKA_NSS_EMAIL, templ, count);
    if (!email) {
        ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }

    /* Store S/MIME Profile by SUBJECT */
    rv = nsslowcert_SaveSMimeProfile(certHandle, email, &derSubj,
                                     pRawProfile, pRawTime);
    if (rv != SECSuccess) {
        ck_rv = CKR_DEVICE_ERROR;
        goto loser;
    }
    emailKey.data = (unsigned char *)email;
    emailKey.len = PORT_Strlen(email) + 1;

    *handle = lg_mkHandle(sdb, &emailKey, LG_TOKEN_TYPE_SMIME);

loser:
    if (email)
        PORT_Free(email);

    return ck_rv;
}

/*
 * check the consistancy and initialize a Trust Object
 */
static CK_RV
lg_createCrlObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
                   const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    PRBool isKRL = PR_FALSE;
    SECItem derSubj, derCrl;
    char *url = NULL;
    const CK_ATTRIBUTE *subject, *crl;
    SECStatus rv;
    NSSLOWCERTCertDBHandle *certHandle;

    certHandle = lg_getCertDB(sdb);

    /* we can't store any private crls */
    if (lg_isTrue(CKA_PRIVATE, templ, count)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    if (certHandle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    /* lookup SUBJECT */
    subject = lg_FindAttribute(CKA_SUBJECT, templ, count);
    if (!subject) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    derSubj.data = (unsigned char *)subject->pValue;
    derSubj.len = subject->ulValueLen;

    /* lookup VALUE */
    crl = lg_FindAttribute(CKA_VALUE, templ, count);
    PORT_Assert(crl);
    if (!crl) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }
    derCrl.data = (unsigned char *)crl->pValue;
    derCrl.len = crl->ulValueLen;

    url = lg_getString(CKA_NSS_URL, templ, count);
    isKRL = lg_isTrue(CKA_NSS_KRL, templ, count);

    /* Store CRL by SUBJECT */
    rv = nsslowcert_AddCrl(certHandle, &derCrl, &derSubj, url, isKRL);

    if (url) {
        PORT_Free(url);
    }
    if (rv != SECSuccess) {
        return CKR_DEVICE_ERROR;
    }

    /* if we overwrote the existing CRL, poison the handle entry so we get
     * a new object handle */
    (void)lg_poisonHandle(sdb, &derSubj,
                          isKRL ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL);
    *handle = lg_mkHandle(sdb, &derSubj,
                          isKRL ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL);

    return CKR_OK;
}

/*
 * check the consistancy and initialize a Public Key Object
 */
static CK_RV
lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
                         CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    CK_ATTRIBUTE_TYPE pubKeyAttr = CKA_VALUE;
    CK_RV crv = CKR_OK;
    NSSLOWKEYPrivateKey *priv;
    SECItem pubKeySpace = { siBuffer, NULL, 0 };
    SECItem *pubKey;
    SECItem pubKey2Space = { siBuffer, NULL, 0 };
    PLArenaPool *arena = NULL;
    NSSLOWKEYDBHandle *keyHandle = NULL;

    switch (key_type) {
        case CKK_RSA:
            pubKeyAttr = CKA_MODULUS;
            break;
        case CKK_EC:
            pubKeyAttr = CKA_EC_POINT;
            break;
        case CKK_DSA:
        case CKK_DH:
            break;
        default:
            return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    pubKey = &pubKeySpace;
    crv = lg_Attribute2SSecItem(NULL, pubKeyAttr, templ, count, pubKey);
    if (crv != CKR_OK)
        return crv;

    if (key_type == CKK_EC) {
        SECStatus rv;
        /*
         * for ECC, use the decoded key first.
         */
        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        if (arena == NULL) {
            crv = CKR_HOST_MEMORY;
            goto done;
        }
        rv = SEC_QuickDERDecodeItem(arena, &pubKey2Space,
                                    SEC_ASN1_GET(SEC_OctetStringTemplate),
                                    pubKey);
        if (rv != SECSuccess) {
            /* decode didn't work, just try the pubKey */
            PORT_FreeArena(arena, PR_FALSE);
            arena = NULL;
        } else {
            /* try the decoded pub key first */
            pubKey = &pubKey2Space;
        }
    }

    PORT_Assert(pubKey->data);
    if (pubKey->data == NULL) {
        crv = CKR_ATTRIBUTE_VALUE_INVALID;
        goto done;
    }
    keyHandle = lg_getKeyDB(sdb);
    if (keyHandle == NULL) {
        crv = CKR_TOKEN_WRITE_PROTECTED;
        goto done;
    }
    if (keyHandle->version != 3) {
        unsigned char buf[SHA1_LENGTH];
        SHA1_HashBuf(buf, pubKey->data, pubKey->len);
        PORT_Memcpy(pubKey->data, buf, sizeof(buf));
        pubKey->len = sizeof(buf);
    }
    /* make sure the associated private key already exists */
    /* only works if we are logged in */
    priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, sdb /*password*/);
    if (priv == NULL && pubKey == &pubKey2Space) {
        /* no match on the decoded key, match the original pubkey */
        pubKey = &pubKeySpace;
        priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey,
                                            sdb /*password*/);
    }
    if (priv == NULL) {
        /* the legacy database can only 'store' public keys which already
         * have their corresponding private keys in the database */
        crv = CKR_ATTRIBUTE_VALUE_INVALID;
        goto done;
    }
    lg_nsslowkey_DestroyPrivateKey(priv);
    crv = CKR_OK;

    *handle = lg_mkHandle(sdb, pubKey, LG_TOKEN_TYPE_PUB);

done:
    PORT_Free(pubKeySpace.data);
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return crv;
}

/* make a private key from a verified object */
static NSSLOWKEYPrivateKey *
lg_mkPrivKey(SDB *sdb, const CK_ATTRIBUTE *templ, CK_ULONG count,
             CK_KEY_TYPE key_type, CK_RV *crvp)
{
    NSSLOWKEYPrivateKey *privKey;
    PLArenaPool *arena;
    CK_RV crv = CKR_OK;
    SECStatus rv;

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

    privKey = (NSSLOWKEYPrivateKey *)
        PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPrivateKey));
    if (privKey == NULL) {
        PORT_FreeArena(arena, PR_FALSE);
        *crvp = CKR_HOST_MEMORY;
        return NULL;
    }

    /* in future this would be a switch on key_type */
    privKey->arena = arena;
    switch (key_type) {
        case CKK_RSA:
            privKey->keyType = NSSLOWKEYRSAKey;
            crv = lg_Attribute2SSecItem(arena, CKA_MODULUS, templ, count,
                                        &privKey->u.rsa.modulus);
            if (crv != CKR_OK)
                break;
            crv = lg_Attribute2SSecItem(arena, CKA_PUBLIC_EXPONENT, templ, count,
                                        &privKey->u.rsa.publicExponent);
            if (crv != CKR_OK)
                break;
            crv = lg_PrivAttr2SSecItem(arena, CKA_PRIVATE_EXPONENT, templ, count,
                                       &privKey->u.rsa.privateExponent, sdb);
            if (crv != CKR_OK)
                break;
            crv = lg_PrivAttr2SSecItem(arena, CKA_PRIME_1, templ, count,
                                       &privKey->u.rsa.prime1, sdb);
            if (crv != CKR_OK)
                break;
            crv = lg_PrivAttr2SSecItem(arena, CKA_PRIME_2, templ, count,
                                       &privKey->u.rsa.prime2, sdb);
            if (crv != CKR_OK)
                break;
            crv = lg_PrivAttr2SSecItem(arena, CKA_EXPONENT_1, templ, count,
                                       &privKey->u.rsa.exponent1, sdb);
            if (crv != CKR_OK)
                break;
            crv = lg_PrivAttr2SSecItem(arena, CKA_EXPONENT_2, templ, count,
                                       &privKey->u.rsa.exponent2, sdb);
            if (crv != CKR_OK)
                break;
            crv = lg_PrivAttr2SSecItem(arena, CKA_COEFFICIENT, templ, count,
                                       &privKey->u.rsa.coefficient, sdb);
            if (crv != CKR_OK)
                break;
            rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version,
                                 NSSLOWKEY_VERSION);
            if (rv != SECSuccess)
                crv = CKR_HOST_MEMORY;
            break;

        case CKK_DSA:
            privKey->keyType = NSSLOWKEYDSAKey;
            crv = lg_Attribute2SSecItem(arena, CKA_PRIME, templ, count,
                                        &privKey->u.dsa.params.prime);
            if (crv != CKR_OK)
                break;
            crv = lg_Attribute2SSecItem(arena, CKA_SUBPRIME, templ, count,
                                        &privKey->u.dsa.params.subPrime);
            if (crv != CKR_OK)
                break;
            crv = lg_Attribute2SSecItem(arena, CKA_BASE, templ, count,
                                        &privKey->u.dsa.params.base);
            if (crv != CKR_OK)
                break;
            crv = lg_PrivAttr2SSecItem(arena, CKA_VALUE, templ, count,
                                       &privKey->u.dsa.privateValue, sdb);
            if (crv != CKR_OK)
                break;
            if (lg_hasAttribute(CKA_NSS_DB, templ, count)) {
                crv = lg_Attribute2SSecItem(arena, CKA_NSS_DB, templ, count,
                                            &privKey->u.dsa.publicValue);
                /* privKey was zero'd so public value is already set to NULL, 0
                 * if we don't set it explicitly */
            }
            break;

        case CKK_DH:
            privKey->keyType = NSSLOWKEYDHKey;
            crv = lg_Attribute2SSecItem(arena, CKA_PRIME, templ, count,
                                        &privKey->u.dh.prime);
            if (crv != CKR_OK)
                break;
            crv = lg_Attribute2SSecItem(arena, CKA_BASE, templ, count,
                                        &privKey->u.dh.base);
            if (crv != CKR_OK)
                break;
            crv = lg_PrivAttr2SSecItem(arena, CKA_VALUE, templ, count,
                                       &privKey->u.dh.privateValue, sdb);
            if (crv != CKR_OK)
                break;
            if (lg_hasAttribute(CKA_NSS_DB, templ, count)) {
                crv = lg_Attribute2SSecItem(arena, CKA_NSS_DB, templ, count,
                                            &privKey->u.dh.publicValue);
                /* privKey was zero'd so public value is already set to NULL, 0
                 * if we don't set it explicitly */
            }
            break;

        case CKK_EC:
            privKey->keyType = NSSLOWKEYECKey;
            crv = lg_Attribute2SSecItem(arena, CKA_EC_PARAMS, templ, count,
                                        &privKey->u.ec.ecParams.DEREncoding);
            if (crv != CKR_OK)
                break;

            /* Fill out the rest of the ecParams structure
             * based on the encoded params
             */
            if (LGEC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding,
                                &privKey->u.ec.ecParams) != SECSuccess) {
                crv = CKR_DOMAIN_PARAMS_INVALID;
                break;
            }
            crv = lg_PrivAttr2SSecItem(arena, CKA_VALUE, templ, count,
                                       &privKey->u.ec.privateValue, sdb);
            if (crv != CKR_OK)
                break;
            if (lg_hasAttribute(CKA_NSS_DB, templ, count)) {
                crv = lg_Attribute2SSecItem(arena, CKA_NSS_DB, templ, count,
                                            &privKey->u.ec.publicValue);
                if (crv != CKR_OK)
                    break;
                /* privKey was zero'd so public value is already set to NULL, 0
                 * if we don't set it explicitly */
            }
            rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version,
                                 NSSLOWKEY_EC_PRIVATE_KEY_VERSION);
            if (rv != SECSuccess)
                crv = CKR_HOST_MEMORY;
            break;

        default:
            crv = CKR_KEY_TYPE_INCONSISTENT;
            break;
    }
    *crvp = crv;
    if (crv != CKR_OK) {
        PORT_FreeArena(arena, PR_FALSE);
        return NULL;
    }
    return privKey;
}

/*
 * check the consistancy and initialize a Private Key Object
 */
static CK_RV
lg_createPrivateKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
                          CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    NSSLOWKEYPrivateKey *privKey;
    char *label;
    SECStatus rv = SECSuccess;
    CK_RV crv = CKR_DEVICE_ERROR;
    SECItem pubKey;
    NSSLOWKEYDBHandle *keyHandle = lg_getKeyDB(sdb);

    if (keyHandle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    privKey = lg_mkPrivKey(sdb, templ, count, key_type, &crv);
    if (privKey == NULL)
        return crv;
    label = lg_getString(CKA_LABEL, templ, count);

    crv = lg_Attribute2SSecItem(NULL, CKA_NSS_DB, templ, count, &pubKey);
    if (crv != CKR_OK) {
        crv = CKR_TEMPLATE_INCOMPLETE;
        rv = SECFailure;
        goto fail;
    }
#ifdef notdef
    if (keyHandle->version != 3) {
        unsigned char buf[SHA1_LENGTH];
        SHA1_HashBuf(buf, pubKey.data, pubKey.len);
        PORT_Memcpy(pubKey.data, buf, sizeof(buf));
        pubKey.len = sizeof(buf);
    }
#endif
    /* get the key type */
    if (key_type == CKK_RSA) {
        rv = RSA_PrivateKeyCheck(&privKey->u.rsa);
        if (rv == SECFailure) {
            goto fail;
        }
    }
    rv = nsslowkey_StoreKeyByPublicKey(keyHandle, privKey, &pubKey,
                                       label, sdb /*->password*/);

fail:
    if (label)
        PORT_Free(label);
    *handle = lg_mkHandle(sdb, &pubKey, LG_TOKEN_TYPE_PRIV);
    if (pubKey.data)
        PORT_Free(pubKey.data);
    lg_nsslowkey_DestroyPrivateKey(privKey);
    if (rv != SECSuccess)
        return crv;

    return CKR_OK;
}

#define LG_KEY_MAX_RETRIES 10 /* don't hang if we are having problems with the rng */
#define LG_KEY_ID_SIZE 18     /* don't use either SHA1 or MD5 sizes */
/*
 * Secret keys must have a CKA_ID value to be stored in the database. This code
 * will generate one if there wasn't one already.
 */
static CK_RV
lg_GenerateSecretCKA_ID(NSSLOWKEYDBHandle *handle, SECItem *id, char *label)
{
    unsigned int retries;
    SECStatus rv = SECSuccess;
    CK_RV crv = CKR_OK;

    id->data = NULL;
    if (label) {
        id->data = (unsigned char *)PORT_Strdup(label);
        if (id->data == NULL) {
            return CKR_HOST_MEMORY;
        }
        id->len = PORT_Strlen(label) + 1;
        if (!nsslowkey_KeyForIDExists(handle, id)) {
            return CKR_OK;
        }
        PORT_Free(id->data);
        id->data = NULL;
        id->len = 0;
    }
    id->data = (unsigned char *)PORT_Alloc(LG_KEY_ID_SIZE);
    if (id->data == NULL) {
        return CKR_HOST_MEMORY;
    }
    id->len = LG_KEY_ID_SIZE;

    retries = 0;
    do {
        rv = RNG_GenerateGlobalRandomBytes(id->data, id->len);
    } while (rv == SECSuccess && nsslowkey_KeyForIDExists(handle, id) &&
             (++retries <= LG_KEY_MAX_RETRIES));

    if ((rv != SECSuccess) || (retries > LG_KEY_MAX_RETRIES)) {
        crv = CKR_DEVICE_ERROR; /* random number generator is bad */
        PORT_Free(id->data);
        id->data = NULL;
        id->len = 0;
    }
    return crv;
}

static NSSLOWKEYPrivateKey *
lg_mkSecretKeyRep(const CK_ATTRIBUTE *templ,
                  CK_ULONG count, CK_KEY_TYPE key_type,
                  SECItem *pubkey, SDB *sdbpw)
{
    NSSLOWKEYPrivateKey *privKey = 0;
    PLArenaPool *arena = 0;
    CK_KEY_TYPE keyType;
    PRUint32 keyTypeStorage;
    SECItem keyTypeItem;
    CK_RV crv;
    SECStatus rv;
    static unsigned char derZero[1] = { 0 };

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

    privKey = (NSSLOWKEYPrivateKey *)
        PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPrivateKey));
    if (privKey == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

    privKey->arena = arena;

    /* Secret keys are represented in the database as "fake" RSA keys.
     * The RSA key is marked as a secret key representation by setting the
     * public exponent field to 0, which is an invalid RSA exponent.
     * The other fields are set as follows:
     *   modulus - CKA_ID value for the secret key
     *   private exponent - CKA_VALUE (the key itself)
     *   coefficient - CKA_KEY_TYPE, which indicates what encryption algorithm
     *      is used for the key.
     *   all others - set to integer 0
     */
    privKey->keyType = NSSLOWKEYRSAKey;

    /* The modulus is set to the key id of the symmetric key */
    privKey->u.rsa.modulus.data =
        (unsigned char *)PORT_ArenaAlloc(arena, pubkey->len);
    if (privKey->u.rsa.modulus.data == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }
    privKey->u.rsa.modulus.len = pubkey->len;
    PORT_Memcpy(privKey->u.rsa.modulus.data, pubkey->data, pubkey->len);

    /* The public exponent is set to 0 to indicate a special key */
    privKey->u.rsa.publicExponent.len = sizeof derZero;
    privKey->u.rsa.publicExponent.data = derZero;

    /* The private exponent is the actual key value */
    crv = lg_PrivAttr2SecItem(arena, CKA_VALUE, templ, count,
                              &privKey->u.rsa.privateExponent, sdbpw);
    if (crv != CKR_OK)
        goto loser;

    /* All other fields empty - needs testing */
    privKey->u.rsa.prime1.len = sizeof derZero;
    privKey->u.rsa.prime1.data = derZero;

    privKey->u.rsa.prime2.len = sizeof derZero;
    privKey->u.rsa.prime2.data = derZero;

    privKey->u.rsa.exponent1.len = sizeof derZero;
    privKey->u.rsa.exponent1.data = derZero;

    privKey->u.rsa.exponent2.len = sizeof derZero;
    privKey->u.rsa.exponent2.data = derZero;

    /* Coeficient set to KEY_TYPE */
    crv = lg_GetULongAttribute(CKA_KEY_TYPE, templ, count, &keyType);
    if (crv != CKR_OK)
        goto loser;
    /* on 64 bit platforms, we still want to store 32 bits of keyType (This is
     * safe since the PKCS #11 defines for all types are 32 bits or less). */
    keyTypeStorage = (PRUint32)keyType;
    keyTypeStorage = PR_htonl(keyTypeStorage);
    keyTypeItem.data = (unsigned char *)&keyTypeStorage;
    keyTypeItem.len = sizeof(keyTypeStorage);
    rv = SECITEM_CopyItem(arena, &privKey->u.rsa.coefficient, &keyTypeItem);
    if (rv != SECSuccess) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

    /* Private key version field set normally for compatibility */
    rv = DER_SetUInteger(privKey->arena,
                         &privKey->u.rsa.version, NSSLOWKEY_VERSION);
    if (rv != SECSuccess) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

loser:
    if (crv != CKR_OK) {
        PORT_FreeArena(arena, PR_FALSE);
        privKey = 0;
    }

    return privKey;
}

/*
 * check the consistancy and initialize a Secret Key Object
 */
static CK_RV
lg_createSecretKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
                         CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    CK_RV crv;
    NSSLOWKEYPrivateKey *privKey = NULL;
    NSSLOWKEYDBHandle *keyHandle = NULL;
    SECItem pubKey;
    char *label = NULL;
    SECStatus rv = SECSuccess;

    pubKey.data = 0;

    /* If the object is a TOKEN object, store in the database */
    keyHandle = lg_getKeyDB(sdb);

    if (keyHandle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    label = lg_getString(CKA_LABEL, templ, count);

    crv = lg_Attribute2SecItem(NULL, CKA_ID, templ, count, &pubKey);
    /* Should this be ID? */
    if (crv != CKR_OK)
        goto loser;

    /* if we don't have an ID, generate one */
    if (pubKey.len == 0) {
        if (pubKey.data) {
            PORT_Free(pubKey.data);
            pubKey.data = NULL;
        }
        crv = lg_GenerateSecretCKA_ID(keyHandle, &pubKey, label);
        if (crv != CKR_OK)
            goto loser;
    }

    privKey = lg_mkSecretKeyRep(templ, count, key_type, &pubKey, sdb);
    if (privKey == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

    rv = nsslowkey_StoreKeyByPublicKey(keyHandle,
                                       privKey, &pubKey, label, sdb /*->password*/);
    if (rv != SECSuccess) {
        crv = CKR_DEVICE_ERROR;
        goto loser;
    }

    *handle = lg_mkHandle(sdb, &pubKey, LG_TOKEN_TYPE_KEY);

loser:
    if (label)
        PORT_Free(label);
    if (privKey)
        lg_nsslowkey_DestroyPrivateKey(privKey);
    if (pubKey.data)
        PORT_Free(pubKey.data);

    return crv;
}

/*
 * check the consistancy and initialize a Key Object
 */
static CK_RV
lg_createKeyObject(SDB *sdb, CK_OBJECT_CLASS objclass,
                   CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    CK_RV crv;
    CK_KEY_TYPE key_type;

    /* get the key type */
    crv = lg_GetULongAttribute(CKA_KEY_TYPE, templ, count, &key_type);
    if (crv != CKR_OK) {
        return crv;
    }

    switch (objclass) {
        case CKO_PUBLIC_KEY:
            return lg_createPublicKeyObject(sdb, key_type, handle, templ, count);
        case CKO_PRIVATE_KEY:
            return lg_createPrivateKeyObject(sdb, key_type, handle, templ, count);
        case CKO_SECRET_KEY:
            return lg_createSecretKeyObject(sdb, key_type, handle, templ, count);
        default:
            break;
    }
    return CKR_ATTRIBUTE_VALUE_INVALID;
}

/*
 * return the 'next' key handle
 */
CK_RV
lg_GetNewObjectID(SDB *sdb, CK_OBJECT_HANDLE *handle)
{
    /* the upper level needs the Object ID early to populate any
     * signature attributes. The legacy can't really return a new
     * handle without the full object template (chicken and egg issue).
     * Fortunately we can just return a bogus handle because the legacy
     * database doesn't support meta data and can't store any of the signed
     * attributes anyway */
    *handle = CK_INVALID_HANDLE;
    return CKR_OK;
}

/*
 * Parse the template and create an object stored in the DB that reflects.
 * the object specified in the database.
 */
CK_RV
lg_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
                const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    CK_RV crv;
    CK_OBJECT_CLASS objclass;

    /* get the object class */
    crv = lg_GetULongAttribute(CKA_CLASS, templ, count, &objclass);
    if (crv != CKR_OK) {
        return crv;
    }

    /* Now handle the specific object class.
     */
    switch (objclass) {
        case CKO_CERTIFICATE:
            crv = lg_createCertObject(sdb, handle, templ, count);
            break;
        case CKO_NSS_TRUST:
            crv = lg_createTrustObject(sdb, handle, templ, count);
            break;
        case CKO_NSS_CRL:
            crv = lg_createCrlObject(sdb, handle, templ, count);
            break;
        case CKO_NSS_SMIME:
            crv = lg_createSMimeObject(sdb, handle, templ, count);
            break;
        case CKO_PRIVATE_KEY:
        case CKO_PUBLIC_KEY:
        case CKO_SECRET_KEY:
            crv = lg_createKeyObject(sdb, objclass, handle, templ, count);
            break;
        default:
            crv = CKR_ATTRIBUTE_VALUE_INVALID;
            break;
    }

    return crv;
}
