/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
 *  The following code handles the storage of PKCS 11 modules used by the
 * NSS. For the rest of NSS, only one kind of database handle exists:
 *
 *     SFTKDBHandle
 *
 * There is one SFTKDBHandle for the each key database and one for each cert
 * database. These databases are opened as associated pairs, one pair per
 * slot. SFTKDBHandles are reference counted objects.
 *
 * Each SFTKDBHandle points to a low level database handle (SDB). This handle
 * represents the underlying physical database. These objects are not
 * reference counted, an are 'owned' by their respective SFTKDBHandles.
 *
 *
 */
#include "sftkdb.h"
#include "sftkdbti.h"
#include "pkcs11t.h"
#include "pkcs11i.h"
#include "sdb.h"
#include "prprf.h"
#include "pratom.h"
#include "lgglue.h"
#include "utilpars.h"
#include "secerr.h"
#include "softoken.h"
#if defined(_WIN32)
#include <windows.h>
#endif

/*
 * We want all databases to have the same binary representation independent of
 * endianness or length of the host architecture. In general PKCS #11 attributes
 * are endian/length independent except those attributes that pass CK_ULONG.
 *
 * The following functions fixes up the CK_ULONG type attributes so that the data
 * base sees a machine independent view. CK_ULONGs are stored as 4 byte network
 * byte order values (big endian).
 */
#define BBP 8

PRBool
sftkdb_isULONGAttribute(CK_ATTRIBUTE_TYPE type)
{
    switch (type) {
        case CKA_CERTIFICATE_CATEGORY:
        case CKA_CERTIFICATE_TYPE:
        case CKA_CLASS:
        case CKA_JAVA_MIDP_SECURITY_DOMAIN:
        case CKA_KEY_GEN_MECHANISM:
        case CKA_KEY_TYPE:
        case CKA_MECHANISM_TYPE:
        case CKA_MODULUS_BITS:
        case CKA_PRIME_BITS:
        case CKA_SUBPRIME_BITS:
        case CKA_VALUE_BITS:
        case CKA_VALUE_LEN:

        case CKA_TRUST_DIGITAL_SIGNATURE:
        case CKA_TRUST_NON_REPUDIATION:
        case CKA_TRUST_KEY_ENCIPHERMENT:
        case CKA_TRUST_DATA_ENCIPHERMENT:
        case CKA_TRUST_KEY_AGREEMENT:
        case CKA_TRUST_KEY_CERT_SIGN:
        case CKA_TRUST_CRL_SIGN:

        case CKA_TRUST_SERVER_AUTH:
        case CKA_TRUST_CLIENT_AUTH:
        case CKA_TRUST_CODE_SIGNING:
        case CKA_TRUST_EMAIL_PROTECTION:
        case CKA_TRUST_IPSEC_END_SYSTEM:
        case CKA_TRUST_IPSEC_TUNNEL:
        case CKA_TRUST_IPSEC_USER:
        case CKA_TRUST_TIME_STAMPING:
        case CKA_TRUST_STEP_UP_APPROVED:
            return PR_TRUE;
        default:
            break;
    }
    return PR_FALSE;
}

/* are the attributes private? */
static PRBool
sftkdb_isPrivateAttribute(CK_ATTRIBUTE_TYPE type)
{
    switch (type) {
        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:
            return PR_TRUE;
        default:
            break;
    }
    return PR_FALSE;
}

/* These attributes must be authenticated with an hmac. */
static PRBool
sftkdb_isAuthenticatedAttribute(CK_ATTRIBUTE_TYPE type)
{
    switch (type) {
        case CKA_MODULUS:
        case CKA_PUBLIC_EXPONENT:
        case CKA_CERT_SHA1_HASH:
        case CKA_CERT_MD5_HASH:
        case CKA_TRUST_SERVER_AUTH:
        case CKA_TRUST_CLIENT_AUTH:
        case CKA_TRUST_EMAIL_PROTECTION:
        case CKA_TRUST_CODE_SIGNING:
        case CKA_TRUST_STEP_UP_APPROVED:
        case CKA_NSS_OVERRIDE_EXTENSIONS:
            return PR_TRUE;
        default:
            break;
    }
    return PR_FALSE;
}

/*
 * convert a native ULONG to a database ulong. Database ulong's
 * are all 4 byte big endian values.
 */
void
sftk_ULong2SDBULong(unsigned char *data, CK_ULONG value)
{
    int i;

    for (i = 0; i < SDB_ULONG_SIZE; i++) {
        data[i] = (value >> (SDB_ULONG_SIZE - 1 - i) * BBP) & 0xff;
    }
}

/*
 * convert a database ulong back to a native ULONG. (reverse of the above
 * function.
 */
static CK_ULONG
sftk_SDBULong2ULong(unsigned char *data)
{
    int i;
    CK_ULONG value = 0;

    for (i = 0; i < SDB_ULONG_SIZE; i++) {
        value |= (((CK_ULONG)data[i]) << (SDB_ULONG_SIZE - 1 - i) * BBP);
    }
    return value;
}

/*
 * fix up the input templates. Our fixed up ints are stored in data and must
 * be freed by the caller. The new template must also be freed. If there are no
 * CK_ULONG attributes, the orignal template is passed in as is.
 */
static CK_ATTRIBUTE *
sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count,
                       unsigned char **dataOut)
{
    int i;
    int ulongCount = 0;
    unsigned char *data;
    CK_ATTRIBUTE *ntemplate;

    *dataOut = NULL;

    /* first count the number of CK_ULONG attributes */
    for (i = 0; i < count; i++) {
        /* Don't 'fixup' NULL values */
        if (!template[i].pValue) {
            continue;
        }
        if (template[i].ulValueLen == sizeof(CK_ULONG)) {
            if (sftkdb_isULONGAttribute(template[i].type)) {
                ulongCount++;
            }
        }
    }
    /* no attributes to fixup, just call on through */
    if (ulongCount == 0) {
        return (CK_ATTRIBUTE *)template;
    }

    /* allocate space for new ULONGS */
    data = (unsigned char *)PORT_Alloc(SDB_ULONG_SIZE * ulongCount);
    if (!data) {
        return NULL;
    }

    /* allocate new template */
    ntemplate = PORT_NewArray(CK_ATTRIBUTE, count);
    if (!ntemplate) {
        PORT_Free(data);
        return NULL;
    }
    *dataOut = data;
    /* copy the old template, fixup the actual ulongs */
    for (i = 0; i < count; i++) {
        ntemplate[i] = template[i];
        /* Don't 'fixup' NULL values */
        if (!template[i].pValue) {
            continue;
        }
        if (template[i].ulValueLen == sizeof(CK_ULONG)) {
            if (sftkdb_isULONGAttribute(template[i].type)) {
                CK_ULONG value = *(CK_ULONG *)template[i].pValue;
                sftk_ULong2SDBULong(data, value);
                ntemplate[i].pValue = data;
                ntemplate[i].ulValueLen = SDB_ULONG_SIZE;
                data += SDB_ULONG_SIZE;
            }
        }
    }
    return ntemplate;
}

static const char SFTKDB_META_SIG_TEMPLATE[] = "sig_%s_%08x_%08x";

/*
 * return a string describing the database type (key or cert)
 */
const char *
sftkdb_TypeString(SFTKDBHandle *handle)
{
    return (handle->type == SFTK_KEYDB_TYPE) ? "key" : "cert";
}

/*
 * Some attributes are signed with an Hmac and a pbe key generated from
 * the password. This signature is stored indexed by object handle and
 * attribute type in the meta data table in the key database.
 *
 * Signature entries are indexed by the string
 * sig_[cert/key]_{ObjectID}_{Attribute}
 *
 * This function fetches that pkcs5 signature. Caller supplies a SECItem
 * pre-allocated to the appropriate size if the SECItem is too small the
 * function will fail with CKR_BUFFER_TOO_SMALL.
 */
static CK_RV
sftkdb_getAttributeSignature(SFTKDBHandle *handle, SFTKDBHandle *keyHandle,
                             CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE type,
                             SECItem *signText)
{
    SDB *db;
    char id[30];
    CK_RV crv;

    db = SFTK_GET_SDB(keyHandle);

    sprintf(id, SFTKDB_META_SIG_TEMPLATE,
            sftkdb_TypeString(handle),
            (unsigned int)objectID, (unsigned int)type);

    crv = (*db->sdb_GetMetaData)(db, id, signText, NULL);
    return crv;
}

/*
 * Some attributes are signed with an Hmac and a pbe key generated from
 * the password. This signature is stored indexed by object handle and
 * attribute type in the meta data table in the key database.
 *
 * Signature entries are indexed by the string
 * sig_[cert/key]_{ObjectID}_{Attribute}
 *
 * This function stores that pkcs5 signature.
 */
CK_RV
sftkdb_PutAttributeSignature(SFTKDBHandle *handle, SDB *keyTarget,
                             CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE type,
                             SECItem *signText)
{
    char id[30];
    CK_RV crv;

    sprintf(id, SFTKDB_META_SIG_TEMPLATE,
            sftkdb_TypeString(handle),
            (unsigned int)objectID, (unsigned int)type);

    crv = (*keyTarget->sdb_PutMetaData)(keyTarget, id, signText, NULL);
    return crv;
}

/*
 * fix up returned data. NOTE: sftkdb_fixupTemplateIn has already allocated
 * separate data sections for the database ULONG values.
 */
static CK_RV
sftkdb_fixupTemplateOut(CK_ATTRIBUTE *template, CK_OBJECT_HANDLE objectID,
                        CK_ATTRIBUTE *ntemplate, int count, SFTKDBHandle *handle)
{
    int i;
    CK_RV crv = CKR_OK;
    SFTKDBHandle *keyHandle;
    PRBool checkSig = PR_TRUE;
    PRBool checkEnc = PR_TRUE;

    PORT_Assert(handle);

    /* find the key handle */
    keyHandle = handle;
    if (handle->type != SFTK_KEYDB_TYPE) {
        checkEnc = PR_FALSE;
        keyHandle = handle->peerDB;
    }

    if ((keyHandle == NULL) ||
        ((SFTK_GET_SDB(keyHandle)->sdb_flags & SDB_HAS_META) == 0) ||
        (keyHandle->passwordKey.data == NULL)) {
        checkSig = PR_FALSE;
    }

    for (i = 0; i < count; i++) {
        CK_ULONG length = template[i].ulValueLen;
        template[i].ulValueLen = ntemplate[i].ulValueLen;
        /* fixup ulongs */
        if (ntemplate[i].ulValueLen == SDB_ULONG_SIZE) {
            if (sftkdb_isULONGAttribute(template[i].type)) {
                if (template[i].pValue) {
                    CK_ULONG value;

                    value = sftk_SDBULong2ULong(ntemplate[i].pValue);
                    if (length < sizeof(CK_ULONG)) {
                        template[i].ulValueLen = -1;
                        crv = CKR_BUFFER_TOO_SMALL;
                        continue;
                    }
                    PORT_Memcpy(template[i].pValue, &value, sizeof(CK_ULONG));
                }
                template[i].ulValueLen = sizeof(CK_ULONG);
            }
        }

        /* if no data was retrieved, no need to process encrypted or signed
         * attributes */
        if ((template[i].pValue == NULL) || (template[i].ulValueLen == -1)) {
            continue;
        }

        /* fixup private attributes */
        if (checkEnc && sftkdb_isPrivateAttribute(ntemplate[i].type)) {
            /* we have a private attribute */
            /* This code depends on the fact that the cipherText is bigger
             * than the plain text */
            SECItem cipherText;
            SECItem *plainText;
            SECStatus rv;

            cipherText.data = ntemplate[i].pValue;
            cipherText.len = ntemplate[i].ulValueLen;
            PZ_Lock(handle->passwordLock);
            if (handle->passwordKey.data == NULL) {
                PZ_Unlock(handle->passwordLock);
                template[i].ulValueLen = -1;
                crv = CKR_USER_NOT_LOGGED_IN;
                continue;
            }
            rv = sftkdb_DecryptAttribute(&handle->passwordKey,
                                         &cipherText, &plainText);
            PZ_Unlock(handle->passwordLock);
            if (rv != SECSuccess) {
                PORT_Memset(template[i].pValue, 0, template[i].ulValueLen);
                template[i].ulValueLen = -1;
                crv = CKR_GENERAL_ERROR;
                continue;
            }
            PORT_Assert(template[i].ulValueLen >= plainText->len);
            if (template[i].ulValueLen < plainText->len) {
                SECITEM_FreeItem(plainText, PR_TRUE);
                PORT_Memset(template[i].pValue, 0, template[i].ulValueLen);
                template[i].ulValueLen = -1;
                crv = CKR_GENERAL_ERROR;
                continue;
            }

            /* copy the plain text back into the template */
            PORT_Memcpy(template[i].pValue, plainText->data, plainText->len);
            template[i].ulValueLen = plainText->len;
            SECITEM_FreeItem(plainText, PR_TRUE);
        }
        /* make sure signed attributes are valid */
        if (checkSig && sftkdb_isAuthenticatedAttribute(ntemplate[i].type)) {
            SECStatus rv;
            SECItem signText;
            SECItem plainText;
            unsigned char signData[SDB_MAX_META_DATA_LEN];

            signText.data = signData;
            signText.len = sizeof(signData);

            rv = sftkdb_getAttributeSignature(handle, keyHandle,
                                              objectID, ntemplate[i].type, &signText);
            if (rv != SECSuccess) {
                PORT_Memset(template[i].pValue, 0, template[i].ulValueLen);
                template[i].ulValueLen = -1;
                crv = CKR_DATA_INVALID; /* better error code? */
                continue;
            }

            plainText.data = ntemplate[i].pValue;
            plainText.len = ntemplate[i].ulValueLen;

            /*
             * we do a second check holding the lock just in case the user
             * loggout while we were trying to get the signature.
             */
            PZ_Lock(keyHandle->passwordLock);
            if (keyHandle->passwordKey.data == NULL) {
                /* if we are no longer logged in, no use checking the other
                 * Signatures either. */
                checkSig = PR_FALSE;
                PZ_Unlock(keyHandle->passwordLock);
                continue;
            }

            rv = sftkdb_VerifyAttribute(&keyHandle->passwordKey,
                                        objectID, ntemplate[i].type,
                                        &plainText, &signText);
            PZ_Unlock(keyHandle->passwordLock);
            if (rv != SECSuccess) {
                PORT_Memset(template[i].pValue, 0, template[i].ulValueLen);
                template[i].ulValueLen = -1;
                crv = CKR_SIGNATURE_INVALID; /* better error code? */
            }
            /* This Attribute is fine */
        }
    }
    return crv;
}

/*
 * Some attributes are signed with an HMAC and a pbe key generated from
 * the password. This signature is stored indexed by object handle and
 *
 * Those attributes are:
 * 1) Trust object hashes and trust values.
 * 2) public key values.
 *
 * Certs themselves are considered properly authenticated by virtue of their
 * signature, or their matching hash with the trust object.
 *
 * These signature is only checked for objects coming from shared databases.
 * Older dbm style databases have such no signature checks. HMACs are also
 * only checked when the token is logged in, as it requires a pbe generated
 * from the password.
 *
 * Tokens which have no key database (and therefore no master password) do not
 * have any stored signature values. Signature values are stored in the key
 * database, since the signature data is tightly coupled to the key database
 * password.
 *
 * This function takes a template of attributes that were either created or
 * modified. These attributes are checked to see if the need to be signed.
 * If they do, then this function signs the attributes and writes them
 * to the meta data store.
 *
 * This function can fail if there are attributes that must be signed, but
 * the token is not logged in.
 *
 * The caller is expected to abort any transaction he was in in the
 * event of a failure of this function.
 */
static CK_RV
sftk_signTemplate(PLArenaPool *arena, SFTKDBHandle *handle,
                  PRBool mayBeUpdateDB,
                  CK_OBJECT_HANDLE objectID, const CK_ATTRIBUTE *template,
                  CK_ULONG count)
{
    unsigned int i;
    CK_RV crv;
    SFTKDBHandle *keyHandle = handle;
    SDB *keyTarget = NULL;
    PRBool usingPeerDB = PR_FALSE;
    PRBool inPeerDBTransaction = PR_FALSE;

    PORT_Assert(handle);

    if (handle->type != SFTK_KEYDB_TYPE) {
        keyHandle = handle->peerDB;
        usingPeerDB = PR_TRUE;
    }

    /* no key DB defined? then no need to sign anything */
    if (keyHandle == NULL) {
        crv = CKR_OK;
        goto loser;
    }

    /* When we are in a middle of an update, we have an update database set,
     * but we want to write to the real database. The bool mayBeUpdateDB is
     * set to TRUE if it's possible that we want to write an update database
     * rather than a primary */
    keyTarget = (mayBeUpdateDB && keyHandle->update) ? keyHandle->update : keyHandle->db;

    /* skip the the database does not support meta data */
    if ((keyTarget->sdb_flags & SDB_HAS_META) == 0) {
        crv = CKR_OK;
        goto loser;
    }

    /* If we had to switch databases, we need to initialize a transaction. */
    if (usingPeerDB) {
        crv = (*keyTarget->sdb_Begin)(keyTarget);
        if (crv != CKR_OK) {
            goto loser;
        }
        inPeerDBTransaction = PR_TRUE;
    }

    for (i = 0; i < count; i++) {
        if (sftkdb_isAuthenticatedAttribute(template[i].type)) {
            SECStatus rv;
            SECItem *signText;
            SECItem plainText;

            plainText.data = template[i].pValue;
            plainText.len = template[i].ulValueLen;
            PZ_Lock(keyHandle->passwordLock);
            if (keyHandle->passwordKey.data == NULL) {
                PZ_Unlock(keyHandle->passwordLock);
                crv = CKR_USER_NOT_LOGGED_IN;
                goto loser;
            }
            rv = sftkdb_SignAttribute(arena, &keyHandle->passwordKey,
                                      objectID, template[i].type,
                                      &plainText, &signText);
            PZ_Unlock(keyHandle->passwordLock);
            if (rv != SECSuccess) {
                crv = CKR_GENERAL_ERROR; /* better error code here? */
                goto loser;
            }
            rv = sftkdb_PutAttributeSignature(handle, keyTarget,
                                              objectID, template[i].type, signText);
            if (rv != SECSuccess) {
                crv = CKR_GENERAL_ERROR; /* better error code here? */
                goto loser;
            }
        }
    }
    crv = CKR_OK;

    /* If necessary, commit the transaction */
    if (inPeerDBTransaction) {
        crv = (*keyTarget->sdb_Commit)(keyTarget);
        if (crv != CKR_OK) {
            goto loser;
        }
        inPeerDBTransaction = PR_FALSE;
    }

loser:
    if (inPeerDBTransaction) {
        /* The transaction must have failed. Abort. */
        (*keyTarget->sdb_Abort)(keyTarget);
        PORT_Assert(crv != CKR_OK);
        if (crv == CKR_OK)
            crv = CKR_GENERAL_ERROR;
    }
    return crv;
}

static CK_RV
sftkdb_CreateObject(PLArenaPool *arena, SFTKDBHandle *handle,
                    SDB *db, CK_OBJECT_HANDLE *objectID,
                    CK_ATTRIBUTE *template, CK_ULONG count)
{
    CK_RV crv;

    crv = (*db->sdb_CreateObject)(db, objectID, template, count);
    if (crv != CKR_OK) {
        goto loser;
    }
    crv = sftk_signTemplate(arena, handle, (db == handle->update),
                            *objectID, template, count);
loser:

    return crv;
}

CK_ATTRIBUTE *
sftk_ExtractTemplate(PLArenaPool *arena, SFTKObject *object,
                     SFTKDBHandle *handle, CK_ULONG *pcount,
                     CK_RV *crv)
{
    unsigned int count;
    CK_ATTRIBUTE *template;
    unsigned int i, templateIndex;
    SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
    PRBool doEnc = PR_TRUE;

    *crv = CKR_OK;

    if (sessObject == NULL) {
        *crv = CKR_GENERAL_ERROR; /* internal programming error */
        return NULL;
    }

    PORT_Assert(handle);
    /* find the key handle */
    if (handle->type != SFTK_KEYDB_TYPE) {
        doEnc = PR_FALSE;
    }

    PZ_Lock(sessObject->attributeLock);
    count = 0;
    for (i = 0; i < sessObject->hashSize; i++) {
        SFTKAttribute *attr;
        for (attr = sessObject->head[i]; attr; attr = attr->next) {
            count++;
        }
    }
    template = PORT_ArenaNewArray(arena, CK_ATTRIBUTE, count);
    if (template == NULL) {
        PZ_Unlock(sessObject->attributeLock);
        *crv = CKR_HOST_MEMORY;
        return NULL;
    }
    templateIndex = 0;
    for (i = 0; i < sessObject->hashSize; i++) {
        SFTKAttribute *attr;
        for (attr = sessObject->head[i]; attr; attr = attr->next) {
            CK_ATTRIBUTE *tp = &template[templateIndex++];
            /* copy the attribute */
            *tp = attr->attrib;

            /* fixup  ULONG s */
            if ((tp->ulValueLen == sizeof(CK_ULONG)) &&
                (sftkdb_isULONGAttribute(tp->type))) {
                CK_ULONG value = *(CK_ULONG *)tp->pValue;
                unsigned char *data;

                tp->pValue = PORT_ArenaAlloc(arena, SDB_ULONG_SIZE);
                data = (unsigned char *)tp->pValue;
                if (data == NULL) {
                    *crv = CKR_HOST_MEMORY;
                    break;
                }
                sftk_ULong2SDBULong(data, value);
                tp->ulValueLen = SDB_ULONG_SIZE;
            }

            /* encrypt private attributes */
            if (doEnc && sftkdb_isPrivateAttribute(tp->type)) {
                /* we have a private attribute */
                SECItem *cipherText;
                SECItem plainText;
                SECStatus rv;

                plainText.data = tp->pValue;
                plainText.len = tp->ulValueLen;
                PZ_Lock(handle->passwordLock);
                if (handle->passwordKey.data == NULL) {
                    PZ_Unlock(handle->passwordLock);
                    *crv = CKR_USER_NOT_LOGGED_IN;
                    break;
                }
                rv = sftkdb_EncryptAttribute(arena, &handle->passwordKey,
                                             &plainText, &cipherText);
                PZ_Unlock(handle->passwordLock);
                if (rv == SECSuccess) {
                    tp->pValue = cipherText->data;
                    tp->ulValueLen = cipherText->len;
                } else {
                    *crv = CKR_GENERAL_ERROR; /* better error code here? */
                    break;
                }
                PORT_Memset(plainText.data, 0, plainText.len);
            }
        }
    }
    PORT_Assert(templateIndex <= count);
    PZ_Unlock(sessObject->attributeLock);

    if (*crv != CKR_OK) {
        return NULL;
    }
    if (pcount) {
        *pcount = count;
    }
    return template;
}

/*
 * return a pointer to the attribute in the give template.
 * The return value is not const, as the caller may modify
 * the given attribute value, but such modifications will
 * modify the actual value in the template.
 */
static CK_ATTRIBUTE *
sftkdb_getAttributeFromTemplate(CK_ATTRIBUTE_TYPE attribute,
                                CK_ATTRIBUTE *ptemplate, CK_ULONG len)
{
    CK_ULONG i;

    for (i = 0; i < len; i++) {
        if (attribute == ptemplate[i].type) {
            return &ptemplate[i];
        }
    }
    return NULL;
}

static const CK_ATTRIBUTE *
sftkdb_getAttributeFromConstTemplate(CK_ATTRIBUTE_TYPE attribute,
                                     const CK_ATTRIBUTE *ptemplate, CK_ULONG len)
{
    CK_ULONG i;

    for (i = 0; i < len; i++) {
        if (attribute == ptemplate[i].type) {
            return &ptemplate[i];
        }
    }
    return NULL;
}

/*
 * fetch a template which identifies 'unique' entries based on object type
 */
static CK_RV
sftkdb_getFindTemplate(CK_OBJECT_CLASS objectType, unsigned char *objTypeData,
                       CK_ATTRIBUTE *findTemplate, CK_ULONG *findCount,
                       CK_ATTRIBUTE *ptemplate, int len)
{
    CK_ATTRIBUTE *attr;
    CK_ULONG count = 1;

    sftk_ULong2SDBULong(objTypeData, objectType);
    findTemplate[0].type = CKA_CLASS;
    findTemplate[0].pValue = objTypeData;
    findTemplate[0].ulValueLen = SDB_ULONG_SIZE;

    switch (objectType) {
        case CKO_CERTIFICATE:
        case CKO_NSS_TRUST:
            attr = sftkdb_getAttributeFromTemplate(CKA_ISSUER, ptemplate, len);
            if (attr == NULL) {
                return CKR_TEMPLATE_INCOMPLETE;
            }
            findTemplate[1] = *attr;
            attr = sftkdb_getAttributeFromTemplate(CKA_SERIAL_NUMBER,
                                                   ptemplate, len);
            if (attr == NULL) {
                return CKR_TEMPLATE_INCOMPLETE;
            }
            findTemplate[2] = *attr;
            count = 3;
            break;

        case CKO_PRIVATE_KEY:
        case CKO_PUBLIC_KEY:
        case CKO_SECRET_KEY:
            attr = sftkdb_getAttributeFromTemplate(CKA_ID, ptemplate, len);
            if (attr == NULL) {
                return CKR_TEMPLATE_INCOMPLETE;
            }
            if (attr->ulValueLen == 0) {
                /* key is too generic to determine that it's unique, usually
                 * happens in the key gen case */
                return CKR_OBJECT_HANDLE_INVALID;
            }

            findTemplate[1] = *attr;
            count = 2;
            break;

        case CKO_NSS_CRL:
            attr = sftkdb_getAttributeFromTemplate(CKA_SUBJECT, ptemplate, len);
            if (attr == NULL) {
                return CKR_TEMPLATE_INCOMPLETE;
            }
            findTemplate[1] = *attr;
            count = 2;
            break;

        case CKO_NSS_SMIME:
            attr = sftkdb_getAttributeFromTemplate(CKA_SUBJECT, ptemplate, len);
            if (attr == NULL) {
                return CKR_TEMPLATE_INCOMPLETE;
            }
            findTemplate[1] = *attr;
            attr = sftkdb_getAttributeFromTemplate(CKA_NSS_EMAIL, ptemplate, len);
            if (attr == NULL) {
                return CKR_TEMPLATE_INCOMPLETE;
            }
            findTemplate[2] = *attr;
            count = 3;
            break;
        default:
            attr = sftkdb_getAttributeFromTemplate(CKA_VALUE, ptemplate, len);
            if (attr == NULL) {
                return CKR_TEMPLATE_INCOMPLETE;
            }
            findTemplate[1] = *attr;
            count = 2;
            break;
    }
    *findCount = count;

    return CKR_OK;
}

/*
 * look to see if this object already exists and return its object ID if
 * it does.
 */
static CK_RV
sftkdb_lookupObject(SDB *db, CK_OBJECT_CLASS objectType,
                    CK_OBJECT_HANDLE *id, CK_ATTRIBUTE *ptemplate, CK_ULONG len)
{
    CK_ATTRIBUTE findTemplate[3];
    CK_ULONG count = 1;
    CK_ULONG objCount = 0;
    SDBFind *find = NULL;
    unsigned char objTypeData[SDB_ULONG_SIZE];
    CK_RV crv;

    *id = CK_INVALID_HANDLE;
    if (objectType == CKO_NSS_CRL) {
        return CKR_OK;
    }
    crv = sftkdb_getFindTemplate(objectType, objTypeData,
                                 findTemplate, &count, ptemplate, len);

    if (crv == CKR_OBJECT_HANDLE_INVALID) {
        /* key is too generic to determine that it's unique, usually
         * happens in the key gen case, tell the caller to go ahead
         * and just create it */
        return CKR_OK;
    }
    if (crv != CKR_OK) {
        return crv;
    }

    /* use the raw find, so we get the correct database */
    crv = (*db->sdb_FindObjectsInit)(db, findTemplate, count, &find);
    if (crv != CKR_OK) {
        return crv;
    }
    (*db->sdb_FindObjects)(db, find, id, 1, &objCount);
    (*db->sdb_FindObjectsFinal)(db, find);

    if (objCount == 0) {
        *id = CK_INVALID_HANDLE;
    }
    return CKR_OK;
}

/*
 * check to see if this template conflicts with others in our current database.
 */
static CK_RV
sftkdb_checkConflicts(SDB *db, CK_OBJECT_CLASS objectType,
                      const CK_ATTRIBUTE *ptemplate, CK_ULONG len,
                      CK_OBJECT_HANDLE sourceID)
{
    CK_ATTRIBUTE findTemplate[2];
    unsigned char objTypeData[SDB_ULONG_SIZE];
    /* we may need to allocate some temporaries. Keep track of what was
     * allocated so we can free it in the end */
    unsigned char *temp1 = NULL;
    unsigned char *temp2 = NULL;
    CK_ULONG objCount = 0;
    SDBFind *find = NULL;
    CK_OBJECT_HANDLE id;
    const CK_ATTRIBUTE *attr, *attr2;
    CK_RV crv;
    CK_ATTRIBUTE subject;

    /* Currently the only conflict is with nicknames pointing to the same
     * subject when creating or modifying a certificate. */
    /* If the object is not a cert, no problem. */
    if (objectType != CKO_CERTIFICATE) {
        return CKR_OK;
    }
    /* if not setting a nickname then there's still no problem */
    attr = sftkdb_getAttributeFromConstTemplate(CKA_LABEL, ptemplate, len);
    if ((attr == NULL) || (attr->ulValueLen == 0)) {
        return CKR_OK;
    }
    /* fetch the subject of the source. For creation and merge, this should
     * be found in the template */
    attr2 = sftkdb_getAttributeFromConstTemplate(CKA_SUBJECT, ptemplate, len);
    if (sourceID == CK_INVALID_HANDLE) {
        if ((attr2 == NULL) || ((CK_LONG)attr2->ulValueLen < 0)) {
            crv = CKR_TEMPLATE_INCOMPLETE;
            goto done;
        }
    } else if ((attr2 == NULL) || ((CK_LONG)attr2->ulValueLen <= 0)) {
        /* sourceID is set if we are trying to modify an existing entry instead
         * of creating a new one. In this case the subject may not be (probably
         * isn't) in the template, we have to read it from the database */
        subject.type = CKA_SUBJECT;
        subject.pValue = NULL;
        subject.ulValueLen = 0;
        crv = (*db->sdb_GetAttributeValue)(db, sourceID, &subject, 1);
        if (crv != CKR_OK) {
            goto done;
        }
        if ((CK_LONG)subject.ulValueLen < 0) {
            crv = CKR_DEVICE_ERROR; /* closest pkcs11 error to corrupted DB */
            goto done;
        }
        temp1 = subject.pValue = PORT_Alloc(++subject.ulValueLen);
        if (temp1 == NULL) {
            crv = CKR_HOST_MEMORY;
            goto done;
        }
        crv = (*db->sdb_GetAttributeValue)(db, sourceID, &subject, 1);
        if (crv != CKR_OK) {
            goto done;
        }
        attr2 = &subject;
    }

    /* check for another cert in the database with the same nickname */
    sftk_ULong2SDBULong(objTypeData, objectType);
    findTemplate[0].type = CKA_CLASS;
    findTemplate[0].pValue = objTypeData;
    findTemplate[0].ulValueLen = SDB_ULONG_SIZE;
    findTemplate[1] = *attr;

    crv = (*db->sdb_FindObjectsInit)(db, findTemplate, 2, &find);
    if (crv != CKR_OK) {
        goto done;
    }
    (*db->sdb_FindObjects)(db, find, &id, 1, &objCount);
    (*db->sdb_FindObjectsFinal)(db, find);

    /* object count == 0 means no conflicting certs found,
     * go on with the operation */
    if (objCount == 0) {
        crv = CKR_OK;
        goto done;
    }

    /* There is a least one cert that shares the nickname, make sure it also
     * matches the subject. */
    findTemplate[0] = *attr2;
    /* we know how big the source subject was. Use that length to create the
     * space for the target. If it's not enough space, then it means the
     * source subject is too big, and therefore not a match. GetAttributeValue
     * will return CKR_BUFFER_TOO_SMALL. Otherwise it should be exactly enough
     * space (or enough space to be able to compare the result. */
    temp2 = findTemplate[0].pValue = PORT_Alloc(++findTemplate[0].ulValueLen);
    if (temp2 == NULL) {
        crv = CKR_HOST_MEMORY;
        goto done;
    }
    crv = (*db->sdb_GetAttributeValue)(db, id, findTemplate, 1);
    if (crv != CKR_OK) {
        if (crv == CKR_BUFFER_TOO_SMALL) {
            /* if our buffer is too small, then the Subjects clearly do
             * not match */
            crv = CKR_ATTRIBUTE_VALUE_INVALID;
            goto loser;
        }
        /* otherwise we couldn't get the value, just fail */
        goto done;
    }

    /* Ok, we have both subjects, make sure they are the same.
     * Compare the subjects */
    if ((findTemplate[0].ulValueLen != attr2->ulValueLen) ||
        (attr2->ulValueLen > 0 &&
         PORT_Memcmp(findTemplate[0].pValue, attr2->pValue, attr2->ulValueLen) != 0)) {
        crv = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }
    crv = CKR_OK;

done:
    /* If we've failed for some other reason than a conflict, make sure we
     * return an error code other than CKR_ATTRIBUTE_VALUE_INVALID.
     * (NOTE: neither sdb_FindObjectsInit nor sdb_GetAttributeValue should
     * return CKR_ATTRIBUTE_VALUE_INVALID, so the following is paranoia).
     */
    if (crv == CKR_ATTRIBUTE_VALUE_INVALID) {
        crv = CKR_GENERAL_ERROR; /* clearly a programming error */
    }

/* exit point if we found a conflict */
loser:
    PORT_Free(temp1);
    PORT_Free(temp2);
    return crv;
}

/*
 * try to update the template to fix any errors. This is only done
 * during update.
 *
 * NOTE: we must update the template or return an error, or the update caller
 * will loop forever!
 *
 * Two copies of the source code for this algorithm exist in NSS.
 * Changes must be made in both copies.
 * The other copy is in pk11_IncrementNickname() in pk11wrap/pk11merge.c.
 *
 */
static CK_RV
sftkdb_resolveConflicts(PLArenaPool *arena, CK_OBJECT_CLASS objectType,
                        CK_ATTRIBUTE *ptemplate, CK_ULONG *plen)
{
    CK_ATTRIBUTE *attr;
    char *nickname, *newNickname;
    unsigned int end, digit;

    /* sanity checks. We should never get here with these errors */
    if (objectType != CKO_CERTIFICATE) {
        return CKR_GENERAL_ERROR; /* shouldn't happen */
    }
    attr = sftkdb_getAttributeFromTemplate(CKA_LABEL, ptemplate, *plen);
    if ((attr == NULL) || (attr->ulValueLen == 0)) {
        return CKR_GENERAL_ERROR; /* shouldn't happen */
    }

    /* update the nickname */
    /* is there a number at the end of the nickname already?
     * if so just increment that number  */
    nickname = (char *)attr->pValue;

    /* does nickname end with " #n*" ? */
    for (end = attr->ulValueLen - 1;
         end >= 2 && (digit = nickname[end]) <= '9' && digit >= '0';
         end--) /* just scan */
        ;
    if (attr->ulValueLen >= 3 &&
        end < (attr->ulValueLen - 1) /* at least one digit */ &&
        nickname[end] == '#' &&
        nickname[end - 1] == ' ') {
        /* Already has a suitable suffix string */
    } else {
        /* ... append " #2" to the name */
        static const char num2[] = " #2";
        newNickname = PORT_ArenaAlloc(arena, attr->ulValueLen + sizeof(num2));
        if (!newNickname) {
            return CKR_HOST_MEMORY;
        }
        PORT_Memcpy(newNickname, nickname, attr->ulValueLen);
        PORT_Memcpy(&newNickname[attr->ulValueLen], num2, sizeof(num2));
        attr->pValue = newNickname; /* modifies ptemplate */
        attr->ulValueLen += 3;      /* 3 is strlen(num2)  */
        return CKR_OK;
    }

    for (end = attr->ulValueLen; end-- > 0;) {
        digit = nickname[end];
        if (digit > '9' || digit < '0') {
            break;
        }
        if (digit < '9') {
            nickname[end]++;
            return CKR_OK;
        }
        nickname[end] = '0';
    }

    /* we overflowed, insert a new '1' for a carry in front of the number */
    newNickname = PORT_ArenaAlloc(arena, attr->ulValueLen + 1);
    if (!newNickname) {
        return CKR_HOST_MEMORY;
    }
    /* PORT_Memcpy should handle len of '0' */
    PORT_Memcpy(newNickname, nickname, ++end);
    newNickname[end] = '1';
    PORT_Memset(&newNickname[end + 1], '0', attr->ulValueLen - end);
    attr->pValue = newNickname;
    attr->ulValueLen++;
    return CKR_OK;
}

/*
 * set an attribute and sign it if necessary
 */
static CK_RV
sftkdb_setAttributeValue(PLArenaPool *arena, SFTKDBHandle *handle,
                         SDB *db, CK_OBJECT_HANDLE objectID, const CK_ATTRIBUTE *template,
                         CK_ULONG count)
{
    CK_RV crv;
    crv = (*db->sdb_SetAttributeValue)(db, objectID, template, count);
    if (crv != CKR_OK) {
        return crv;
    }
    crv = sftk_signTemplate(arena, handle, db == handle->update,
                            objectID, template, count);
    return crv;
}

/*
 * write a softoken object out to the database.
 */
CK_RV
sftkdb_write(SFTKDBHandle *handle, SFTKObject *object,
             CK_OBJECT_HANDLE *objectID)
{
    CK_ATTRIBUTE *template;
    PLArenaPool *arena;
    CK_ULONG count;
    CK_RV crv;
    SDB *db;
    PRBool inTransaction = PR_FALSE;
    CK_OBJECT_HANDLE id;

    *objectID = CK_INVALID_HANDLE;

    if (handle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }
    db = SFTK_GET_SDB(handle);

    /*
     * we have opened a new database, but we have not yet updated it. We are
     * still running pointing to the old database (so the application can
     * still read). We don't want to write to the old database at this point,
     * however, since it leads to user confusion. So at this point we simply
     * require a user login. Let NSS know this so it can prompt the user.
     */
    if (db == handle->update) {
        return CKR_USER_NOT_LOGGED_IN;
    }

    arena = PORT_NewArena(256);
    if (arena == NULL) {
        return CKR_HOST_MEMORY;
    }

    template = sftk_ExtractTemplate(arena, object, handle, &count, &crv);
    if (!template) {
        goto loser;
    }

    crv = (*db->sdb_Begin)(db);
    if (crv != CKR_OK) {
        goto loser;
    }
    inTransaction = PR_TRUE;

    /*
     * We want to make the base database as free from object specific knowledge
     * as possible. To maintain compatibility, keep some of the desirable
     * object specific semantics of the old database.
     *
     * These were 2 fold:
     *  1) there were certain conflicts (like trying to set the same nickname
     * on two different subjects) that would return an error.
     *  2) Importing the 'same' object would silently update that object.
     *
     * The following 2 functions mimic the desirable effects of these two
     * semantics without pushing any object knowledge to the underlying database
     * code.
     */

    /* make sure we don't have attributes that conflict with the existing DB */
    crv = sftkdb_checkConflicts(db, object->objclass, template, count,
                                CK_INVALID_HANDLE);
    if (crv != CKR_OK) {
        goto loser;
    }
    /* Find any copies that match this particular object */
    crv = sftkdb_lookupObject(db, object->objclass, &id, template, count);
    if (crv != CKR_OK) {
        goto loser;
    }
    if (id == CK_INVALID_HANDLE) {
        crv = sftkdb_CreateObject(arena, handle, db, objectID, template, count);
    } else {
        /* object already exists, modify it's attributes */
        *objectID = id;
        crv = sftkdb_setAttributeValue(arena, handle, db, id, template, count);
    }
    if (crv != CKR_OK) {
        goto loser;
    }

    crv = (*db->sdb_Commit)(db);
    inTransaction = PR_FALSE;

loser:
    if (inTransaction) {
        (*db->sdb_Abort)(db);
        /* It is trivial to show the following code cannot
         * happen unless something is horribly wrong with our compilier or
         * hardware */
        PORT_Assert(crv != CKR_OK);
        if (crv == CKR_OK)
            crv = CKR_GENERAL_ERROR;
    }

    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    if (crv == CKR_OK) {
        *objectID |= (handle->type | SFTK_TOKEN_TYPE);
    }
    return crv;
}

CK_RV
sftkdb_FindObjectsInit(SFTKDBHandle *handle, const CK_ATTRIBUTE *template,
                       CK_ULONG count, SDBFind **find)
{
    unsigned char *data = NULL;
    CK_ATTRIBUTE *ntemplate = NULL;
    CK_RV crv;
    SDB *db;

    if (handle == NULL) {
        return CKR_OK;
    }
    db = SFTK_GET_SDB(handle);

    if (count != 0) {
        ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
        if (ntemplate == NULL) {
            return CKR_HOST_MEMORY;
        }
    }

    crv = (*db->sdb_FindObjectsInit)(db, ntemplate,
                                     count, find);
    if (data) {
        PORT_Free(ntemplate);
        PORT_Free(data);
    }
    return crv;
}

CK_RV
sftkdb_FindObjects(SFTKDBHandle *handle, SDBFind *find,
                   CK_OBJECT_HANDLE *ids, int arraySize, CK_ULONG *count)
{
    CK_RV crv;
    SDB *db;

    if (handle == NULL) {
        *count = 0;
        return CKR_OK;
    }
    db = SFTK_GET_SDB(handle);

    crv = (*db->sdb_FindObjects)(db, find, ids,
                                 arraySize, count);
    if (crv == CKR_OK) {
        unsigned int i;
        for (i = 0; i < *count; i++) {
            ids[i] |= (handle->type | SFTK_TOKEN_TYPE);
        }
    }
    return crv;
}

CK_RV
sftkdb_FindObjectsFinal(SFTKDBHandle *handle, SDBFind *find)
{
    SDB *db;
    if (handle == NULL) {
        return CKR_OK;
    }
    db = SFTK_GET_SDB(handle);
    return (*db->sdb_FindObjectsFinal)(db, find);
}

CK_RV
sftkdb_GetAttributeValue(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID,
                         CK_ATTRIBUTE *template, CK_ULONG count)
{
    CK_RV crv, crv2;
    CK_ATTRIBUTE *ntemplate;
    unsigned char *data = NULL;
    SDB *db;

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

    /* short circuit common attributes */
    if (count == 1 &&
        (template[0].type == CKA_TOKEN ||
         template[0].type == CKA_PRIVATE ||
         template[0].type == CKA_SENSITIVE)) {
        CK_BBOOL boolVal = CK_TRUE;

        if (template[0].pValue == NULL) {
            template[0].ulValueLen = sizeof(CK_BBOOL);
            return CKR_OK;
        }
        if (template[0].ulValueLen < sizeof(CK_BBOOL)) {
            template[0].ulValueLen = -1;
            return CKR_BUFFER_TOO_SMALL;
        }

        if ((template[0].type == CKA_PRIVATE) &&
            (handle->type != SFTK_KEYDB_TYPE)) {
            boolVal = CK_FALSE;
        }
        if ((template[0].type == CKA_SENSITIVE) &&
            (handle->type != SFTK_KEYDB_TYPE)) {
            boolVal = CK_FALSE;
        }
        *(CK_BBOOL *)template[0].pValue = boolVal;
        template[0].ulValueLen = sizeof(CK_BBOOL);
        return CKR_OK;
    }

    db = SFTK_GET_SDB(handle);
    /* nothing to do */
    if (count == 0) {
        return CKR_OK;
    }
    ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
    if (ntemplate == NULL) {
        return CKR_HOST_MEMORY;
    }
    objectID &= SFTK_OBJ_ID_MASK;
    crv = (*db->sdb_GetAttributeValue)(db, objectID,
                                       ntemplate, count);
    crv2 = sftkdb_fixupTemplateOut(template, objectID, ntemplate,
                                   count, handle);
    if (crv == CKR_OK)
        crv = crv2;
    if (data) {
        PORT_Free(ntemplate);
        PORT_Free(data);
    }
    return crv;
}

CK_RV
sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object,
                         const CK_ATTRIBUTE *template, CK_ULONG count)
{
    CK_ATTRIBUTE *ntemplate;
    unsigned char *data = NULL;
    PLArenaPool *arena = NULL;
    SDB *db;
    CK_RV crv = CKR_OK;
    CK_OBJECT_HANDLE objectID = (object->handle & SFTK_OBJ_ID_MASK);
    PRBool inTransaction = PR_FALSE;

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

    db = SFTK_GET_SDB(handle);
    /* nothing to do */
    if (count == 0) {
        return CKR_OK;
    }
    /*
     * we have opened a new database, but we have not yet updated it. We are
     * still running  pointing to the old database (so the application can
     * still read). We don't want to write to the old database at this point,
     * however, since it leads to user confusion. So at this point we simply
     * require a user login. Let NSS know this so it can prompt the user.
     */
    if (db == handle->update) {
        return CKR_USER_NOT_LOGGED_IN;
    }

    ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
    if (ntemplate == NULL) {
        return CKR_HOST_MEMORY;
    }

    /* make sure we don't have attributes that conflict with the existing DB */
    crv = sftkdb_checkConflicts(db, object->objclass, ntemplate, count,
                                objectID);
    if (crv != CKR_OK) {
        goto loser;
    }

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

    crv = (*db->sdb_Begin)(db);
    if (crv != CKR_OK) {
        goto loser;
    }
    inTransaction = PR_TRUE;
    crv = sftkdb_setAttributeValue(arena, handle, db, objectID, ntemplate,
                                   count);
    if (crv != CKR_OK) {
        goto loser;
    }
    crv = (*db->sdb_Commit)(db);
loser:
    if (crv != CKR_OK && inTransaction) {
        (*db->sdb_Abort)(db);
    }
    if (data) {
        PORT_Free(ntemplate);
        PORT_Free(data);
    }
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return crv;
}

CK_RV
sftkdb_DestroyObject(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID)
{
    CK_RV crv = CKR_OK;
    SDB *db;

    if (handle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }
    db = SFTK_GET_SDB(handle);
    objectID &= SFTK_OBJ_ID_MASK;
    crv = (*db->sdb_Begin)(db);
    if (crv != CKR_OK) {
        goto loser;
    }
    crv = (*db->sdb_DestroyObject)(db, objectID);
    if (crv != CKR_OK) {
        goto loser;
    }
    crv = (*db->sdb_Commit)(db);
loser:
    if (crv != CKR_OK) {
        (*db->sdb_Abort)(db);
    }
    return crv;
}

CK_RV
sftkdb_CloseDB(SFTKDBHandle *handle)
{
#ifdef NO_FORK_CHECK
    PRBool parentForkedAfterC_Initialize = PR_FALSE;
#endif
    if (handle == NULL) {
        return CKR_OK;
    }
    if (handle->update) {
        if (handle->db->sdb_SetForkState) {
            (*handle->db->sdb_SetForkState)(parentForkedAfterC_Initialize);
        }
        (*handle->update->sdb_Close)(handle->update);
    }
    if (handle->db) {
        if (handle->db->sdb_SetForkState) {
            (*handle->db->sdb_SetForkState)(parentForkedAfterC_Initialize);
        }
        (*handle->db->sdb_Close)(handle->db);
    }
    if (handle->passwordKey.data) {
        PORT_ZFree(handle->passwordKey.data, handle->passwordKey.len);
    }
    if (handle->passwordLock) {
        SKIP_AFTER_FORK(PZ_DestroyLock(handle->passwordLock));
    }
    if (handle->updatePasswordKey) {
        SECITEM_FreeItem(handle->updatePasswordKey, PR_TRUE);
    }
    if (handle->updateID) {
        PORT_Free(handle->updateID);
    }
    PORT_Free(handle);
    return CKR_OK;
}

/*
 * reset a database to it's uninitialized state.
 */
static CK_RV
sftkdb_ResetDB(SFTKDBHandle *handle)
{
    CK_RV crv = CKR_OK;
    SDB *db;
    if (handle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }
    db = SFTK_GET_SDB(handle);
    crv = (*db->sdb_Begin)(db);
    if (crv != CKR_OK) {
        goto loser;
    }
    crv = (*db->sdb_Reset)(db);
    if (crv != CKR_OK) {
        goto loser;
    }
    crv = (*db->sdb_Commit)(db);
loser:
    if (crv != CKR_OK) {
        (*db->sdb_Abort)(db);
    }
    return crv;
}

CK_RV
sftkdb_Begin(SFTKDBHandle *handle)
{
    CK_RV crv = CKR_OK;
    SDB *db;

    if (handle == NULL) {
        return CKR_OK;
    }
    db = SFTK_GET_SDB(handle);
    if (db) {
        crv = (*db->sdb_Begin)(db);
    }
    return crv;
}

CK_RV
sftkdb_Commit(SFTKDBHandle *handle)
{
    CK_RV crv = CKR_OK;
    SDB *db;

    if (handle == NULL) {
        return CKR_OK;
    }
    db = SFTK_GET_SDB(handle);
    if (db) {
        (*db->sdb_Commit)(db);
    }
    return crv;
}

CK_RV
sftkdb_Abort(SFTKDBHandle *handle)
{
    CK_RV crv = CKR_OK;
    SDB *db;

    if (handle == NULL) {
        return CKR_OK;
    }
    db = SFTK_GET_SDB(handle);
    if (db) {
        crv = (db->sdb_Abort)(db);
    }
    return crv;
}

/*
 * functions to update the database from an old database
 */

/*
 * known attributes
 */
static const CK_ATTRIBUTE_TYPE known_attributes[] = {
    CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_APPLICATION,
    CKA_VALUE, CKA_OBJECT_ID, CKA_CERTIFICATE_TYPE, CKA_ISSUER,
    CKA_SERIAL_NUMBER, CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES, CKA_TRUSTED,
    CKA_CERTIFICATE_CATEGORY, CKA_JAVA_MIDP_SECURITY_DOMAIN, CKA_URL,
    CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CKA_HASH_OF_ISSUER_PUBLIC_KEY,
    CKA_CHECK_VALUE, CKA_KEY_TYPE, CKA_SUBJECT, CKA_ID, CKA_SENSITIVE,
    CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, CKA_SIGN, CKA_SIGN_RECOVER,
    CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_DERIVE, CKA_START_DATE, CKA_END_DATE,
    CKA_MODULUS, CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
    CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT,
    CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_PRIME_BITS,
    CKA_SUB_PRIME_BITS, CKA_VALUE_BITS, CKA_VALUE_LEN, CKA_EXTRACTABLE,
    CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE,
    CKA_KEY_GEN_MECHANISM, CKA_MODIFIABLE, CKA_EC_PARAMS,
    CKA_EC_POINT, CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
    CKA_ALWAYS_AUTHENTICATE, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_TEMPLATE,
    CKA_UNWRAP_TEMPLATE, CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT,
    CKA_HAS_RESET, CKA_PIXEL_X, CKA_PIXEL_Y, CKA_RESOLUTION, CKA_CHAR_ROWS,
    CKA_CHAR_COLUMNS, CKA_COLOR, CKA_BITS_PER_PIXEL, CKA_CHAR_SETS,
    CKA_ENCODING_METHODS, CKA_MIME_TYPES, CKA_MECHANISM_TYPE,
    CKA_REQUIRED_CMS_ATTRIBUTES, CKA_DEFAULT_CMS_ATTRIBUTES,
    CKA_SUPPORTED_CMS_ATTRIBUTES, CKA_NSS_URL, CKA_NSS_EMAIL,
    CKA_NSS_SMIME_INFO, CKA_NSS_SMIME_TIMESTAMP,
    CKA_NSS_PKCS8_SALT, CKA_NSS_PASSWORD_CHECK, CKA_NSS_EXPIRES,
    CKA_NSS_KRL, CKA_NSS_PQG_COUNTER, CKA_NSS_PQG_SEED,
    CKA_NSS_PQG_H, CKA_NSS_PQG_SEED_BITS, CKA_NSS_MODULE_SPEC,
    CKA_TRUST_DIGITAL_SIGNATURE, CKA_TRUST_NON_REPUDIATION,
    CKA_TRUST_KEY_ENCIPHERMENT, CKA_TRUST_DATA_ENCIPHERMENT,
    CKA_TRUST_KEY_AGREEMENT, CKA_TRUST_KEY_CERT_SIGN, CKA_TRUST_CRL_SIGN,
    CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_CODE_SIGNING,
    CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_IPSEC_END_SYSTEM,
    CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING,
    CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
    CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS,
    CKA_PUBLIC_KEY_INFO
};

static unsigned int known_attributes_size = sizeof(known_attributes) /
                                            sizeof(known_attributes[0]);

static CK_RV
sftkdb_GetObjectTemplate(SDB *source, CK_OBJECT_HANDLE id,
                         CK_ATTRIBUTE *ptemplate, CK_ULONG *max)
{
    unsigned int i, j;
    CK_RV crv;

    if (*max < known_attributes_size) {
        *max = known_attributes_size;
        return CKR_BUFFER_TOO_SMALL;
    }
    for (i = 0; i < known_attributes_size; i++) {
        ptemplate[i].type = known_attributes[i];
        ptemplate[i].pValue = NULL;
        ptemplate[i].ulValueLen = 0;
    }

    crv = (*source->sdb_GetAttributeValue)(source, id,
                                           ptemplate, known_attributes_size);

    if ((crv != CKR_OK) && (crv != CKR_ATTRIBUTE_TYPE_INVALID)) {
        return crv;
    }

    for (i = 0, j = 0; i < known_attributes_size; i++, j++) {
        while (i < known_attributes_size && (ptemplate[i].ulValueLen == -1)) {
            i++;
        }
        if (i >= known_attributes_size) {
            break;
        }
        /* cheap optimization */
        if (i == j) {
            continue;
        }
        ptemplate[j] = ptemplate[i];
    }
    *max = j;
    return CKR_OK;
}

static const char SFTKDB_META_UPDATE_TEMPLATE[] = "upd_%s_%s";

/*
 * check to see if we have already updated this database.
 * a NULL updateID means we are trying to do an in place
 * single database update. In that case we have already
 * determined that an update was necessary.
 */
static PRBool
sftkdb_hasUpdate(const char *typeString, SDB *db, const char *updateID)
{
    char *id;
    CK_RV crv;
    SECItem dummy = { 0, NULL, 0 };
    unsigned char dummyData[SDB_MAX_META_DATA_LEN];

    if (!updateID) {
        return PR_FALSE;
    }
    id = PR_smprintf(SFTKDB_META_UPDATE_TEMPLATE, typeString, updateID);
    if (id == NULL) {
        return PR_FALSE;
    }
    dummy.data = dummyData;
    dummy.len = sizeof(dummyData);

    crv = (*db->sdb_GetMetaData)(db, id, &dummy, NULL);
    PR_smprintf_free(id);
    return crv == CKR_OK ? PR_TRUE : PR_FALSE;
}

/*
 * we just completed an update, store the update id
 * so we don't need to do it again. If non was given,
 * there is nothing to do.
 */
static CK_RV
sftkdb_putUpdate(const char *typeString, SDB *db, const char *updateID)
{
    char *id;
    CK_RV crv;
    SECItem dummy = { 0, NULL, 0 };

    /* if no id was given, nothing to do */
    if (updateID == NULL) {
        return CKR_OK;
    }

    dummy.data = (unsigned char *)updateID;
    dummy.len = PORT_Strlen(updateID);

    id = PR_smprintf(SFTKDB_META_UPDATE_TEMPLATE, typeString, updateID);
    if (id == NULL) {
        return PR_FALSE;
    }

    crv = (*db->sdb_PutMetaData)(db, id, &dummy, NULL);
    PR_smprintf_free(id);
    return crv;
}

/*
 * get a ULong attribute from a template:
 * NOTE: this is a raw templated stored in database order!
 */
static CK_ULONG
sftkdb_getULongFromTemplate(CK_ATTRIBUTE_TYPE type,
                            CK_ATTRIBUTE *ptemplate, CK_ULONG len)
{
    CK_ATTRIBUTE *attr = sftkdb_getAttributeFromTemplate(type,
                                                         ptemplate, len);

    if (attr && attr->pValue && attr->ulValueLen == SDB_ULONG_SIZE) {
        return sftk_SDBULong2ULong(attr->pValue);
    }
    return (CK_ULONG)-1;
}

/*
 * we need to find a unique CKA_ID.
 *  The basic idea is to just increment the lowest byte.
 *  This code also handles the following corner cases:
 *   1) the single byte overflows. On overflow we increment the next byte up
 *    and so forth until we have overflowed the entire CKA_ID.
 *   2) If we overflow the entire CKA_ID we expand it by one byte.
 *   3) the CKA_ID is non-existant, we create a new one with one byte.
 *    This means no matter what CKA_ID is passed, the result of this function
 *    is always a new CKA_ID, and this function will never return the same
 *    CKA_ID the it has returned in the passed.
 */
static CK_RV
sftkdb_incrementCKAID(PLArenaPool *arena, CK_ATTRIBUTE *ptemplate)
{
    unsigned char *buf = ptemplate->pValue;
    CK_ULONG len = ptemplate->ulValueLen;

    if (buf == NULL || len == (CK_ULONG)-1) {
        /* we have no valid CKAID, we'll create a basic one byte CKA_ID below */
        len = 0;
    } else {
        CK_ULONG i;

        /* walk from the back to front, incrementing
         * the CKA_ID until we no longer have a carry,
         * or have hit the front of the id. */
        for (i = len; i != 0; i--) {
            buf[i - 1]++;
            if (buf[i - 1] != 0) {
                /* no more carries, the increment is complete */
                return CKR_OK;
            }
        }
        /* we've now overflowed, fall through and expand the CKA_ID by
         * one byte */
    }
    buf = PORT_ArenaAlloc(arena, len + 1);
    if (!buf) {
        return CKR_HOST_MEMORY;
    }
    if (len > 0) {
        PORT_Memcpy(buf, ptemplate->pValue, len);
    }
    buf[len] = 0;
    ptemplate->pValue = buf;
    ptemplate->ulValueLen = len + 1;
    return CKR_OK;
}

/*
 * drop an attribute from a template.
 */
void
sftkdb_dropAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE *ptemplate,
                     CK_ULONG *plen)
{
    CK_ULONG count = *plen;
    CK_ULONG i;

    for (i = 0; i < count; i++) {
        if (attr->type == ptemplate[i].type) {
            break;
        }
    }

    if (i == count) {
        /* attribute not found */
        return;
    }

    /* copy the remaining attributes up */
    for (i++; i < count; i++) {
        ptemplate[i - 1] = ptemplate[i];
    }

    /* decrement the template size */
    *plen = count - 1;
}

/*
 * create some defines for the following functions to document the meaning
 * of true/false. (make's it easier to remember what means what.
 */
typedef enum {
    SFTKDB_DO_NOTHING = 0,
    SFTKDB_ADD_OBJECT,
    SFTKDB_MODIFY_OBJECT,
    SFTKDB_DROP_ATTRIBUTE
} sftkdbUpdateStatus;

/*
 * helper function to reconcile a single trust entry.
 *   Identify which trust entry we want to keep.
 *   If we don't need to do anything (the records are already equal).
 *       return SFTKDB_DO_NOTHING.
 *   If we want to use the source version,
 *       return SFTKDB_MODIFY_OBJECT
 *   If we want to use the target version,
 *       return SFTKDB_DROP_ATTRIBUTE
 *
 *   In the end the caller will remove any attributes in the source
 *   template when SFTKDB_DROP_ATTRIBUTE is specified, then use do a
 *   set attributes with that template on the target if we received
 *   any SFTKDB_MODIFY_OBJECT returns.
 */
sftkdbUpdateStatus
sftkdb_reconcileTrustEntry(PLArenaPool *arena, CK_ATTRIBUTE *target,
                           CK_ATTRIBUTE *source)
{
    CK_ULONG targetTrust = sftkdb_getULongFromTemplate(target->type,
                                                       target, 1);
    CK_ULONG sourceTrust = sftkdb_getULongFromTemplate(target->type,
                                                       source, 1);

    /*
     * try to pick the best solution between the source and the
     * target. Update the source template if we want the target value
     * to win out. Prefer cases where we don't actually update the
     * trust entry.
     */

    /* they are the same, everything is already kosher */
    if (targetTrust == sourceTrust) {
        return SFTKDB_DO_NOTHING;
    }

    /* handle the case where the source Trust attribute may be a bit
     * flakey */
    if (sourceTrust == (CK_ULONG)-1) {
        /*
         * The source Trust is invalid. We know that the target Trust
         * must be valid here, otherwise the above
         * targetTrust == sourceTrust check would have succeeded.
         */
        return SFTKDB_DROP_ATTRIBUTE;
    }

    /* target is invalid, use the source's idea of the trust value */
    if (targetTrust == (CK_ULONG)-1) {
        /* overwriting the target in this case is OK */
        return SFTKDB_MODIFY_OBJECT;
    }

    /* at this point we know that both attributes exist and have the
     * appropriate length (SDB_ULONG_SIZE). We no longer need to check
     * ulValueLen for either attribute.
     */
    if (sourceTrust == CKT_NSS_TRUST_UNKNOWN) {
        return SFTKDB_DROP_ATTRIBUTE;
    }

    /* target has no idea, use the source's idea of the trust value */
    if (targetTrust == CKT_NSS_TRUST_UNKNOWN) {
        /* overwriting the target in this case is OK */
        return SFTKDB_MODIFY_OBJECT;
    }

    /* so both the target and the source have some idea of what this
     * trust attribute should be, and neither agree exactly.
     * At this point, we prefer 'hard' attributes over 'soft' ones.
     * 'hard' ones are CKT_NSS_TRUSTED, CKT_NSS_TRUSTED_DELEGATOR, and
     * CKT_NSS_NOT_TRUTED. Soft ones are ones which don't change the
     * actual trust of the cert (CKT_MUST_VERIFY_TRUST,
     * CKT_NSS_VALID_DELEGATOR).
     */
    if ((sourceTrust == CKT_NSS_MUST_VERIFY_TRUST) || (sourceTrust == CKT_NSS_VALID_DELEGATOR)) {
        return SFTKDB_DROP_ATTRIBUTE;
    }
    if ((targetTrust == CKT_NSS_MUST_VERIFY_TRUST) || (targetTrust == CKT_NSS_VALID_DELEGATOR)) {
        /* again, overwriting the target in this case is OK */
        return SFTKDB_MODIFY_OBJECT;
    }

    /* both have hard attributes, we have a conflict, let the target win. */
    return SFTKDB_DROP_ATTRIBUTE;
}

const CK_ATTRIBUTE_TYPE sftkdb_trustList[] =
    { CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH,
      CKA_TRUST_CODE_SIGNING, CKA_TRUST_EMAIL_PROTECTION,
      CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER,
      CKA_TRUST_TIME_STAMPING };

#define SFTK_TRUST_TEMPLATE_COUNT \
    (sizeof(sftkdb_trustList) / sizeof(sftkdb_trustList[0]))
/*
 * Run through the list of known trust types, and reconcile each trust
 * entry one by one. Keep track of we really need to write out the source
 * trust object (overwriting the existing one).
 */
static sftkdbUpdateStatus
sftkdb_reconcileTrust(PLArenaPool *arena, SDB *db, CK_OBJECT_HANDLE id,
                      CK_ATTRIBUTE *ptemplate, CK_ULONG *plen)
{
    CK_ATTRIBUTE trustTemplate[SFTK_TRUST_TEMPLATE_COUNT];
    unsigned char trustData[SFTK_TRUST_TEMPLATE_COUNT * SDB_ULONG_SIZE];
    sftkdbUpdateStatus update = SFTKDB_DO_NOTHING;
    CK_ULONG i;
    CK_RV crv;

    for (i = 0; i < SFTK_TRUST_TEMPLATE_COUNT; i++) {
        trustTemplate[i].type = sftkdb_trustList[i];
        trustTemplate[i].pValue = &trustData[i * SDB_ULONG_SIZE];
        trustTemplate[i].ulValueLen = SDB_ULONG_SIZE;
    }
    crv = (*db->sdb_GetAttributeValue)(db, id,
                                       trustTemplate, SFTK_TRUST_TEMPLATE_COUNT);
    if ((crv != CKR_OK) && (crv != CKR_ATTRIBUTE_TYPE_INVALID)) {
        /* target trust has some problems, update it */
        update = SFTKDB_MODIFY_OBJECT;
        goto done;
    }

    for (i = 0; i < SFTK_TRUST_TEMPLATE_COUNT; i++) {
        CK_ATTRIBUTE *attr = sftkdb_getAttributeFromTemplate(
            trustTemplate[i].type, ptemplate, *plen);
        sftkdbUpdateStatus status;

        /* if target trust value doesn't exist, nothing to merge */
        if (trustTemplate[i].ulValueLen == (CK_ULONG)-1) {
            /* if the source exists, then we want the source entry,
             * go ahead and update */
            if (attr && attr->ulValueLen != (CK_ULONG)-1) {
                update = SFTKDB_MODIFY_OBJECT;
            }
            continue;
        }

        /*
         * the source doesn't have the attribute, go to the next attribute
         */
        if (attr == NULL) {
            continue;
        }
        status = sftkdb_reconcileTrustEntry(arena, &trustTemplate[i], attr);
        if (status == SFTKDB_MODIFY_OBJECT) {
            update = SFTKDB_MODIFY_OBJECT;
        } else if (status == SFTKDB_DROP_ATTRIBUTE) {
            /* drop the source copy of the attribute, we are going with
             * the target's version */
            sftkdb_dropAttribute(attr, ptemplate, plen);
        }
    }

    /* finally manage stepup */
    if (update == SFTKDB_MODIFY_OBJECT) {
        CK_BBOOL stepUpBool = CK_FALSE;
        /* if we are going to write from the source, make sure we don't
         * overwrite the stepup bit if it's on*/
        trustTemplate[0].type = CKA_TRUST_STEP_UP_APPROVED;
        trustTemplate[0].pValue = &stepUpBool;
        trustTemplate[0].ulValueLen = sizeof(stepUpBool);
        crv = (*db->sdb_GetAttributeValue)(db, id, trustTemplate, 1);
        if ((crv == CKR_OK) && (stepUpBool == CK_TRUE)) {
            sftkdb_dropAttribute(trustTemplate, ptemplate, plen);
        }
    } else {
        /* we currently aren't going to update. If the source stepup bit is
         * on however, do an update so the target gets it as well */
        CK_ATTRIBUTE *attr;

        attr = sftkdb_getAttributeFromTemplate(CKA_TRUST_STEP_UP_APPROVED,
                                               ptemplate, *plen);
        if (attr && (attr->ulValueLen == sizeof(CK_BBOOL)) &&
            (*(CK_BBOOL *)(attr->pValue) == CK_TRUE)) {
            update = SFTKDB_MODIFY_OBJECT;
        }
    }

done:
    return update;
}

static sftkdbUpdateStatus
sftkdb_handleIDAndName(PLArenaPool *arena, SDB *db, CK_OBJECT_HANDLE id,
                       CK_ATTRIBUTE *ptemplate, CK_ULONG *plen)
{
    sftkdbUpdateStatus update = SFTKDB_DO_NOTHING;
    CK_ATTRIBUTE *attr1, *attr2;
    CK_ATTRIBUTE ttemplate[2] = {
        { CKA_ID, NULL, 0 },
        { CKA_LABEL, NULL, 0 }
    };

    attr1 = sftkdb_getAttributeFromTemplate(CKA_LABEL, ptemplate, *plen);
    attr2 = sftkdb_getAttributeFromTemplate(CKA_ID, ptemplate, *plen);

    /* if the source has neither an id nor label, don't bother updating */
    if ((!attr1 || attr1->ulValueLen == 0) &&
        (!attr2 || attr2->ulValueLen == 0)) {
        return SFTKDB_DO_NOTHING;
    }

    /* the source has either an id or a label, see what the target has */
    (void)(*db->sdb_GetAttributeValue)(db, id, ttemplate, 2);

    /* if the target has neither, update from the source */
    if (((ttemplate[0].ulValueLen == 0) ||
         (ttemplate[0].ulValueLen == (CK_ULONG)-1)) &&
        ((ttemplate[1].ulValueLen == 0) ||
         (ttemplate[1].ulValueLen == (CK_ULONG)-1))) {
        return SFTKDB_MODIFY_OBJECT;
    }

    /* check the CKA_ID */
    if ((ttemplate[0].ulValueLen != 0) &&
        (ttemplate[0].ulValueLen != (CK_ULONG)-1)) {
        /* we have a CKA_ID in the target, don't overwrite
         * the target with an empty CKA_ID from the source*/
        if (attr1 && attr1->ulValueLen == 0) {
            sftkdb_dropAttribute(attr1, ptemplate, plen);
        }
    } else if (attr1 && attr1->ulValueLen != 0) {
        /* source has a CKA_ID, but the target doesn't, update the target */
        update = SFTKDB_MODIFY_OBJECT;
    }

    /* check the nickname */
    if ((ttemplate[1].ulValueLen != 0) &&
        (ttemplate[1].ulValueLen != (CK_ULONG)-1)) {

        /* we have a nickname in the target, and we don't have to update
         * the CKA_ID. We are done. NOTE: if we add addition attributes
         * in this check, this shortcut can only go on the last of them. */
        if (update == SFTKDB_DO_NOTHING) {
            return update;
        }
        /* we have a nickname in the target, don't overwrite
         * the target with an empty nickname from the source */
        if (attr2 && attr2->ulValueLen == 0) {
            sftkdb_dropAttribute(attr2, ptemplate, plen);
        }
    } else if (attr2 && attr2->ulValueLen != 0) {
        /* source has a nickname, but the target doesn't, update the target */
        update = SFTKDB_MODIFY_OBJECT;
    }

    return update;
}

/*
 * This function updates the template before we write the object out.
 *
 * If we are going to skip updating this object, return PR_FALSE.
 * If it should be updated we return PR_TRUE.
 * To help readability, these have been defined
 * as SFTK_DONT_UPDATE and SFTK_UPDATE respectively.
 */
static PRBool
sftkdb_updateObjectTemplate(PLArenaPool *arena, SDB *db,
                            CK_OBJECT_CLASS objectType,
                            CK_ATTRIBUTE *ptemplate, CK_ULONG *plen,
                            CK_OBJECT_HANDLE *targetID)
{
    PRBool done; /* should we repeat the loop? */
    CK_OBJECT_HANDLE id;
    CK_RV crv = CKR_OK;

    do {
        crv = sftkdb_checkConflicts(db, objectType, ptemplate,
                                    *plen, CK_INVALID_HANDLE);
        if (crv != CKR_ATTRIBUTE_VALUE_INVALID) {
            break;
        }
        crv = sftkdb_resolveConflicts(arena, objectType, ptemplate, plen);
    } while (crv == CKR_OK);

    if (crv != CKR_OK) {
        return SFTKDB_DO_NOTHING;
    }

    do {
        done = PR_TRUE;
        crv = sftkdb_lookupObject(db, objectType, &id, ptemplate, *plen);
        if (crv != CKR_OK) {
            return SFTKDB_DO_NOTHING;
        }

        /* This object already exists, merge it, don't update */
        if (id != CK_INVALID_HANDLE) {
            CK_ATTRIBUTE *attr = NULL;
            /* special post processing for attributes */
            switch (objectType) {
                case CKO_CERTIFICATE:
                case CKO_PUBLIC_KEY:
                case CKO_PRIVATE_KEY:
                    /* update target's CKA_ID and labels if they don't already
                     * exist */
                    *targetID = id;
                    return sftkdb_handleIDAndName(arena, db, id, ptemplate, plen);
                case CKO_NSS_TRUST:
                    /* if we have conflicting trust object types,
                     * we need to reconcile them */
                    *targetID = id;
                    return sftkdb_reconcileTrust(arena, db, id, ptemplate, plen);
                case CKO_SECRET_KEY:
                    /* secret keys in the old database are all sdr keys,
                     * unfortunately they all appear to have the same CKA_ID,
                     * even though they are truly different keys, so we always
                     * want to update these keys, but we need to
                     * give them a new CKA_ID */
                    /* NOTE: this changes ptemplate */
                    attr = sftkdb_getAttributeFromTemplate(CKA_ID, ptemplate, *plen);
                    crv = attr ? sftkdb_incrementCKAID(arena, attr)
                               : CKR_HOST_MEMORY;
                    /* in the extremely rare event that we needed memory and
                     * couldn't get it, just drop the key */
                    if (crv != CKR_OK) {
                        return SFTKDB_DO_NOTHING;
                    }
                    done = PR_FALSE; /* repeat this find loop */
                    break;
                default:
                    /* for all other objects, if we found the equivalent object,
                     * don't update it */
                    return SFTKDB_DO_NOTHING;
            }
        }
    } while (!done);

    /* this object doesn't exist, update it */
    return SFTKDB_ADD_OBJECT;
}

#define MAX_ATTRIBUTES 500
static CK_RV
sftkdb_mergeObject(SFTKDBHandle *handle, CK_OBJECT_HANDLE id,
                   SECItem *key)
{
    CK_ATTRIBUTE template[MAX_ATTRIBUTES];
    CK_ATTRIBUTE *ptemplate;
    CK_ULONG max_attributes = MAX_ATTRIBUTES;
    CK_OBJECT_CLASS objectType;
    SDB *source = handle->update;
    SDB *target = handle->db;
    unsigned int i;
    CK_RV crv;
    PLArenaPool *arena = NULL;

    arena = PORT_NewArena(256);
    if (arena == NULL) {
        return CKR_HOST_MEMORY;
    }

    ptemplate = &template[0];
    id &= SFTK_OBJ_ID_MASK;
    crv = sftkdb_GetObjectTemplate(source, id, ptemplate, &max_attributes);
    if (crv == CKR_BUFFER_TOO_SMALL) {
        ptemplate = PORT_ArenaNewArray(arena, CK_ATTRIBUTE, max_attributes);
        if (ptemplate == NULL) {
            crv = CKR_HOST_MEMORY;
        } else {
            crv = sftkdb_GetObjectTemplate(source, id,
                                           ptemplate, &max_attributes);
        }
    }
    if (crv != CKR_OK) {
        goto loser;
    }

    for (i = 0; i < max_attributes; i++) {
        ptemplate[i].pValue = PORT_ArenaAlloc(arena, ptemplate[i].ulValueLen);
        if (ptemplate[i].pValue == NULL) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }
    }
    crv = (*source->sdb_GetAttributeValue)(source, id,
                                           ptemplate, max_attributes);
    if (crv != CKR_OK) {
        goto loser;
    }

    objectType = sftkdb_getULongFromTemplate(CKA_CLASS, ptemplate,
                                             max_attributes);

    /*
     * Update Object updates the object template if necessary then returns
     * whether or not we need to actually write the object out to our target
     * database.
     */
    if (!handle->updateID) {
        crv = sftkdb_CreateObject(arena, handle, target, &id,
                                  ptemplate, max_attributes);
    } else {
        sftkdbUpdateStatus update_status;
        update_status = sftkdb_updateObjectTemplate(arena, target,
                                                    objectType, ptemplate, &max_attributes, &id);
        switch (update_status) {
            case SFTKDB_ADD_OBJECT:
                crv = sftkdb_CreateObject(arena, handle, target, &id,
                                          ptemplate, max_attributes);
                break;
            case SFTKDB_MODIFY_OBJECT:
                crv = sftkdb_setAttributeValue(arena, handle, target,
                                               id, ptemplate, max_attributes);
                break;
            case SFTKDB_DO_NOTHING:
            case SFTKDB_DROP_ATTRIBUTE:
                break;
        }
    }

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_TRUE);
    }
    return crv;
}

#define MAX_IDS 10
/*
 * update a new database from an old one, now that we have the key
 */
CK_RV
sftkdb_Update(SFTKDBHandle *handle, SECItem *key)
{
    SDBFind *find = NULL;
    CK_ULONG idCount = MAX_IDS;
    CK_OBJECT_HANDLE ids[MAX_IDS];
    SECItem *updatePasswordKey = NULL;
    CK_RV crv, crv2;
    PRBool inTransaction = PR_FALSE;
    unsigned int i;

    if (handle == NULL) {
        return CKR_OK;
    }
    if (handle->update == NULL) {
        return CKR_OK;
    }

    /*
     * put the whole update under a transaction. This allows us to handle
     * any possible race conditions between with the updateID check.
     */
    crv = (*handle->db->sdb_Begin)(handle->db);
    if (crv != CKR_OK) {
        goto loser;
    }
    inTransaction = PR_TRUE;

    /* some one else has already updated this db */
    if (sftkdb_hasUpdate(sftkdb_TypeString(handle),
                         handle->db, handle->updateID)) {
        crv = CKR_OK;
        goto done;
    }

    updatePasswordKey = sftkdb_GetUpdatePasswordKey(handle);
    if (updatePasswordKey) {
        /* pass the source DB key to the legacy code,
         * so it can decrypt things */
        handle->oldKey = updatePasswordKey;
    }

    /* find all the objects */
    crv = sftkdb_FindObjectsInit(handle, NULL, 0, &find);

    if (crv != CKR_OK) {
        goto loser;
    }
    while ((crv == CKR_OK) && (idCount == MAX_IDS)) {
        crv = sftkdb_FindObjects(handle, find, ids, MAX_IDS, &idCount);
        for (i = 0; (crv == CKR_OK) && (i < idCount); i++) {
            crv = sftkdb_mergeObject(handle, ids[i], key);
        }
    }
    crv2 = sftkdb_FindObjectsFinal(handle, find);
    if (crv == CKR_OK)
        crv = crv2;

loser:
    /* no longer need the old key value */
    handle->oldKey = NULL;

    /* update the password - even if we didn't update objects */
    if (handle->type == SFTK_KEYDB_TYPE) {
        SECItem item1, item2;
        unsigned char data1[SDB_MAX_META_DATA_LEN];
        unsigned char data2[SDB_MAX_META_DATA_LEN];

        item1.data = data1;
        item1.len = sizeof(data1);
        item2.data = data2;
        item2.len = sizeof(data2);

        /* if the target db already has a password, skip this. */
        crv = (*handle->db->sdb_GetMetaData)(handle->db, "password",
                                             &item1, &item2);
        if (crv == CKR_OK) {
            goto done;
        }

        /* nope, update it from the source */
        crv = (*handle->update->sdb_GetMetaData)(handle->update, "password",
                                                 &item1, &item2);
        if (crv != CKR_OK) {
            /* if we get here, neither the source, nor the target has been initialized
             * with a password entry. Create a metadata table now so that we don't
             * mistake this for a partially updated database */
            item1.data[0] = 0;
            item2.data[0] = 0;
            item1.len = item2.len = 1;
            crv = (*handle->db->sdb_PutMetaData)(handle->db, "empty", &item1, &item2);
            goto done;
        }
        crv = (*handle->db->sdb_PutMetaData)(handle->db, "password", &item1,
                                             &item2);
        if (crv != CKR_OK) {
            goto done;
        }
    }

done:
    /* finally mark this up to date db up to date */
    /* some one else has already updated this db */
    if (crv == CKR_OK) {
        crv = sftkdb_putUpdate(sftkdb_TypeString(handle),
                               handle->db, handle->updateID);
    }

    if (inTransaction) {
        if (crv == CKR_OK) {
            crv = (*handle->db->sdb_Commit)(handle->db);
        } else {
            (*handle->db->sdb_Abort)(handle->db);
        }
    }
    if (handle->update) {
        (*handle->update->sdb_Close)(handle->update);
        handle->update = NULL;
    }
    if (handle->updateID) {
        PORT_Free(handle->updateID);
        handle->updateID = NULL;
    }
    sftkdb_FreeUpdatePasswordKey(handle);
    if (updatePasswordKey) {
        SECITEM_ZfreeItem(updatePasswordKey, PR_TRUE);
    }
    handle->updateDBIsInit = PR_FALSE;
    return crv;
}

/******************************************************************
 * DB handle managing functions.
 *
 * These functions are called by softoken to initialize, acquire,
 * and release database handles.
 */

const char *
sftkdb_GetUpdateID(SFTKDBHandle *handle)
{
    return handle->updateID;
}

/* release a database handle */
void
sftk_freeDB(SFTKDBHandle *handle)
{
    PRInt32 ref;

    if (!handle)
        return;
    ref = PR_ATOMIC_DECREMENT(&handle->ref);
    if (ref == 0) {
        sftkdb_CloseDB(handle);
    }
    return;
}

/*
 * acquire a database handle for a certificate db
 * (database for public objects)
 */
SFTKDBHandle *
sftk_getCertDB(SFTKSlot *slot)
{
    SFTKDBHandle *dbHandle;

    PZ_Lock(slot->slotLock);
    dbHandle = slot->certDB;
    if (dbHandle) {
        (void)PR_ATOMIC_INCREMENT(&dbHandle->ref);
    }
    PZ_Unlock(slot->slotLock);
    return dbHandle;
}

/*
 * acquire a database handle for a key database
 * (database for private objects)
 */
SFTKDBHandle *
sftk_getKeyDB(SFTKSlot *slot)
{
    SFTKDBHandle *dbHandle;

    SKIP_AFTER_FORK(PZ_Lock(slot->slotLock));
    dbHandle = slot->keyDB;
    if (dbHandle) {
        (void)PR_ATOMIC_INCREMENT(&dbHandle->ref);
    }
    SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock));
    return dbHandle;
}

/*
 * acquire the database for a specific object. NOTE: objectID must point
 * to a Token object!
 */
SFTKDBHandle *
sftk_getDBForTokenObject(SFTKSlot *slot, CK_OBJECT_HANDLE objectID)
{
    SFTKDBHandle *dbHandle;

    PZ_Lock(slot->slotLock);
    dbHandle = objectID & SFTK_KEYDB_TYPE ? slot->keyDB : slot->certDB;
    if (dbHandle) {
        (void)PR_ATOMIC_INCREMENT(&dbHandle->ref);
    }
    PZ_Unlock(slot->slotLock);
    return dbHandle;
}

/*
 * initialize a new database handle
 */
static SFTKDBHandle *
sftk_NewDBHandle(SDB *sdb, int type)
{
    SFTKDBHandle *handle = PORT_New(SFTKDBHandle);
    handle->ref = 1;
    handle->db = sdb;
    handle->update = NULL;
    handle->peerDB = NULL;
    handle->newKey = NULL;
    handle->oldKey = NULL;
    handle->updatePasswordKey = NULL;
    handle->updateID = NULL;
    handle->type = type;
    handle->passwordKey.data = NULL;
    handle->passwordKey.len = 0;
    handle->passwordLock = NULL;
    if (type == SFTK_KEYDB_TYPE) {
        handle->passwordLock = PZ_NewLock(nssILockAttribute);
    }
    sdb->app_private = handle;
    return handle;
}

/*
 * reset the key database to it's uninitialized state. This call
 * will clear all the key entried.
 */
SECStatus
sftkdb_ResetKeyDB(SFTKDBHandle *handle)
{
    CK_RV crv;

    /* only rest the key db */
    if (handle->type != SFTK_KEYDB_TYPE) {
        return SECFailure;
    }
    crv = sftkdb_ResetDB(handle);
    if (crv != CKR_OK) {
        /* set error */
        return SECFailure;
    }
    return SECSuccess;
}

static PRBool
sftk_oldVersionExists(const char *dir, int version)
{
    int i;
    PRStatus exists = PR_FAILURE;
    char *file = NULL;

    for (i = version; i > 1; i--) {
        file = PR_smprintf("%s%d.db", dir, i);
        if (file == NULL) {
            continue;
        }
        exists = PR_Access(file, PR_ACCESS_EXISTS);
        PR_smprintf_free(file);
        if (exists == PR_SUCCESS) {
            return PR_TRUE;
        }
    }
    return PR_FALSE;
}

#if defined(_WIN32)
/*
 * Convert an sdb path (encoded in UTF-8) to a legacy path (encoded in the
 * current system codepage). Fails if the path contains a character outside
 * the current system codepage.
 */
static char *
sftk_legacyPathFromSDBPath(const char *confdir)
{
    wchar_t *confdirWide;
    DWORD size;
    char *nconfdir;
    BOOL unmappable;

    if (!confdir) {
        return NULL;
    }
    confdirWide = _NSSUTIL_UTF8ToWide(confdir);
    if (!confdirWide) {
        return NULL;
    }

    size = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, confdirWide, -1,
                               NULL, 0, NULL, &unmappable);
    if (size == 0 || unmappable) {
        PORT_Free(confdirWide);
        return NULL;
    }
    nconfdir = PORT_Alloc(sizeof(char) * size);
    if (!nconfdir) {
        PORT_Free(confdirWide);
        return NULL;
    }
    size = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, confdirWide, -1,
                               nconfdir, size, NULL, &unmappable);
    PORT_Free(confdirWide);
    if (size == 0 || unmappable) {
        PORT_Free(nconfdir);
        return NULL;
    }

    return nconfdir;
}
#else
#define sftk_legacyPathFromSDBPath(confdir) PORT_Strdup((confdir))
#endif

static PRBool
sftk_hasLegacyDB(const char *confdir, const char *certPrefix,
                 const char *keyPrefix, int certVersion, int keyVersion)
{
    char *dir;
    PRBool exists;

    if (certPrefix == NULL) {
        certPrefix = "";
    }

    if (keyPrefix == NULL) {
        keyPrefix = "";
    }

    dir = PR_smprintf("%s/%scert", confdir, certPrefix);
    if (dir == NULL) {
        return PR_FALSE;
    }

    exists = sftk_oldVersionExists(dir, certVersion);
    PR_smprintf_free(dir);
    if (exists) {
        return PR_TRUE;
    }

    dir = PR_smprintf("%s/%skey", confdir, keyPrefix);
    if (dir == NULL) {
        return PR_FALSE;
    }

    exists = sftk_oldVersionExists(dir, keyVersion);
    PR_smprintf_free(dir);
    return exists;
}

/*
 * initialize certificate and key database handles as a pair.
 *
 * This function figures out what type of database we are opening and
 * calls the appropriate low level function to open the database.
 * It also figures out whether or not to setup up automatic update.
 */
CK_RV
sftk_DBInit(const char *configdir, const char *certPrefix,
            const char *keyPrefix, const char *updatedir,
            const char *updCertPrefix, const char *updKeyPrefix,
            const char *updateID, PRBool readOnly, PRBool noCertDB,
            PRBool noKeyDB, PRBool forceOpen, PRBool isFIPS,
            SFTKDBHandle **certDB, SFTKDBHandle **keyDB)
{
    const char *confdir;
    NSSDBType dbType = NSS_DB_TYPE_NONE;
    char *appName = NULL;
    SDB *keySDB, *certSDB;
    CK_RV crv = CKR_OK;
    int flags = SDB_RDONLY;
    PRBool newInit = PR_FALSE;
    PRBool needUpdate = PR_FALSE;
    char *nconfdir = NULL;

    if (!readOnly) {
        flags = SDB_CREATE;
    }
    if (isFIPS) {
        flags |= SDB_FIPS;
    }

    *certDB = NULL;
    *keyDB = NULL;

    if (noKeyDB && noCertDB) {
        return CKR_OK;
    }
    confdir = _NSSUTIL_EvaluateConfigDir(configdir, &dbType, &appName);

    /*
     * now initialize the appropriate database
     */
    switch (dbType) {
        case NSS_DB_TYPE_LEGACY:
            crv = sftkdbCall_open(confdir, certPrefix, keyPrefix, 8, 3, flags,
                                  noCertDB ? NULL : &certSDB, noKeyDB ? NULL : &keySDB);
            break;
        case NSS_DB_TYPE_MULTIACCESS:
            crv = sftkdbCall_open(configdir, certPrefix, keyPrefix, 8, 3, flags,
                                  noCertDB ? NULL : &certSDB, noKeyDB ? NULL : &keySDB);
            break;
        case NSS_DB_TYPE_SQL:
        case NSS_DB_TYPE_EXTERN: /* SHOULD open a loadable db */
            crv = s_open(confdir, certPrefix, keyPrefix, 9, 4, flags,
                         noCertDB ? NULL : &certSDB, noKeyDB ? NULL : &keySDB, &newInit);

            /*
             * if we failed to open the DB's read only, use the old ones if
             * the exists.
             */
            if (crv != CKR_OK) {
                if ((flags & SDB_RDONLY) == SDB_RDONLY) {
                    nconfdir = sftk_legacyPathFromSDBPath(confdir);
                }
                if (nconfdir &&
                    sftk_hasLegacyDB(nconfdir, certPrefix, keyPrefix, 8, 3)) {
                    /* we have legacy databases, if we failed to open the new format
                     * DB's read only, just use the legacy ones */
                    crv = sftkdbCall_open(nconfdir, certPrefix,
                                          keyPrefix, 8, 3, flags,
                                          noCertDB ? NULL : &certSDB, noKeyDB ? NULL : &keySDB);
                }
                /* Handle the database merge case.
                 *
                 * For the merge case, we need help from the application. Only
                 * the application knows where the old database is, and what unique
                 * identifier it has associated with it.
                 *
                 * If the client supplies these values, we use them to determine
                 * if we need to update.
                 */
            } else if (
                /* both update params have been supplied */
                updatedir && *updatedir && updateID && *updateID
                /* old dbs exist? */
                && sftk_hasLegacyDB(updatedir, updCertPrefix, updKeyPrefix, 8, 3)
                /* and they have not yet been updated? */
                && ((noKeyDB || !sftkdb_hasUpdate("key", keySDB, updateID)) || (noCertDB || !sftkdb_hasUpdate("cert", certSDB, updateID)))) {
                /* we need to update */
                confdir = updatedir;
                certPrefix = updCertPrefix;
                keyPrefix = updKeyPrefix;
                needUpdate = PR_TRUE;
            } else if (newInit) {
                /* if the new format DB was also a newly created DB, and we
                 * succeeded, then need to update that new database with data
                 * from the existing legacy DB */
                nconfdir = sftk_legacyPathFromSDBPath(confdir);
                if (nconfdir &&
                    sftk_hasLegacyDB(nconfdir, certPrefix, keyPrefix, 8, 3)) {
                    confdir = nconfdir;
                    needUpdate = PR_TRUE;
                }
            }
            break;
        default:
            crv = CKR_GENERAL_ERROR; /* can't happen, EvaluationConfigDir MUST
                                      * return one of the types we already
                                      * specified. */
    }
    if (crv != CKR_OK) {
        goto done;
    }
    if (!noCertDB) {
        *certDB = sftk_NewDBHandle(certSDB, SFTK_CERTDB_TYPE);
    } else {
        *certDB = NULL;
    }
    if (!noKeyDB) {
        *keyDB = sftk_NewDBHandle(keySDB, SFTK_KEYDB_TYPE);
    } else {
        *keyDB = NULL;
    }

    /* link them together */
    if (*certDB) {
        (*certDB)->peerDB = *keyDB;
    }
    if (*keyDB) {
        (*keyDB)->peerDB = *certDB;
    }

    /*
     * if we need to update, open the legacy database and
     * mark the handle as needing update.
     */
    if (needUpdate) {
        SDB *updateCert = NULL;
        SDB *updateKey = NULL;
        CK_RV crv2;

        crv2 = sftkdbCall_open(confdir, certPrefix, keyPrefix, 8, 3, flags,
                               noCertDB ? NULL : &updateCert,
                               noKeyDB ? NULL : &updateKey);
        if (crv2 == CKR_OK) {
            if (*certDB) {
                (*certDB)->update = updateCert;
                (*certDB)->updateID = updateID && *updateID
                                          ? PORT_Strdup(updateID)
                                          : NULL;
                updateCert->app_private = (*certDB);
            }
            if (*keyDB) {
                PRBool tokenRemoved = PR_FALSE;
                (*keyDB)->update = updateKey;
                (*keyDB)->updateID = updateID && *updateID ? PORT_Strdup(updateID) : NULL;
                updateKey->app_private = (*keyDB);
                (*keyDB)->updateDBIsInit = PR_TRUE;
                (*keyDB)->updateDBIsInit =
                    (sftkdb_HasPasswordSet(*keyDB) == SECSuccess) ? PR_TRUE : PR_FALSE;
                /* if the password on the key db is NULL, kick off our update
                 * chain of events */
                sftkdb_CheckPassword((*keyDB), "", &tokenRemoved);
            } else {
                /* we don't have a key DB, update the certificate DB now */
                sftkdb_Update(*certDB, NULL);
            }
        }
    }
done:
    if (appName) {
        PORT_Free(appName);
    }
    if (nconfdir) {
        PORT_Free(nconfdir);
    }
    return forceOpen ? CKR_OK : crv;
}

CK_RV
sftkdb_Shutdown(void)
{
    s_shutdown();
    sftkdbCall_Shutdown();
    return CKR_OK;
}
