/* 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/. */
/*
 * Internal PKCS #11 functions. Should only be called by pkcs11.c
 */
#include "pkcs11.h"
#include "lgdb.h"

#include "pcertt.h"
#include "lowkeyi.h"
#include "pcert.h"
#include "blapi.h"
#include "secerr.h"
#include "secasn1.h"

/*
 * Cache the object we are working on during Set's and Get's
 */
typedef struct LGObjectCacheStr {
    CK_OBJECT_CLASS objclass;
    CK_OBJECT_HANDLE handle;
    SDB *sdb;
    void *objectInfo;
    LGFreeFunc infoFree;
    SECItem dbKey;
} LGObjectCache;

static const CK_OBJECT_HANDLE lg_classArray[] = {
    0, CKO_PRIVATE_KEY, CKO_PUBLIC_KEY, CKO_SECRET_KEY,
    CKO_NSS_TRUST, CKO_NSS_CRL, CKO_NSS_SMIME,
    CKO_CERTIFICATE
};

#define handleToClass(handle) \
    lg_classArray[((handle & LG_TOKEN_TYPE_MASK)) >> LG_TOKEN_TYPE_SHIFT]

static void lg_DestroyObjectCache(LGObjectCache *obj);

static LGObjectCache *
lg_NewObjectCache(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE handle)
{
    LGObjectCache *obj = NULL;
    SECStatus rv;

    obj = PORT_New(LGObjectCache);
    if (obj == NULL) {
        return NULL;
    }

    obj->objclass = handleToClass(handle);
    obj->handle = handle;
    obj->sdb = sdb;
    obj->objectInfo = NULL;
    obj->infoFree = NULL;
    obj->dbKey.data = NULL;
    obj->dbKey.len = 0;
    lg_DBLock(sdb);
    if (dbKey == NULL) {
        dbKey = lg_lookupTokenKeyByHandle(sdb, handle);
    }
    if (dbKey == NULL) {
        lg_DBUnlock(sdb);
        goto loser;
    }
    rv = SECITEM_CopyItem(NULL, &obj->dbKey, dbKey);
    lg_DBUnlock(sdb);
    if (rv != SECSuccess) {
        goto loser;
    }

    return obj;
loser:
    (void)lg_DestroyObjectCache(obj);
    return NULL;
}

/*
 * free all the data associated with an object. Object reference count must
 * be 'zero'.
 */
static void
lg_DestroyObjectCache(LGObjectCache *obj)
{
    if (obj->dbKey.data) {
        PORT_Free(obj->dbKey.data);
        obj->dbKey.data = NULL;
    }
    if (obj->objectInfo) {
        (*obj->infoFree)(obj->objectInfo);
        obj->objectInfo = NULL;
        obj->infoFree = NULL;
    }
    PORT_Free(obj);
}
/*
 * ******************** Attribute Utilities *******************************
 */

static CK_RV
lg_ULongAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, CK_ULONG value)
{
    unsigned char *data;
    int i;

    if (attr->pValue == NULL) {
        attr->ulValueLen = 4;
        return CKR_OK;
    }
    if (attr->ulValueLen < 4) {
        attr->ulValueLen = (CK_ULONG)-1;
        return CKR_BUFFER_TOO_SMALL;
    }

    data = (unsigned char *)attr->pValue;
    for (i = 0; i < 4; i++) {
        data[i] = (value >> ((3 - i) * 8)) & 0xff;
    }
    attr->ulValueLen = 4;
    return CKR_OK;
}

static CK_RV
lg_CopyAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type,
                 CK_VOID_PTR value, CK_ULONG len)
{

    if (attr->pValue == NULL) {
        attr->ulValueLen = len;
        return CKR_OK;
    }
    if (attr->ulValueLen < len) {
        attr->ulValueLen = (CK_ULONG)-1;
        return CKR_BUFFER_TOO_SMALL;
    }
    if (len > 0 && value != NULL) {
        PORT_Memcpy(attr->pValue, value, len);
    }
    attr->ulValueLen = len;
    return CKR_OK;
}

static CK_RV
lg_CopyAttributeSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
                       void *value, CK_ULONG len)
{
    unsigned char *dval = (unsigned char *)value;
    if (*dval == 0) {
        dval++;
        len--;
    }
    return lg_CopyAttribute(attribute, type, dval, len);
}

static CK_RV
lg_CopyPrivAttribute(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
                     void *value, CK_ULONG len, SDB *sdbpw)
{
    SECItem plainText, *cipherText = NULL;
    CK_RV crv = CKR_USER_NOT_LOGGED_IN;
    SECStatus rv;

    plainText.data = value;
    plainText.len = len;
    rv = lg_util_encrypt(NULL, sdbpw, &plainText, &cipherText);
    if (rv != SECSuccess) {
        goto loser;
    }
    crv = lg_CopyAttribute(attribute, type, cipherText->data, cipherText->len);
loser:
    if (cipherText) {
        SECITEM_FreeItem(cipherText, PR_TRUE);
    }
    return crv;
}

static CK_RV
lg_CopyPrivAttrSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
                      void *value, CK_ULONG len, SDB *sdbpw)
{
    unsigned char *dval = (unsigned char *)value;

    if (*dval == 0) {
        dval++;
        len--;
    }
    return lg_CopyPrivAttribute(attribute, type, dval, len, sdbpw);
}

static CK_RV
lg_invalidAttribute(CK_ATTRIBUTE *attr)
{
    attr->ulValueLen = (CK_ULONG)-1;
    return CKR_ATTRIBUTE_TYPE_INVALID;
}

#define LG_DEF_ATTRIBUTE(value, len) \
    {                                \
        0, value, len                \
    }

#define LG_CLONE_ATTR(attribute, type, staticAttr) \
    lg_CopyAttribute(attribute, type, staticAttr.pValue, staticAttr.ulValueLen)

CK_BBOOL lg_staticTrueValue = CK_TRUE;
CK_BBOOL lg_staticFalseValue = CK_FALSE;
static const CK_ATTRIBUTE lg_StaticTrueAttr =
    LG_DEF_ATTRIBUTE(&lg_staticTrueValue, sizeof(lg_staticTrueValue));
static const CK_ATTRIBUTE lg_StaticFalseAttr =
    LG_DEF_ATTRIBUTE(&lg_staticFalseValue, sizeof(lg_staticFalseValue));
static const CK_ATTRIBUTE lg_StaticNullAttr = LG_DEF_ATTRIBUTE(NULL, 0);
char lg_StaticOneValue = 1;

/*
 * helper functions which get the database and call the underlying
 * low level database function.
 */
static char *
lg_FindKeyNicknameByPublicKey(SDB *sdb, SECItem *dbKey)
{
    NSSLOWKEYDBHandle *keyHandle;
    char *label;

    keyHandle = lg_getKeyDB(sdb);
    if (!keyHandle) {
        return NULL;
    }

    label = nsslowkey_FindKeyNicknameByPublicKey(keyHandle, dbKey,
                                                 sdb);
    return label;
}

NSSLOWKEYPrivateKey *
lg_FindKeyByPublicKey(SDB *sdb, SECItem *dbKey)
{
    NSSLOWKEYPrivateKey *privKey;
    NSSLOWKEYDBHandle *keyHandle;

    keyHandle = lg_getKeyDB(sdb);
    if (keyHandle == NULL) {
        return NULL;
    }
    privKey = nsslowkey_FindKeyByPublicKey(keyHandle, dbKey, sdb);
    if (privKey == NULL) {
        return NULL;
    }
    return privKey;
}

static certDBEntrySMime *
lg_getSMime(LGObjectCache *obj)
{
    certDBEntrySMime *entry;
    NSSLOWCERTCertDBHandle *certHandle;

    if (obj->objclass != CKO_NSS_SMIME) {
        return NULL;
    }
    if (obj->objectInfo) {
        return (certDBEntrySMime *)obj->objectInfo;
    }

    certHandle = lg_getCertDB(obj->sdb);
    if (!certHandle) {
        return NULL;
    }
    entry = nsslowcert_ReadDBSMimeEntry(certHandle, (char *)obj->dbKey.data);
    obj->objectInfo = (void *)entry;
    obj->infoFree = (LGFreeFunc)nsslowcert_DestroyDBEntry;
    return entry;
}

static certDBEntryRevocation *
lg_getCrl(LGObjectCache *obj)
{
    certDBEntryRevocation *crl;
    PRBool isKrl;
    NSSLOWCERTCertDBHandle *certHandle;

    if (obj->objclass != CKO_NSS_CRL) {
        return NULL;
    }
    if (obj->objectInfo) {
        return (certDBEntryRevocation *)obj->objectInfo;
    }

    isKrl = (PRBool)(obj->handle == LG_TOKEN_KRL_HANDLE);
    certHandle = lg_getCertDB(obj->sdb);
    if (!certHandle) {
        return NULL;
    }

    crl = nsslowcert_FindCrlByKey(certHandle, &obj->dbKey, isKrl);
    obj->objectInfo = (void *)crl;
    obj->infoFree = (LGFreeFunc)nsslowcert_DestroyDBEntry;
    return crl;
}

static NSSLOWCERTCertificate *
lg_getCert(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle)
{
    NSSLOWCERTCertificate *cert;
    CK_OBJECT_CLASS objClass = obj->objclass;

    if ((objClass != CKO_CERTIFICATE) && (objClass != CKO_NSS_TRUST)) {
        return NULL;
    }
    if (objClass == CKO_CERTIFICATE && obj->objectInfo) {
        return (NSSLOWCERTCertificate *)obj->objectInfo;
    }
    cert = nsslowcert_FindCertByKey(certHandle, &obj->dbKey);
    if (objClass == CKO_CERTIFICATE) {
        obj->objectInfo = (void *)cert;
        obj->infoFree = (LGFreeFunc)nsslowcert_DestroyCertificate;
    }
    return cert;
}

static NSSLOWCERTTrust *
lg_getTrust(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle)
{
    NSSLOWCERTTrust *trust;

    if (obj->objclass != CKO_NSS_TRUST) {
        return NULL;
    }
    if (obj->objectInfo) {
        return (NSSLOWCERTTrust *)obj->objectInfo;
    }
    trust = nsslowcert_FindTrustByKey(certHandle, &obj->dbKey);
    obj->objectInfo = (void *)trust;
    obj->infoFree = (LGFreeFunc)nsslowcert_DestroyTrust;
    return trust;
}

static NSSLOWKEYPublicKey *
lg_GetPublicKey(LGObjectCache *obj)
{
    NSSLOWKEYPublicKey *pubKey;
    NSSLOWKEYPrivateKey *privKey;

    if (obj->objclass != CKO_PUBLIC_KEY) {
        return NULL;
    }
    if (obj->objectInfo) {
        return (NSSLOWKEYPublicKey *)obj->objectInfo;
    }
    privKey = lg_FindKeyByPublicKey(obj->sdb, &obj->dbKey);
    if (privKey == NULL) {
        return NULL;
    }
    pubKey = lg_nsslowkey_ConvertToPublicKey(privKey);
    lg_nsslowkey_DestroyPrivateKey(privKey);
    obj->objectInfo = (void *)pubKey;
    obj->infoFree = (LGFreeFunc)lg_nsslowkey_DestroyPublicKey;
    return pubKey;
}

/*
 * we need two versions of lg_GetPrivateKey. One version that takes the
 * DB handle so we can pass the handle we have already acquired in,
 *  rather than going through the 'getKeyDB' code again,
 *  which may fail the second time and another which just aquires
 *  the key handle from the sdb (where we don't already have a key handle.
 * This version does the former.
 */
static NSSLOWKEYPrivateKey *
lg_GetPrivateKeyWithDB(LGObjectCache *obj, NSSLOWKEYDBHandle *keyHandle)
{
    NSSLOWKEYPrivateKey *privKey;

    if ((obj->objclass != CKO_PRIVATE_KEY) &&
        (obj->objclass != CKO_SECRET_KEY)) {
        return NULL;
    }
    if (obj->objectInfo) {
        return (NSSLOWKEYPrivateKey *)obj->objectInfo;
    }
    privKey = nsslowkey_FindKeyByPublicKey(keyHandle, &obj->dbKey, obj->sdb);
    if (privKey == NULL) {
        return NULL;
    }
    obj->objectInfo = (void *)privKey;
    obj->infoFree = (LGFreeFunc)lg_nsslowkey_DestroyPrivateKey;
    return privKey;
}

/* this version does the latter */
static NSSLOWKEYPrivateKey *
lg_GetPrivateKey(LGObjectCache *obj)
{
    NSSLOWKEYDBHandle *keyHandle;
    NSSLOWKEYPrivateKey *privKey;

    keyHandle = lg_getKeyDB(obj->sdb);
    if (!keyHandle) {
        return NULL;
    }
    privKey = lg_GetPrivateKeyWithDB(obj, keyHandle);
    return privKey;
}

/* lg_GetPubItem returns data associated with the public key.
 * one only needs to free the public key. This comment is here
 * because this sematic would be non-obvious otherwise. All callers
 * should include this comment.
 */
static SECItem *
lg_GetPubItem(NSSLOWKEYPublicKey *pubKey)
{
    SECItem *pubItem = NULL;
    /* get value to compare from the cert's public key */
    switch (pubKey->keyType) {
        case NSSLOWKEYRSAKey:
            pubItem = &pubKey->u.rsa.modulus;
            break;
        case NSSLOWKEYDSAKey:
            pubItem = &pubKey->u.dsa.publicValue;
            break;
        case NSSLOWKEYDHKey:
            pubItem = &pubKey->u.dh.publicValue;
            break;
        case NSSLOWKEYECKey:
            pubItem = &pubKey->u.ec.publicValue;
            break;
        default:
            break;
    }
    return pubItem;
}

static CK_RV
lg_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
                             CK_ATTRIBUTE *attribute)
{
    unsigned char hash[SHA1_LENGTH];
    CK_KEY_TYPE keyType = CKK_RSA;

    switch (type) {
        case CKA_KEY_TYPE:
            return lg_ULongAttribute(attribute, type, keyType);
        case CKA_ID:
            SHA1_HashBuf(hash, key->u.rsa.modulus.data, key->u.rsa.modulus.len);
            return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
        case CKA_DERIVE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_ENCRYPT:
        case CKA_VERIFY:
        case CKA_VERIFY_RECOVER:
        case CKA_WRAP:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_MODULUS:
            return lg_CopyAttributeSigned(attribute, type, key->u.rsa.modulus.data,
                                          key->u.rsa.modulus.len);
        case CKA_PUBLIC_EXPONENT:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.rsa.publicExponent.data,
                                          key->u.rsa.publicExponent.len);
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
                             CK_ATTRIBUTE *attribute)
{
    unsigned char hash[SHA1_LENGTH];
    CK_KEY_TYPE keyType = CKK_DSA;

    switch (type) {
        case CKA_KEY_TYPE:
            return lg_ULongAttribute(attribute, type, keyType);
        case CKA_ID:
            SHA1_HashBuf(hash, key->u.dsa.publicValue.data,
                         key->u.dsa.publicValue.len);
            return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
        case CKA_DERIVE:
        case CKA_ENCRYPT:
        case CKA_VERIFY_RECOVER:
        case CKA_WRAP:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_VERIFY:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_VALUE:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.dsa.publicValue.data,
                                          key->u.dsa.publicValue.len);
        case CKA_PRIME:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.dsa.params.prime.data,
                                          key->u.dsa.params.prime.len);
        case CKA_SUBPRIME:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.dsa.params.subPrime.data,
                                          key->u.dsa.params.subPrime.len);
        case CKA_BASE:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.dsa.params.base.data,
                                          key->u.dsa.params.base.len);
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
                            CK_ATTRIBUTE *attribute)
{
    unsigned char hash[SHA1_LENGTH];
    CK_KEY_TYPE keyType = CKK_DH;

    switch (type) {
        case CKA_KEY_TYPE:
            return lg_ULongAttribute(attribute, type, keyType);
        case CKA_ID:
            SHA1_HashBuf(hash, key->u.dh.publicValue.data, key->u.dh.publicValue.len);
            return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
        case CKA_DERIVE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_ENCRYPT:
        case CKA_VERIFY:
        case CKA_VERIFY_RECOVER:
        case CKA_WRAP:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_VALUE:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.dh.publicValue.data,
                                          key->u.dh.publicValue.len);
        case CKA_PRIME:
            return lg_CopyAttributeSigned(attribute, type, key->u.dh.prime.data,
                                          key->u.dh.prime.len);
        case CKA_BASE:
            return lg_CopyAttributeSigned(attribute, type, key->u.dh.base.data,
                                          key->u.dh.base.len);
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
                            CK_ATTRIBUTE *attribute)
{
    unsigned char hash[SHA1_LENGTH];
    CK_KEY_TYPE keyType = CKK_EC;

    switch (type) {
        case CKA_KEY_TYPE:
            return lg_ULongAttribute(attribute, type, keyType);
        case CKA_ID:
            SHA1_HashBuf(hash, key->u.ec.publicValue.data,
                         key->u.ec.publicValue.len);
            return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
        case CKA_DERIVE:
        case CKA_VERIFY:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_ENCRYPT:
        case CKA_VERIFY_RECOVER:
        case CKA_WRAP:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_EC_PARAMS:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.ec.ecParams.DEREncoding.data,
                                          key->u.ec.ecParams.DEREncoding.len);
        case CKA_EC_POINT:
            if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT")) {
                return lg_CopyAttributeSigned(attribute, type,
                                              key->u.ec.publicValue.data,
                                              key->u.ec.publicValue.len);
            } else {
                SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
                                                       &(key->u.ec.publicValue),
                                                       SEC_ASN1_GET(SEC_OctetStringTemplate));
                CK_RV crv;
                if (!pubValue) {
                    return CKR_HOST_MEMORY;
                }
                crv = lg_CopyAttributeSigned(attribute, type,
                                             pubValue->data,
                                             pubValue->len);
                SECITEM_FreeItem(pubValue, PR_TRUE);
                return crv;
            }
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
                          CK_ATTRIBUTE *attribute)
{
    NSSLOWKEYPublicKey *key;
    CK_RV crv;
    char *label;

    switch (type) {
        case CKA_PRIVATE:
        case CKA_SENSITIVE:
        case CKA_ALWAYS_SENSITIVE:
        case CKA_NEVER_EXTRACTABLE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_MODIFIABLE:
        case CKA_EXTRACTABLE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_SUBJECT:
            return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
        case CKA_START_DATE:
        case CKA_END_DATE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
        case CKA_LABEL:
            label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
            if (label == NULL) {
                return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
            }
            crv = lg_CopyAttribute(attribute, type, label, PORT_Strlen(label));
            PORT_Free(label);
            return crv;
        default:
            break;
    }

    key = lg_GetPublicKey(obj);
    if (key == NULL) {
        if (type == CKA_ID) {
            return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
        }
        return CKR_OBJECT_HANDLE_INVALID;
    }

    switch (key->keyType) {
        case NSSLOWKEYRSAKey:
            return lg_FindRSAPublicKeyAttribute(key, type, attribute);
        case NSSLOWKEYDSAKey:
            return lg_FindDSAPublicKeyAttribute(key, type, attribute);
        case NSSLOWKEYDHKey:
            return lg_FindDHPublicKeyAttribute(key, type, attribute);
        case NSSLOWKEYECKey:
            return lg_FindECPublicKeyAttribute(key, type, attribute);
        default:
            break;
    }

    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindSecretKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
                          CK_ATTRIBUTE *attribute)
{
    NSSLOWKEYPrivateKey *key;
    char *label;
    unsigned char *keyString;
    CK_RV crv;
    int keyTypeLen;
    CK_ULONG keyLen;
    CK_KEY_TYPE keyType;
    PRUint32 keyTypeStorage;

    switch (type) {
        case CKA_PRIVATE:
        case CKA_SENSITIVE:
        case CKA_ALWAYS_SENSITIVE:
        case CKA_EXTRACTABLE:
        case CKA_DERIVE:
        case CKA_ENCRYPT:
        case CKA_DECRYPT:
        case CKA_SIGN:
        case CKA_VERIFY:
        case CKA_WRAP:
        case CKA_UNWRAP:
        case CKA_MODIFIABLE:
        case CKA_LOCAL:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_NEVER_EXTRACTABLE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_START_DATE:
        case CKA_END_DATE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
        case CKA_LABEL:
            label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
            if (label == NULL) {
                return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
            }
            crv = lg_CopyAttribute(attribute, type, label, PORT_Strlen(label));
            PORT_Free(label);
            return crv;
        case CKA_ID:
            return lg_CopyAttribute(attribute, type, obj->dbKey.data,
                                    obj->dbKey.len);
        case CKA_KEY_TYPE:
        case CKA_VALUE_LEN:
        case CKA_VALUE:
            break;
        default:
            return lg_invalidAttribute(attribute);
    }

    key = lg_GetPrivateKey(obj);
    if (key == NULL) {
        return CKR_OBJECT_HANDLE_INVALID;
    }
    switch (type) {
        case CKA_KEY_TYPE:
            /* handle legacy databases. In legacy databases key_type was stored
             * in host order, with any leading zeros stripped off. Only key types
             * under 0x1f (AES) were stored. We assume that any values which are
             * either 1 byte long (big endian), or have byte[0] between 0 and
             * 0x7f and bytes[1]-bytes[3] equal to '0' (little endian). All other
             * values are assumed to be from the new database, which is always 4
             * bytes in network order */
            keyType = 0;
            keyString = key->u.rsa.coefficient.data;
            keyTypeLen = key->u.rsa.coefficient.len;

            /*
             * Because of various endian and word lengths The database may have
             * stored the keyType value in one of the following formats:
             *   (kt) <= 0x1f
             *                                   length data
             * Big Endian,     pre-3.9, all lengths: 1  (kt)
             * Little Endian,  pre-3.9, 32 bits:     4  (kt) 0  0  0
             * Little Endian,  pre-3.9, 64 bits:     8  (kt) 0  0  0   0  0  0  0
             * All platforms,      3.9, 32 bits:     4    0  0  0 (kt)
             * Big Endian,         3.9, 64 bits:     8    0  0  0 (kt) 0  0  0  0
             * Little  Endian,     3.9, 64 bits:     8    0  0  0  0   0  0  0 (kt)
             * All platforms, >= 3.9.1, all lengths: 4   (a) k1 k2 k3
             * where (a) is 0 or >= 0x80. currently (a) can only be 0.
             */
            /*
             * this key was written on a 64 bit platform with a using NSS 3.9
             * or earlier. Reduce the 64 bit possibilities above. When we are
             * through, we will only have:
             *
             * Big Endian,     pre-3.9, all lengths: 1  (kt)
             * Little Endian,  pre-3.9, all lengths: 4  (kt) 0  0  0
             * All platforms,      3.9, all lengths: 4    0  0  0 (kt)
             * All platforms, => 3.9.1, all lengths: 4   (a) k1 k2 k3
             */
            if (keyTypeLen == 8) {
                keyTypeStorage = *(PRUint32 *)keyString;
                if (keyTypeStorage == 0) {
                    keyString += sizeof(PRUint32);
                }
                keyTypeLen = 4;
            }
            /*
             * Now Handle:
             *
             * All platforms,      3.9, all lengths: 4    0  0  0 (kt)
             * All platforms, => 3.9.1, all lengths: 4   (a) k1 k2 k3
             *
             * NOTE: if  kt == 0 or ak1k2k3 == 0, the test fails and
             * we handle it as:
             *
             * Little Endian,  pre-3.9, all lengths: 4  (kt) 0  0  0
             */
            if (keyTypeLen == sizeof(keyTypeStorage) &&
                (((keyString[0] & 0x80) == 0x80) ||
                 !((keyString[1] == 0) && (keyString[2] == 0) && (keyString[3] == 0)))) {
                PORT_Memcpy(&keyTypeStorage, keyString, sizeof(keyTypeStorage));
                keyType = (CK_KEY_TYPE)PR_ntohl(keyTypeStorage);
            } else {
                /*
                 * Now Handle:
                 *
                 * Big Endian,     pre-3.9, all lengths: 1  (kt)
                 * Little Endian,  pre-3.9, all lengths: 4  (kt) 0  0  0
                 *  -- KeyType == 0 all other cases ---: 4    0  0  0  0
                 */
                keyType = (CK_KEY_TYPE)keyString[0];
            }
            return lg_ULongAttribute(attribute, type, keyType);
        case CKA_VALUE:
            return lg_CopyPrivAttribute(attribute, type, key->u.rsa.privateExponent.data,
                                        key->u.rsa.privateExponent.len, obj->sdb);
        case CKA_VALUE_LEN:
            keyLen = key->u.rsa.privateExponent.len;
            return lg_ULongAttribute(attribute, type, keyLen);
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
                              CK_ATTRIBUTE *attribute, SDB *sdbpw)
{
    unsigned char hash[SHA1_LENGTH];
    CK_KEY_TYPE keyType = CKK_RSA;

    switch (type) {
        case CKA_KEY_TYPE:
            return lg_ULongAttribute(attribute, type, keyType);
        case CKA_ID:
            SHA1_HashBuf(hash, key->u.rsa.modulus.data, key->u.rsa.modulus.len);
            return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
        case CKA_DERIVE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_DECRYPT:
        case CKA_SIGN:
        case CKA_SIGN_RECOVER:
        case CKA_UNWRAP:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_MODULUS:
            return lg_CopyAttributeSigned(attribute, type, key->u.rsa.modulus.data,
                                          key->u.rsa.modulus.len);
        case CKA_PUBLIC_EXPONENT:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.rsa.publicExponent.data,
                                          key->u.rsa.publicExponent.len);
        case CKA_PRIVATE_EXPONENT:
            return lg_CopyPrivAttrSigned(attribute, type,
                                         key->u.rsa.privateExponent.data,
                                         key->u.rsa.privateExponent.len, sdbpw);
        case CKA_PRIME_1:
            return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime1.data,
                                         key->u.rsa.prime1.len, sdbpw);
        case CKA_PRIME_2:
            return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime2.data,
                                         key->u.rsa.prime2.len, sdbpw);
        case CKA_EXPONENT_1:
            return lg_CopyPrivAttrSigned(attribute, type,
                                         key->u.rsa.exponent1.data,
                                         key->u.rsa.exponent1.len, sdbpw);
        case CKA_EXPONENT_2:
            return lg_CopyPrivAttrSigned(attribute, type,
                                         key->u.rsa.exponent2.data,
                                         key->u.rsa.exponent2.len, sdbpw);
        case CKA_COEFFICIENT:
            return lg_CopyPrivAttrSigned(attribute, type,
                                         key->u.rsa.coefficient.data,
                                         key->u.rsa.coefficient.len, sdbpw);
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
                              CK_ATTRIBUTE *attribute, SDB *sdbpw)
{
    unsigned char hash[SHA1_LENGTH];
    CK_KEY_TYPE keyType = CKK_DSA;

    switch (type) {
        case CKA_KEY_TYPE:
            return lg_ULongAttribute(attribute, type, keyType);
        case CKA_ID:
            SHA1_HashBuf(hash, key->u.dsa.publicValue.data,
                         key->u.dsa.publicValue.len);
            return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
        case CKA_DERIVE:
        case CKA_DECRYPT:
        case CKA_SIGN_RECOVER:
        case CKA_UNWRAP:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_SIGN:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_VALUE:
            return lg_CopyPrivAttrSigned(attribute, type,
                                         key->u.dsa.privateValue.data,
                                         key->u.dsa.privateValue.len, sdbpw);
        case CKA_PRIME:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.dsa.params.prime.data,
                                          key->u.dsa.params.prime.len);
        case CKA_SUBPRIME:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.dsa.params.subPrime.data,
                                          key->u.dsa.params.subPrime.len);
        case CKA_BASE:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.dsa.params.base.data,
                                          key->u.dsa.params.base.len);
        case CKA_NETSCAPE_DB:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.dsa.publicValue.data,
                                          key->u.dsa.publicValue.len);
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
                             CK_ATTRIBUTE *attribute, SDB *sdbpw)
{
    unsigned char hash[SHA1_LENGTH];
    CK_KEY_TYPE keyType = CKK_DH;

    switch (type) {
        case CKA_KEY_TYPE:
            return lg_ULongAttribute(attribute, type, keyType);
        case CKA_ID:
            SHA1_HashBuf(hash, key->u.dh.publicValue.data, key->u.dh.publicValue.len);
            return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
        case CKA_DERIVE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_DECRYPT:
        case CKA_SIGN:
        case CKA_SIGN_RECOVER:
        case CKA_UNWRAP:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_VALUE:
            return lg_CopyPrivAttrSigned(attribute, type,
                                         key->u.dh.privateValue.data,
                                         key->u.dh.privateValue.len, sdbpw);
        case CKA_PRIME:
            return lg_CopyAttributeSigned(attribute, type, key->u.dh.prime.data,
                                          key->u.dh.prime.len);
        case CKA_BASE:
            return lg_CopyAttributeSigned(attribute, type, key->u.dh.base.data,
                                          key->u.dh.base.len);
        case CKA_NETSCAPE_DB:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.dh.publicValue.data,
                                          key->u.dh.publicValue.len);
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
                             CK_ATTRIBUTE *attribute, SDB *sdbpw)
{
    unsigned char hash[SHA1_LENGTH];
    CK_KEY_TYPE keyType = CKK_EC;

    switch (type) {
        case CKA_KEY_TYPE:
            return lg_ULongAttribute(attribute, type, keyType);
        case CKA_ID:
            SHA1_HashBuf(hash, key->u.ec.publicValue.data, key->u.ec.publicValue.len);
            return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
        case CKA_DERIVE:
        case CKA_SIGN:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_DECRYPT:
        case CKA_SIGN_RECOVER:
        case CKA_UNWRAP:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_VALUE:
            return lg_CopyPrivAttrSigned(attribute, type,
                                         key->u.ec.privateValue.data,
                                         key->u.ec.privateValue.len, sdbpw);
        case CKA_EC_PARAMS:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.ec.ecParams.DEREncoding.data,
                                          key->u.ec.ecParams.DEREncoding.len);
        case CKA_NETSCAPE_DB:
            return lg_CopyAttributeSigned(attribute, type,
                                          key->u.ec.publicValue.data,
                                          key->u.ec.publicValue.len);
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
                           CK_ATTRIBUTE *attribute)
{
    NSSLOWKEYPrivateKey *key;
    char *label;
    CK_RV crv;

    switch (type) {
        case CKA_PRIVATE:
        case CKA_SENSITIVE:
        case CKA_ALWAYS_SENSITIVE:
        case CKA_EXTRACTABLE:
        case CKA_MODIFIABLE:
        case CKA_LOCAL:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_NEVER_EXTRACTABLE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_SUBJECT:
            return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
        case CKA_START_DATE:
        case CKA_END_DATE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
        case CKA_LABEL:
            label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
            if (label == NULL) {
                return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
            }
            crv = lg_CopyAttribute(attribute, type, label, PORT_Strlen(label));
            PORT_Free(label);
            return crv;
        default:
            break;
    }
    key = lg_GetPrivateKey(obj);
    if (key == NULL) {
        return CKR_OBJECT_HANDLE_INVALID;
    }
    switch (key->keyType) {
        case NSSLOWKEYRSAKey:
            return lg_FindRSAPrivateKeyAttribute(key, type, attribute, obj->sdb);
        case NSSLOWKEYDSAKey:
            return lg_FindDSAPrivateKeyAttribute(key, type, attribute, obj->sdb);
        case NSSLOWKEYDHKey:
            return lg_FindDHPrivateKeyAttribute(key, type, attribute, obj->sdb);
        case NSSLOWKEYECKey:
            return lg_FindECPrivateKeyAttribute(key, type, attribute, obj->sdb);
        default:
            break;
    }

    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindSMIMEAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
                      CK_ATTRIBUTE *attribute)
{
    certDBEntrySMime *entry;
    switch (type) {
        case CKA_PRIVATE:
        case CKA_MODIFIABLE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_NSS_EMAIL:
            return lg_CopyAttribute(attribute, type, obj->dbKey.data,
                                    obj->dbKey.len - 1);
        case CKA_NSS_SMIME_TIMESTAMP:
        case CKA_SUBJECT:
        case CKA_VALUE:
            break;
        default:
            return lg_invalidAttribute(attribute);
    }
    entry = lg_getSMime(obj);
    if (entry == NULL) {
        return CKR_OBJECT_HANDLE_INVALID;
    }
    switch (type) {
        case CKA_NSS_SMIME_TIMESTAMP:
            return lg_CopyAttribute(attribute, type, entry->optionsDate.data,
                                    entry->optionsDate.len);
        case CKA_SUBJECT:
            return lg_CopyAttribute(attribute, type, entry->subjectName.data,
                                    entry->subjectName.len);
        case CKA_VALUE:
            return lg_CopyAttribute(attribute, type, entry->smimeOptions.data,
                                    entry->smimeOptions.len);
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindTrustAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
                      CK_ATTRIBUTE *attribute)
{
    NSSLOWCERTTrust *trust;
    NSSLOWCERTCertDBHandle *certHandle;
    NSSLOWCERTCertificate *cert;
    unsigned char hash[SHA1_LENGTH];
    unsigned int trustFlags;
    CK_RV crv;

    switch (type) {
        case CKA_PRIVATE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_MODIFIABLE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_CERT_SHA1_HASH:
        case CKA_CERT_MD5_HASH:
        case CKA_TRUST_CLIENT_AUTH:
        case CKA_TRUST_SERVER_AUTH:
        case CKA_TRUST_EMAIL_PROTECTION:
        case CKA_TRUST_CODE_SIGNING:
        case CKA_TRUST_STEP_UP_APPROVED:
        case CKA_ISSUER:
        case CKA_SERIAL_NUMBER:
            break;
        default:
            return lg_invalidAttribute(attribute);
    }
    certHandle = lg_getCertDB(obj->sdb);
    if (!certHandle) {
        return CKR_OBJECT_HANDLE_INVALID;
    }
    trust = lg_getTrust(obj, certHandle);
    if (trust == NULL) {
        return CKR_OBJECT_HANDLE_INVALID;
    }
    switch (type) {
        case CKA_CERT_SHA1_HASH:
            SHA1_HashBuf(hash, trust->derCert->data, trust->derCert->len);
            return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
        case CKA_CERT_MD5_HASH:
            MD5_HashBuf(hash, trust->derCert->data, trust->derCert->len);
            return lg_CopyAttribute(attribute, type, hash, MD5_LENGTH);
        case CKA_TRUST_CLIENT_AUTH:
            trustFlags = trust->trust->sslFlags &
                                 CERTDB_TRUSTED_CLIENT_CA
                             ? trust->trust->sslFlags | CERTDB_TRUSTED_CA
                             : 0;
            goto trust;
        case CKA_TRUST_SERVER_AUTH:
            trustFlags = trust->trust->sslFlags;
            goto trust;
        case CKA_TRUST_EMAIL_PROTECTION:
            trustFlags = trust->trust->emailFlags;
            goto trust;
        case CKA_TRUST_CODE_SIGNING:
            trustFlags = trust->trust->objectSigningFlags;
        trust:
            if (trustFlags & CERTDB_TRUSTED_CA) {
                return lg_ULongAttribute(attribute, type,
                                         CKT_NSS_TRUSTED_DELEGATOR);
            }
            if (trustFlags & CERTDB_TRUSTED) {
                return lg_ULongAttribute(attribute, type, CKT_NSS_TRUSTED);
            }
            if (trustFlags & CERTDB_MUST_VERIFY) {
                return lg_ULongAttribute(attribute, type,
                                         CKT_NSS_MUST_VERIFY_TRUST);
            }
            if (trustFlags & CERTDB_TRUSTED_UNKNOWN) {
                return lg_ULongAttribute(attribute, type, CKT_NSS_TRUST_UNKNOWN);
            }
            if (trustFlags & CERTDB_VALID_CA) {
                return lg_ULongAttribute(attribute, type, CKT_NSS_VALID_DELEGATOR);
            }
            if (trustFlags & CERTDB_TERMINAL_RECORD) {
                return lg_ULongAttribute(attribute, type, CKT_NSS_NOT_TRUSTED);
            }
            return lg_ULongAttribute(attribute, type, CKT_NSS_TRUST_UNKNOWN);
        case CKA_TRUST_STEP_UP_APPROVED:
            if (trust->trust->sslFlags & CERTDB_GOVT_APPROVED_CA) {
                return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
            } else {
                return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
            }
        default:
            break;
    }

    switch (type) {
        case CKA_ISSUER:
            cert = lg_getCert(obj, certHandle);
            if (cert == NULL)
                break;
            crv = lg_CopyAttribute(attribute, type, cert->derIssuer.data,
                                   cert->derIssuer.len);
            break;
        case CKA_SERIAL_NUMBER:
            cert = lg_getCert(obj, certHandle);
            if (cert == NULL)
                break;
            crv = lg_CopyAttribute(attribute, type, cert->derSN.data,
                                   cert->derSN.len);
            break;
        default:
            cert = NULL;
            break;
    }
    if (cert) {
        nsslowcert_DestroyCertificate(cert);
        return crv;
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindCrlAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
                    CK_ATTRIBUTE *attribute)
{
    certDBEntryRevocation *crl;

    switch (type) {
        case CKA_PRIVATE:
        case CKA_MODIFIABLE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_NSS_KRL:
            return ((obj->handle == LG_TOKEN_KRL_HANDLE)
                        ? LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)
                        : LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr));
        case CKA_SUBJECT:
            return lg_CopyAttribute(attribute, type, obj->dbKey.data,
                                    obj->dbKey.len);
        case CKA_NSS_URL:
        case CKA_VALUE:
            break;
        default:
            return lg_invalidAttribute(attribute);
    }
    crl = lg_getCrl(obj);
    if (!crl) {
        return CKR_OBJECT_HANDLE_INVALID;
    }
    switch (type) {
        case CKA_NSS_URL:
            if (crl->url == NULL) {
                return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
            }
            return lg_CopyAttribute(attribute, type, crl->url,
                                    PORT_Strlen(crl->url) + 1);
        case CKA_VALUE:
            return lg_CopyAttribute(attribute, type, crl->derCrl.data,
                                    crl->derCrl.len);
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

static CK_RV
lg_FindCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
                     CK_ATTRIBUTE *attribute)
{
    NSSLOWCERTCertificate *cert;
    NSSLOWCERTCertDBHandle *certHandle;
    NSSLOWKEYPublicKey *pubKey;
    unsigned char hash[SHA1_LENGTH];
    SECItem *item;

    switch (type) {
        case CKA_PRIVATE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
        case CKA_MODIFIABLE:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_CERTIFICATE_TYPE:
            /* hardcoding X.509 into here */
            return lg_ULongAttribute(attribute, type, CKC_X_509);
        case CKA_VALUE:
        case CKA_ID:
        case CKA_LABEL:
        case CKA_SUBJECT:
        case CKA_ISSUER:
        case CKA_SERIAL_NUMBER:
        case CKA_NSS_EMAIL:
            break;
        default:
            return lg_invalidAttribute(attribute);
    }

    certHandle = lg_getCertDB(obj->sdb);
    if (certHandle == NULL) {
        return CKR_OBJECT_HANDLE_INVALID;
    }

    cert = lg_getCert(obj, certHandle);
    if (cert == NULL) {
        return CKR_OBJECT_HANDLE_INVALID;
    }
    switch (type) {
        case CKA_VALUE:
            return lg_CopyAttribute(attribute, type, cert->derCert.data,
                                    cert->derCert.len);
        case CKA_ID:
            if (((cert->trust->sslFlags & CERTDB_USER) == 0) &&
                ((cert->trust->emailFlags & CERTDB_USER) == 0) &&
                ((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) {
                return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
            }
            pubKey = nsslowcert_ExtractPublicKey(cert);
            if (pubKey == NULL)
                break;
            item = lg_GetPubItem(pubKey);
            if (item == NULL) {
                lg_nsslowkey_DestroyPublicKey(pubKey);
                break;
            }
            SHA1_HashBuf(hash, item->data, item->len);
            /* item is imbedded in pubKey, just free the key */
            lg_nsslowkey_DestroyPublicKey(pubKey);
            return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
        case CKA_LABEL:
            return cert->nickname
                       ? lg_CopyAttribute(attribute, type, cert->nickname,
                                          PORT_Strlen(cert->nickname))
                       : LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
        case CKA_SUBJECT:
            return lg_CopyAttribute(attribute, type, cert->derSubject.data,
                                    cert->derSubject.len);
        case CKA_ISSUER:
            return lg_CopyAttribute(attribute, type, cert->derIssuer.data,
                                    cert->derIssuer.len);
        case CKA_SERIAL_NUMBER:
            return lg_CopyAttribute(attribute, type, cert->derSN.data,
                                    cert->derSN.len);
        case CKA_NSS_EMAIL:
            return (cert->emailAddr && cert->emailAddr[0])
                       ? lg_CopyAttribute(attribute, type, cert->emailAddr,
                                          PORT_Strlen(cert->emailAddr))
                       : LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

CK_RV
lg_GetSingleAttribute(LGObjectCache *obj, CK_ATTRIBUTE *attribute)
{
    /* handle the common ones */
    CK_ATTRIBUTE_TYPE type = attribute->type;
    switch (type) {
        case CKA_CLASS:
            return lg_ULongAttribute(attribute, type, obj->objclass);
        case CKA_TOKEN:
            return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr);
        case CKA_LABEL:
            if ((obj->objclass == CKO_CERTIFICATE) ||
                (obj->objclass == CKO_PRIVATE_KEY) ||
                (obj->objclass == CKO_PUBLIC_KEY) ||
                (obj->objclass == CKO_SECRET_KEY)) {
                break;
            }
            return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr);
        default:
            break;
    }
    switch (obj->objclass) {
        case CKO_CERTIFICATE:
            return lg_FindCertAttribute(obj, type, attribute);
        case CKO_NSS_CRL:
            return lg_FindCrlAttribute(obj, type, attribute);
        case CKO_NSS_TRUST:
            return lg_FindTrustAttribute(obj, type, attribute);
        case CKO_NSS_SMIME:
            return lg_FindSMIMEAttribute(obj, type, attribute);
        case CKO_PUBLIC_KEY:
            return lg_FindPublicKeyAttribute(obj, type, attribute);
        case CKO_PRIVATE_KEY:
            return lg_FindPrivateKeyAttribute(obj, type, attribute);
        case CKO_SECRET_KEY:
            return lg_FindSecretKeyAttribute(obj, type, attribute);
        default:
            break;
    }
    return lg_invalidAttribute(attribute);
}

/*
 * Fill in the attribute template based on the data in the database.
 */
CK_RV
lg_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE *templ,
                     CK_ULONG count)
{
    LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK);
    CK_RV crv, crvCollect = CKR_OK;
    unsigned int i;

    if (obj == NULL) {
        return CKR_OBJECT_HANDLE_INVALID;
    }

    for (i = 0; i < count; i++) {
        crv = lg_GetSingleAttribute(obj, &templ[i]);
        if (crvCollect == CKR_OK)
            crvCollect = crv;
    }

    lg_DestroyObjectCache(obj);
    return crvCollect;
}

PRBool
lg_cmpAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attribute)
{
    unsigned char buf[LG_BUF_SPACE];
    CK_ATTRIBUTE testAttr;
    unsigned char *tempBuf = NULL;
    PRBool match = PR_TRUE;
    CK_RV crv;

    /* we're going to compare 'attribute' with the actual attribute from
     * the object. We'll use the length of 'attribute' to decide how much
     * space we need to read the test attribute. If 'attribute' doesn't give
     * enough space, then we know the values don't match and that will
     * show up as ckr != CKR_OK */
    testAttr = *attribute;
    testAttr.pValue = buf;

    /* if we don't have enough space, malloc it */
    if (attribute->ulValueLen > LG_BUF_SPACE) {
        tempBuf = PORT_Alloc(attribute->ulValueLen);
        if (!tempBuf) {
            return PR_FALSE;
        }
        testAttr.pValue = tempBuf;
    }

    /* get the attribute */
    crv = lg_GetSingleAttribute(obj, &testAttr);
    /* if the attribute was read OK, compare it */
    if ((crv != CKR_OK) ||
        (attribute->pValue == NULL) ||
        (attribute->ulValueLen != testAttr.ulValueLen) ||
        (PORT_Memcmp(attribute->pValue, testAttr.pValue, testAttr.ulValueLen) != 0)) {
        /* something didn't match, this isn't the object we are looking for */
        match = PR_FALSE;
    }
    /* free the buffer we may have allocated */
    if (tempBuf) {
        PORT_Free(tempBuf);
    }
    return match;
}

PRBool
lg_tokenMatch(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE class,
              const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    PRBool match = PR_TRUE;
    LGObjectCache *obj = lg_NewObjectCache(sdb, dbKey, class);
    unsigned int i;

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

    for (i = 0; i < count; i++) {
        match = lg_cmpAttribute(obj, &templ[i]);
        if (!match) {
            break;
        }
    }

    /* done looking, free up our cache */
    lg_DestroyObjectCache(obj);

    /* if we get through the whole list without finding a mismatched attribute,
     * then this object fits the criteria we are matching */
    return match;
}

static CK_RV
lg_SetCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
                    const void *value, unsigned int len)
{
    NSSLOWCERTCertificate *cert;
    NSSLOWCERTCertDBHandle *certHandle;
    char *nickname = NULL;
    SECStatus rv;
    CK_RV crv;

    /* we can't change  the EMAIL values, but let the
     * upper layers feel better about the fact we tried to set these */
    if (type == CKA_NSS_EMAIL) {
        return CKR_OK;
    }

    certHandle = lg_getCertDB(obj->sdb);
    if (certHandle == NULL) {
        crv = CKR_TOKEN_WRITE_PROTECTED;
        goto done;
    }

    if ((type != CKA_LABEL) && (type != CKA_ID)) {
        crv = CKR_ATTRIBUTE_READ_ONLY;
        goto done;
    }

    cert = lg_getCert(obj, certHandle);
    if (cert == NULL) {
        crv = CKR_OBJECT_HANDLE_INVALID;
        goto done;
    }

    /* if the app is trying to set CKA_ID, it's probably because it just
     * imported the key. Look to see if we need to set the CERTDB_USER bits.
     */
    if (type == CKA_ID) {
        if (((cert->trust->sslFlags & CERTDB_USER) == 0) &&
            ((cert->trust->emailFlags & CERTDB_USER) == 0) &&
            ((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) {
            NSSLOWKEYDBHandle *keyHandle;

            keyHandle = lg_getKeyDB(obj->sdb);
            if (keyHandle) {
                if (nsslowkey_KeyForCertExists(keyHandle, cert)) {
                    NSSLOWCERTCertTrust trust = *cert->trust;
                    trust.sslFlags |= CERTDB_USER;
                    trust.emailFlags |= CERTDB_USER;
                    trust.objectSigningFlags |= CERTDB_USER;
                    nsslowcert_ChangeCertTrust(certHandle, cert, &trust);
                }
            }
        }
        crv = CKR_OK;
        goto done;
    }

    /* must be CKA_LABEL */
    if (value != NULL) {
        nickname = PORT_ZAlloc(len + 1);
        if (nickname == NULL) {
            crv = CKR_HOST_MEMORY;
            goto done;
        }
        PORT_Memcpy(nickname, value, len);
        nickname[len] = 0;
    }
    rv = nsslowcert_AddPermNickname(certHandle, cert, nickname);
    crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;

done:
    if (nickname) {
        PORT_Free(nickname);
    }
    return crv;
}

static CK_RV
lg_SetPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
                          const void *value, unsigned int len,
                          PRBool *writePrivate)
{
    NSSLOWKEYPrivateKey *privKey;
    NSSLOWKEYDBHandle *keyHandle;
    char *nickname = NULL;
    SECStatus rv;
    CK_RV crv;

    /* we can't change the ID and we don't store the subject, but let the
     * upper layers feel better about the fact we tried to set these */
    if ((type == CKA_ID) || (type == CKA_SUBJECT) ||
        (type == CKA_LOCAL) || (type == CKA_NEVER_EXTRACTABLE) ||
        (type == CKA_ALWAYS_SENSITIVE)) {
        return CKR_OK;
    }

    keyHandle = lg_getKeyDB(obj->sdb);
    if (keyHandle == NULL) {
        crv = CKR_TOKEN_WRITE_PROTECTED;
        goto done;
    }

    privKey = lg_GetPrivateKeyWithDB(obj, keyHandle);
    if (privKey == NULL) {
        crv = CKR_OBJECT_HANDLE_INVALID;
        goto done;
    }

    crv = CKR_ATTRIBUTE_READ_ONLY;
    switch (type) {
        case CKA_LABEL:
            if (value != NULL) {
                nickname = PORT_ZAlloc(len + 1);
                if (nickname == NULL) {
                    crv = CKR_HOST_MEMORY;
                    goto done;
                }
                PORT_Memcpy(nickname, value, len);
                nickname[len] = 0;
            }
            rv = nsslowkey_UpdateNickname(keyHandle, privKey, &obj->dbKey,
                                          nickname, obj->sdb);
            crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
            break;
        case CKA_UNWRAP:
        case CKA_SIGN:
        case CKA_DERIVE:
        case CKA_SIGN_RECOVER:
        case CKA_DECRYPT:
            /* ignore attempts to change restrict these.
             * legacyDB ignore these flags and always presents all of them
             * that are valid as true.
             * NOTE: We only get here if the current value and the new value do
             * not match. */
            if (*(char *)value == 0) {
                crv = CKR_OK;
            }
            break;
        case CKA_VALUE:
        case CKA_PRIVATE_EXPONENT:
        case CKA_PRIME_1:
        case CKA_PRIME_2:
        case CKA_EXPONENT_1:
        case CKA_EXPONENT_2:
        case CKA_COEFFICIENT:
            /* We aren't really changing these values, we are just triggering
     * the database to update it's entry */
            *writePrivate = PR_TRUE;
            crv = CKR_OK;
            break;
        default:
            crv = CKR_ATTRIBUTE_READ_ONLY;
            break;
    }
done:
    if (nickname) {
        PORT_Free(nickname);
    }
    return crv;
}

static CK_RV
lg_SetPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
                         const void *value, unsigned int len,
                         PRBool *writePrivate)
{
    /* we can't change the ID and we don't store the subject, but let the
     * upper layers feel better about the fact we tried to set these */
    if ((type == CKA_ID) || (type == CKA_SUBJECT) || (type == CKA_LABEL)) {
        return CKR_OK;
    }
    return CKR_ATTRIBUTE_READ_ONLY;
}

static CK_RV
lg_SetTrustAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr)
{
    unsigned int flags;
    CK_TRUST trust;
    NSSLOWCERTCertificate *cert = NULL;
    NSSLOWCERTCertDBHandle *certHandle;
    NSSLOWCERTCertTrust dbTrust;
    SECStatus rv;
    CK_RV crv;

    if (attr->type == CKA_LABEL) {
        return CKR_OK;
    }

    crv = lg_GetULongAttribute(attr->type, attr, 1, &trust);
    if (crv != CKR_OK) {
        return crv;
    }
    flags = lg_MapTrust(trust, (PRBool)(attr->type == CKA_TRUST_CLIENT_AUTH));

    certHandle = lg_getCertDB(obj->sdb);

    if (certHandle == NULL) {
        crv = CKR_TOKEN_WRITE_PROTECTED;
        goto done;
    }

    cert = lg_getCert(obj, certHandle);
    if (cert == NULL) {
        crv = CKR_OBJECT_HANDLE_INVALID;
        goto done;
    }
    dbTrust = *cert->trust;

    switch (attr->type) {
        case CKA_TRUST_EMAIL_PROTECTION:
            dbTrust.emailFlags = flags |
                                 (cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS);
            break;
        case CKA_TRUST_CODE_SIGNING:
            dbTrust.objectSigningFlags = flags |
                                         (cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS);
            break;
        case CKA_TRUST_CLIENT_AUTH:
            dbTrust.sslFlags = flags | (cert->trust->sslFlags &
                                        (CERTDB_PRESERVE_TRUST_BITS | CERTDB_TRUSTED_CA));
            break;
        case CKA_TRUST_SERVER_AUTH:
            dbTrust.sslFlags = flags | (cert->trust->sslFlags &
                                        (CERTDB_PRESERVE_TRUST_BITS | CERTDB_TRUSTED_CLIENT_CA));
            break;
        default:
            crv = CKR_ATTRIBUTE_READ_ONLY;
            goto done;
    }

    rv = nsslowcert_ChangeCertTrust(certHandle, cert, &dbTrust);
    crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
done:
    if (cert) {
        nsslowcert_DestroyCertificate(cert);
    }
    return crv;
}

static CK_RV
lg_SetSingleAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr,
                      PRBool *writePrivate)
{
    CK_ATTRIBUTE attribLocal;
    CK_RV crv;

    if ((attr->type == CKA_NETSCAPE_DB) && (obj->objclass == CKO_PRIVATE_KEY)) {
        *writePrivate = PR_TRUE;
        return CKR_OK;
    }

    /* Make sure the attribute exists first */
    attribLocal.type = attr->type;
    attribLocal.pValue = NULL;
    attribLocal.ulValueLen = 0;
    crv = lg_GetSingleAttribute(obj, &attribLocal);
    if (crv != CKR_OK) {
        return crv;
    }

    /* if we are just setting it to the value we already have,
     * allow it to happen. Let label setting go through so
     * we have the opportunity to repair any database corruption. */
    if (attr->type != CKA_LABEL) {
        if (lg_cmpAttribute(obj, attr)) {
            return CKR_OK;
        }
    }

    crv = CKR_ATTRIBUTE_READ_ONLY;
    switch (obj->objclass) {
        case CKO_CERTIFICATE:
            /* change NICKNAME, EMAIL,  */
            crv = lg_SetCertAttribute(obj, attr->type,
                                      attr->pValue, attr->ulValueLen);
            break;
        case CKO_NSS_CRL:
            /* change URL */
            break;
        case CKO_NSS_TRUST:
            crv = lg_SetTrustAttribute(obj, attr);
            break;
        case CKO_PRIVATE_KEY:
        case CKO_SECRET_KEY:
            crv = lg_SetPrivateKeyAttribute(obj, attr->type,
                                            attr->pValue, attr->ulValueLen, writePrivate);
            break;
        case CKO_PUBLIC_KEY:
            crv = lg_SetPublicKeyAttribute(obj, attr->type,
                                           attr->pValue, attr->ulValueLen, writePrivate);
            break;
    }
    return crv;
}

/*
 * Fill in the attribute template based on the data in the database.
 */
CK_RV
lg_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle,
                     const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK);
    CK_RV crv, crvCollect = CKR_OK;
    PRBool writePrivate = PR_FALSE;
    unsigned int i;

    if (obj == NULL) {
        return CKR_OBJECT_HANDLE_INVALID;
    }

    for (i = 0; i < count; i++) {
        crv = lg_SetSingleAttribute(obj, &templ[i], &writePrivate);
        if (crvCollect == CKR_OK)
            crvCollect = crv;
    }

    /* Write any collected changes out for private and secret keys.
     *  don't do the write for just the label */
    if (writePrivate) {
        NSSLOWKEYPrivateKey *privKey = lg_GetPrivateKey(obj);
        SECStatus rv = SECFailure;
        char *label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);

        if (privKey) {
            rv = nsslowkey_StoreKeyByPublicKeyAlg(lg_getKeyDB(sdb), privKey,
                                                  &obj->dbKey, label, sdb, PR_TRUE);
        }
        if (rv != SECSuccess) {
            crv = CKR_DEVICE_ERROR;
        }
        PORT_Free(label);
    }

    lg_DestroyObjectCache(obj);
    return crvCollect;
}
