/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "ckcapi.h"
#include "nssbase.h"

/*
 * ckcapi/cobject.c
 *
 * This file implements the NSSCKMDObject object for the
 * "nss to capi objects" cryptoki module.
 */

const CK_ATTRIBUTE_TYPE certAttrs[] = {
    CKA_CLASS,
    CKA_TOKEN,
    CKA_PRIVATE,
    CKA_MODIFIABLE,
    CKA_LABEL,
    CKA_CERTIFICATE_TYPE,
    CKA_SUBJECT,
    CKA_ISSUER,
    CKA_SERIAL_NUMBER,
    CKA_VALUE
};
const PRUint32 certAttrsCount = NSS_CKCAPI_ARRAY_SIZE(certAttrs);

/* private keys, for now only support RSA */
const CK_ATTRIBUTE_TYPE privKeyAttrs[] = {
    CKA_CLASS,
    CKA_TOKEN,
    CKA_PRIVATE,
    CKA_MODIFIABLE,
    CKA_LABEL,
    CKA_KEY_TYPE,
    CKA_DERIVE,
    CKA_LOCAL,
    CKA_SUBJECT,
    CKA_SENSITIVE,
    CKA_DECRYPT,
    CKA_SIGN,
    CKA_SIGN_RECOVER,
    CKA_UNWRAP,
    CKA_EXTRACTABLE,
    CKA_ALWAYS_SENSITIVE,
    CKA_NEVER_EXTRACTABLE,
    CKA_MODULUS,
    CKA_PUBLIC_EXPONENT,
};
const PRUint32 privKeyAttrsCount = NSS_CKCAPI_ARRAY_SIZE(privKeyAttrs);

/* public keys, for now only support RSA */
const CK_ATTRIBUTE_TYPE pubKeyAttrs[] = {
    CKA_CLASS,
    CKA_TOKEN,
    CKA_PRIVATE,
    CKA_MODIFIABLE,
    CKA_LABEL,
    CKA_KEY_TYPE,
    CKA_DERIVE,
    CKA_LOCAL,
    CKA_SUBJECT,
    CKA_ENCRYPT,
    CKA_VERIFY,
    CKA_VERIFY_RECOVER,
    CKA_WRAP,
    CKA_MODULUS,
    CKA_PUBLIC_EXPONENT,
};
const PRUint32 pubKeyAttrsCount = NSS_CKCAPI_ARRAY_SIZE(pubKeyAttrs);
static const CK_BBOOL ck_true = CK_TRUE;
static const CK_BBOOL ck_false = CK_FALSE;
static const CK_CERTIFICATE_TYPE ckc_x509 = CKC_X_509;
static const CK_KEY_TYPE ckk_rsa = CKK_RSA;
static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
static const CK_OBJECT_CLASS cko_private_key = CKO_PRIVATE_KEY;
static const CK_OBJECT_CLASS cko_public_key = CKO_PUBLIC_KEY;
static const NSSItem ckcapi_trueItem = {
    (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL)
};
static const NSSItem ckcapi_falseItem = {
    (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL)
};
static const NSSItem ckcapi_x509Item = {
    (void *)&ckc_x509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE)
};
static const NSSItem ckcapi_rsaItem = {
    (void *)&ckk_rsa, (PRUint32)sizeof(CK_KEY_TYPE)
};
static const NSSItem ckcapi_certClassItem = {
    (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS)
};
static const NSSItem ckcapi_privKeyClassItem = {
    (void *)&cko_private_key, (PRUint32)sizeof(CK_OBJECT_CLASS)
};
static const NSSItem ckcapi_pubKeyClassItem = {
    (void *)&cko_public_key, (PRUint32)sizeof(CK_OBJECT_CLASS)
};
static const NSSItem ckcapi_emptyItem = {
    (void *)&ck_true, 0
};

/*
 * these are utilities. The chould be moved to a new utilities file.
 */

/*
 * unwrap a single DER value
 */
unsigned char *
nss_ckcapi_DERUnwrap(
    unsigned char *src,
    unsigned int size,
    unsigned int *outSize,
    unsigned char **next)
{
    unsigned char *start = src;
    unsigned char *end = src + size;
    unsigned int len = 0;

    /* initialize error condition return values */
    *outSize = 0;
    if (next) {
        *next = src;
    }

    if (size < 2) {
        return start;
    }
    src++; /* skip the tag -- should check it against an expected value! */
    len = (unsigned)*src++;
    if (len & 0x80) {
        unsigned int count = len & 0x7f;
        len = 0;

        if (count + 2 > size) {
            return start;
        }
        while (count-- > 0) {
            len = (len << 8) | (unsigned)*src++;
        }
    }
    if (len + (src - start) > size) {
        return start;
    }
    if (next) {
        *next = src + len;
    }
    *outSize = len;

    return src;
}

/*
 * convert a PKCS #11 bytestrin into a CK_ULONG, the byte stream must be
 * less than sizeof (CK_ULONG).
 */
CK_ULONG
nss_ckcapi_DataToInt(
    NSSItem *data,
    CK_RV *pError)
{
    CK_ULONG value = 0;
    unsigned long count = data->size;
    unsigned char *dataPtr = data->data;
    unsigned long size = 0;

    *pError = CKR_OK;

    while (count--) {
        value = value << 8;
        value = value + *dataPtr++;
        if (size || value) {
            size++;
        }
    }
    if (size > sizeof(CK_ULONG)) {
        *pError = CKR_ATTRIBUTE_VALUE_INVALID;
    }
    return value;
}

/*
 * convert a CK_ULONG to a bytestream. Data is stored in the buffer 'buf'
 * and must be at least CK_ULONG. Caller must provide buf.
 */
CK_ULONG
nss_ckcapi_IntToData(
    CK_ULONG value,
    NSSItem *data,
    unsigned char *dataPtr,
    CK_RV *pError)
{
    unsigned long count = 0;
    unsigned long i;
#define SHIFT ((sizeof(CK_ULONG) - 1) * 8)
    PRBool first = 0;

    *pError = CKR_OK;

    data->data = dataPtr;
    for (i = 0; i < sizeof(CK_ULONG); i++) {
        unsigned char digit = (unsigned char)((value >> SHIFT) & 0xff);

        value = value << 8;

        /* drop leading zero bytes */
        if (first && (0 == digit)) {
            continue;
        }
        *dataPtr++ = digit;
        count++;
    }
    data->size = count;
    return count;
}

/*
 * get an attribute from a template. Value is returned in NSS item.
 * data for the item is owned by the template.
 */
CK_RV
nss_ckcapi_GetAttribute(
    CK_ATTRIBUTE_TYPE type,
    CK_ATTRIBUTE *template,
    CK_ULONG templateSize,
    NSSItem *item)
{
    CK_ULONG i;

    for (i = 0; i < templateSize; i++) {
        if (template[i].type == type) {
            item->data = template[i].pValue;
            item->size = template[i].ulValueLen;
            return CKR_OK;
        }
    }
    return CKR_TEMPLATE_INCOMPLETE;
}

/*
 * get an attribute which is type CK_ULONG.
 */
CK_ULONG
nss_ckcapi_GetULongAttribute(
    CK_ATTRIBUTE_TYPE type,
    CK_ATTRIBUTE *template,
    CK_ULONG templateSize,
    CK_RV *pError)
{
    NSSItem item;

    *pError = nss_ckcapi_GetAttribute(type, template, templateSize, &item);
    if (CKR_OK != *pError) {
        return (CK_ULONG)0;
    }
    if (item.size != sizeof(CK_ULONG)) {
        *pError = CKR_ATTRIBUTE_VALUE_INVALID;
        return (CK_ULONG)0;
    }
    return *(CK_ULONG *)item.data;
}

/*
 * get an attribute which is type CK_BBOOL.
 */
CK_BBOOL
nss_ckcapi_GetBoolAttribute(
    CK_ATTRIBUTE_TYPE type,
    CK_ATTRIBUTE *template,
    CK_ULONG templateSize,
    CK_RV *pError)
{
    NSSItem item;

    *pError = nss_ckcapi_GetAttribute(type, template, templateSize, &item);
    if (CKR_OK != *pError) {
        return (CK_BBOOL)0;
    }
    if (item.size != sizeof(CK_BBOOL)) {
        *pError = CKR_ATTRIBUTE_VALUE_INVALID;
        return (CK_BBOOL)0;
    }
    return *(CK_BBOOL *)item.data;
}

/*
 * get an attribute which is type CK_BBOOL.
 */
char *
nss_ckcapi_GetStringAttribute(
    CK_ATTRIBUTE_TYPE type,
    CK_ATTRIBUTE *template,
    CK_ULONG templateSize,
    CK_RV *pError)
{
    NSSItem item;
    char *str;

    /* get the attribute */
    *pError = nss_ckcapi_GetAttribute(type, template, templateSize, &item);
    if (CKR_OK != *pError) {
        return (char *)NULL;
    }
    /* make sure it is null terminated */
    str = nss_ZNEWARRAY(NULL, char, item.size + 1);
    if ((char *)NULL == str) {
        *pError = CKR_HOST_MEMORY;
        return (char *)NULL;
    }

    nsslibc_memcpy(str, item.data, item.size);
    str[item.size] = 0;

    return str;
}

/*
 * Return the size in bytes of a wide string, including the terminating null
 * character
 */
int
nss_ckcapi_WideSize(
    LPCWSTR wide)
{
    DWORD size;

    if ((LPWSTR)NULL == wide) {
        return 0;
    }
    size = wcslen(wide) + 1;
    return size * sizeof(WCHAR);
}

/*
 * Covert a Unicode wide character string to a UTF8 string
 */
char *
nss_ckcapi_WideToUTF8(
    LPCWSTR wide)
{
    DWORD size;
    char *buf;

    if ((LPWSTR)NULL == wide) {
        return (char *)NULL;
    }

    size = WideCharToMultiByte(CP_UTF8, 0, wide, -1, NULL, 0, NULL, 0);
    if (size == 0) {
        return (char *)NULL;
    }
    buf = nss_ZNEWARRAY(NULL, char, size);
    size = WideCharToMultiByte(CP_UTF8, 0, wide, -1, buf, size, NULL, 0);
    if (size == 0) {
        nss_ZFreeIf(buf);
        return (char *)NULL;
    }
    return buf;
}

/*
 * Return a Wide String duplicated with nss allocated memory.
 */
LPWSTR
nss_ckcapi_WideDup(
    LPCWSTR wide)
{
    DWORD len;
    LPWSTR buf;

    if ((LPWSTR)NULL == wide) {
        return (LPWSTR)NULL;
    }

    len = wcslen(wide) + 1;

    buf = nss_ZNEWARRAY(NULL, WCHAR, len);
    if ((LPWSTR)NULL == buf) {
        return buf;
    }
    nsslibc_memcpy(buf, wide, len * sizeof(WCHAR));
    return buf;
}

/*
 * Covert a UTF8 string to Unicode wide character
 */
LPWSTR
nss_ckcapi_UTF8ToWide(
    char *buf)
{
    DWORD size;
    LPWSTR wide;

    if ((char *)NULL == buf) {
        return (LPWSTR)NULL;
    }

    size = MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0);
    if (size == 0) {
        return (LPWSTR)NULL;
    }
    wide = nss_ZNEWARRAY(NULL, WCHAR, size);
    size = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wide, size);
    if (size == 0) {
        nss_ZFreeIf(wide);
        return (LPWSTR)NULL;
    }
    return wide;
}

/*
 * keep all the knowlege of how the internalObject is laid out in this function
 *
 * nss_ckcapi_FetchKeyContainer
 *
 * fetches the Provider container and info as well as a key handle for a
 * private key. If something other than a private key is passed in,
 * this function fails with CKR_KEY_TYPE_INCONSISTENT
 */
NSS_EXTERN CK_RV
nss_ckcapi_FetchKeyContainer(
    ckcapiInternalObject *iKey,
    HCRYPTPROV *hProv,
    DWORD *keySpec,
    HCRYPTKEY *hKey)
{
    ckcapiCertObject *co;
    ckcapiKeyObject *ko;
    BOOL rc, dummy;
    DWORD msError;

    switch (iKey->type) {
        default:
        case ckcapiRaw:
            /* can't have raw private keys */
            return CKR_KEY_TYPE_INCONSISTENT;
        case ckcapiCert:
            if (iKey->objClass != CKO_PRIVATE_KEY) {
                /* Only private keys have private key provider handles */
                return CKR_KEY_TYPE_INCONSISTENT;
            }
            co = &iKey->u.cert;

            /* OK, get the Provider */
            rc = CryptAcquireCertificatePrivateKey(co->certContext,
                                                   CRYPT_ACQUIRE_CACHE_FLAG |
                                                       CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
                                                   NULL, hProv,
                                                   keySpec, &dummy);
            if (!rc) {
                goto loser;
            }
            break;
        case ckcapiBareKey:
            if (iKey->objClass != CKO_PRIVATE_KEY) {
                /* Only private keys have private key provider handles */
                return CKR_KEY_TYPE_INCONSISTENT;
            }
            ko = &iKey->u.key;

            /* OK, get the Provider */
            if (0 == ko->hProv) {
                rc =
                    CryptAcquireContext(hProv,
                                        ko->containerName,
                                        ko->provName,
                                        ko->provInfo.dwProvType, 0);
                if (!rc) {
                    goto loser;
                }
            } else {
                *hProv =
                    ko->hProv;
            }
            *keySpec = ko->provInfo.dwKeySpec;
            break;
    }

    /* and get the crypto handle */
    rc = CryptGetUserKey(*hProv, *keySpec, hKey);
    if (!rc) {
        goto loser;
    }
    return CKR_OK;
loser:
    /* map the microsoft error before leaving */
    msError = GetLastError();
    switch (msError) {
        case ERROR_INVALID_HANDLE:
        case ERROR_INVALID_PARAMETER:
        case NTE_BAD_KEY:
        case NTE_NO_KEY:
        case NTE_BAD_PUBLIC_KEY:
        case NTE_BAD_KEYSET:
        case NTE_KEYSET_NOT_DEF:
            return CKR_KEY_TYPE_INCONSISTENT;
        case NTE_BAD_UID:
        case NTE_KEYSET_ENTRY_BAD:
            return CKR_DEVICE_ERROR;
    }
    return CKR_GENERAL_ERROR;
}

/*
 * take a DER PUBLIC Key block and return the modulus and exponent
 */
static void
ckcapi_CertPopulateModulusExponent(
    ckcapiInternalObject *io)
{
    ckcapiKeyParams *kp = &io->u.cert.key;
    PCCERT_CONTEXT certContext = io->u.cert.certContext;
    unsigned char *pkData =
        certContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData;
    unsigned int size =
        certContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData;
    unsigned int newSize;
    unsigned char *ptr, *newptr;

    /* find the start of the modulus -- this will not give good results if
     * the key isn't an rsa key! */
    ptr = nss_ckcapi_DERUnwrap(pkData, size, &newSize, NULL);
    kp->modulus.data = nss_ckcapi_DERUnwrap(ptr, newSize,
                                            &kp->modulus.size, &newptr);
    /* changed from signed to unsigned int */
    if (0 == *(char *)kp->modulus.data) {
        kp->modulus.data = ((char *)kp->modulus.data) + 1;
        kp->modulus.size = kp->modulus.size - 1;
    }
    /* changed from signed to unsigned int */
    kp->exponent.data = nss_ckcapi_DERUnwrap(newptr, (newptr - ptr) + newSize,
                                             &kp->exponent.size, NULL);
    if (0 == *(char *)kp->exponent.data) {
        kp->exponent.data = ((char *)kp->exponent.data) + 1;
        kp->exponent.size = kp->exponent.size - 1;
    }
    return;
}

typedef struct _CAPI_RSA_KEY_BLOB {
    PUBLICKEYSTRUC header;
    RSAPUBKEY rsa;
    char data[1];
} CAPI_RSA_KEY_BLOB;

#define CAPI_MODULUS_OFFSET(modSize) 0
#define CAPI_PRIME_1_OFFSET(modSize) (modSize)
#define CAPI_PRIME_2_OFFSET(modSize) ((modSize) + (modSize) / 2)
#define CAPI_EXPONENT_1_OFFSET(modSize) ((modSize)*2)
#define CAPI_EXPONENT_2_OFFSET(modSize) ((modSize)*2 + (modSize) / 2)
#define CAPI_COEFFICIENT_OFFSET(modSize) ((modSize)*3)
#define CAPI_PRIVATE_EXP_OFFSET(modSize) ((modSize)*3 + (modSize) / 2)

void
ckcapi_FetchPublicKey(
    ckcapiInternalObject *io)
{
    ckcapiKeyParams *kp;
    HCRYPTPROV hProv;
    DWORD keySpec;
    HCRYPTKEY hKey = 0;
    CK_RV error;
    DWORD bufLen;
    BOOL rc;
    unsigned long modulus;
    char *buf = NULL;
    CAPI_RSA_KEY_BLOB *blob;

    error = nss_ckcapi_FetchKeyContainer(io, &hProv, &keySpec, &hKey);
    if (CKR_OK != error) {
        goto loser;
    }
    kp = (ckcapiCert == io->type) ? &io->u.cert.key : &io->u.key.key;

    rc = CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, buf, &bufLen);
    if (!rc) {
        goto loser;
    }
    buf = nss_ZNEWARRAY(NULL, char, bufLen);
    rc = CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, buf, &bufLen);
    if (!rc) {
        goto loser;
    }
    /* validate the blob */
    blob = (CAPI_RSA_KEY_BLOB *)buf;
    if ((PUBLICKEYBLOB != blob->header.bType) ||
        (0x02 != blob->header.bVersion) ||
        (0x31415352 != blob->rsa.magic)) {
        goto loser;
    }
    modulus = blob->rsa.bitlen / 8;
    kp->pubKey = buf;
    buf = NULL;

    kp->modulus.data = &blob->data[CAPI_MODULUS_OFFSET(modulus)];
    kp->modulus.size = modulus;
    ckcapi_ReverseData(&kp->modulus);
    nss_ckcapi_IntToData(blob->rsa.pubexp, &kp->exponent,
                         kp->publicExponentData, &error);

loser:
    nss_ZFreeIf(buf);
    if (0 != hKey) {
        CryptDestroyKey(hKey);
    }
    return;
}

void
ckcapi_FetchPrivateKey(
    ckcapiInternalObject *io)
{
    ckcapiKeyParams *kp;
    HCRYPTPROV hProv;
    DWORD keySpec;
    HCRYPTKEY hKey = 0;
    CK_RV error;
    DWORD bufLen;
    BOOL rc;
    unsigned long modulus;
    char *buf = NULL;
    CAPI_RSA_KEY_BLOB *blob;

    error = nss_ckcapi_FetchKeyContainer(io, &hProv, &keySpec, &hKey);
    if (CKR_OK != error) {
        goto loser;
    }
    kp = (ckcapiCert == io->type) ? &io->u.cert.key : &io->u.key.key;

    rc = CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, buf, &bufLen);
    if (!rc) {
        goto loser;
    }
    buf = nss_ZNEWARRAY(NULL, char, bufLen);
    rc = CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, buf, &bufLen);
    if (!rc) {
        goto loser;
    }
    /* validate the blob */
    blob = (CAPI_RSA_KEY_BLOB *)buf;
    if ((PRIVATEKEYBLOB != blob->header.bType) ||
        (0x02 != blob->header.bVersion) ||
        (0x32415352 != blob->rsa.magic)) {
        goto loser;
    }
    modulus = blob->rsa.bitlen / 8;
    kp->privateKey = buf;
    buf = NULL;

    kp->privateExponent.data = &blob->data[CAPI_PRIVATE_EXP_OFFSET(modulus)];
    kp->privateExponent.size = modulus;
    ckcapi_ReverseData(&kp->privateExponent);
    kp->prime1.data = &blob->data[CAPI_PRIME_1_OFFSET(modulus)];
    kp->prime1.size = modulus / 2;
    ckcapi_ReverseData(&kp->prime1);
    kp->prime2.data = &blob->data[CAPI_PRIME_2_OFFSET(modulus)];
    kp->prime2.size = modulus / 2;
    ckcapi_ReverseData(&kp->prime2);
    kp->exponent1.data = &blob->data[CAPI_EXPONENT_1_OFFSET(modulus)];
    kp->exponent1.size = modulus / 2;
    ckcapi_ReverseData(&kp->exponent1);
    kp->exponent2.data = &blob->data[CAPI_EXPONENT_2_OFFSET(modulus)];
    kp->exponent2.size = modulus / 2;
    ckcapi_ReverseData(&kp->exponent2);
    kp->coefficient.data = &blob->data[CAPI_COEFFICIENT_OFFSET(modulus)];
    kp->coefficient.size = modulus / 2;
    ckcapi_ReverseData(&kp->coefficient);

loser:
    nss_ZFreeIf(buf);
    if (0 != hKey) {
        CryptDestroyKey(hKey);
    }
    return;
}

void
ckcapi_PopulateModulusExponent(
    ckcapiInternalObject *io)
{
    if (ckcapiCert == io->type) {
        ckcapi_CertPopulateModulusExponent(io);
    } else {
        ckcapi_FetchPublicKey(io);
    }
    return;
}

/*
 * fetch the friendly name attribute.
 * can only be called with ckcapiCert type objects!
 */
void
ckcapi_FetchLabel(
    ckcapiInternalObject *io)
{
    ckcapiCertObject *co = &io->u.cert;
    char *label;
    PCCERT_CONTEXT certContext = io->u.cert.certContext;
    char labelDataUTF16[128];
    DWORD size = sizeof(labelDataUTF16);
    DWORD size8 = sizeof(co->labelData);
    BOOL rv;

    rv = CertGetCertificateContextProperty(certContext,
                                           CERT_FRIENDLY_NAME_PROP_ID, labelDataUTF16, &size);
    if (rv) {
        co->labelData = nss_ckcapi_WideToUTF8((LPCWSTR)labelDataUTF16);
        if ((CHAR *)NULL == co->labelData) {
            rv = 0;
        } else {
            size = strlen(co->labelData);
        }
    }
    label = co->labelData;
    /* we are presuming a user cert, make sure it has a nickname, even if
     * Microsoft never gave it one */
    if (!rv && co->hasID) {
        DWORD mserror = GetLastError();
#define DEFAULT_NICKNAME "no Microsoft nickname"
        label = DEFAULT_NICKNAME;
        size = sizeof(DEFAULT_NICKNAME);
        rv = 1;
    }

    if (rv) {
        co->label.data = label;
        co->label.size = size;
    }
    return;
}

void
ckcapi_FetchSerial(
    ckcapiInternalObject *io)
{
    ckcapiCertObject *co = &io->u.cert;
    PCCERT_CONTEXT certContext = io->u.cert.certContext;
    DWORD size = sizeof(co->derSerial);

    BOOL rc = CryptEncodeObject(X509_ASN_ENCODING,
                                X509_MULTI_BYTE_INTEGER,
                                &certContext->pCertInfo->SerialNumber,
                                co->derSerial,
                                &size);
    if (rc) {
        co->serial.data = co->derSerial;
        co->serial.size = size;
    }
    return;
}

/*
 * fetch the key ID.
 */
void
ckcapi_FetchID(
    ckcapiInternalObject *io)
{
    PCCERT_CONTEXT certContext = io->u.cert.certContext;
    DWORD size = 0;
    BOOL rc;

    rc = CertGetCertificateContextProperty(certContext,
                                           CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
    if (!rc) {
        return;
    }
    io->idData = nss_ZNEWARRAY(NULL, char, size);
    if (io->idData == NULL) {
        return;
    }

    rc = CertGetCertificateContextProperty(certContext,
                                           CERT_KEY_IDENTIFIER_PROP_ID, io->idData, &size);
    if (!rc) {
        nss_ZFreeIf(io->idData);
        io->idData = NULL;
        return;
    }
    io->id.data = io->idData;
    io->id.size = size;
    return;
}

/*
 * fetch the hash key.
 */
void
ckcapi_CertFetchHashKey(
    ckcapiInternalObject *io)
{
    ckcapiCertObject *co = &io->u.cert;
    PCCERT_CONTEXT certContext = io->u.cert.certContext;
    DWORD size = certContext->cbCertEncoded;
    DWORD max = sizeof(io->hashKeyData) - 1;
    DWORD offset = 0;

    /* make sure we don't over flow. NOTE: cutting the top of a cert is
     * not a big issue because the signature for will be unique for the cert */
    if (size > max) {
        offset = size - max;
        size = max;
    }

    nsslibc_memcpy(io->hashKeyData, certContext->pbCertEncoded + offset, size);
    io->hashKeyData[size] = (char)(io->objClass & 0xff);

    io->hashKey.data = io->hashKeyData;
    io->hashKey.size = size + 1;
    return;
}

/*
 * fetch the hash key.
 */
void
ckcapi_KeyFetchHashKey(
    ckcapiInternalObject *io)
{
    ckcapiKeyObject *ko = &io->u.key;
    DWORD size;
    DWORD max = sizeof(io->hashKeyData) - 2;
    DWORD offset = 0;
    DWORD provLen = strlen(ko->provName);
    DWORD containerLen = strlen(ko->containerName);

    size = provLen + containerLen;

    /* make sure we don't overflow, try to keep things unique */
    if (size > max) {
        DWORD diff = ((size - max) + 1) / 2;
        provLen -= diff;
        containerLen -= diff;
        size = provLen + containerLen;
    }

    nsslibc_memcpy(io->hashKeyData, ko->provName, provLen);
    nsslibc_memcpy(&io->hashKeyData[provLen],
                   ko->containerName,
                   containerLen);
    io->hashKeyData[size] = (char)(io->objClass & 0xff);
    io->hashKeyData[size + 1] = (char)(ko->provInfo.dwKeySpec & 0xff);

    io->hashKey.data = io->hashKeyData;
    io->hashKey.size = size + 2;
    return;
}

/*
 * fetch the hash key.
 */
void
ckcapi_FetchHashKey(
    ckcapiInternalObject *io)
{
    if (ckcapiCert == io->type) {
        ckcapi_CertFetchHashKey(io);
    } else {
        ckcapi_KeyFetchHashKey(io);
    }
    return;
}

const NSSItem *
ckcapi_FetchCertAttribute(
    ckcapiInternalObject *io,
    CK_ATTRIBUTE_TYPE type)
{
    PCCERT_CONTEXT certContext = io->u.cert.certContext;
    switch (type) {
        case CKA_CLASS:
            return &ckcapi_certClassItem;
        case CKA_TOKEN:
            return &ckcapi_trueItem;
        case CKA_MODIFIABLE:
        case CKA_PRIVATE:
            return &ckcapi_falseItem;
        case CKA_CERTIFICATE_TYPE:
            return &ckcapi_x509Item;
        case CKA_LABEL:
            if (0 == io->u.cert.label.size) {
                ckcapi_FetchLabel(io);
            }
            return &io->u.cert.label;
        case CKA_SUBJECT:
            if (0 == io->u.cert.subject.size) {
                io->u.cert.subject.data =
                    certContext->pCertInfo->Subject.pbData;
                io->u.cert.subject.size =
                    certContext->pCertInfo->Subject.cbData;
            }
            return &io->u.cert.subject;
        case CKA_ISSUER:
            if (0 == io->u.cert.issuer.size) {
                io->u.cert.issuer.data =
                    certContext->pCertInfo->Issuer.pbData;
                io->u.cert.issuer.size =
                    certContext->pCertInfo->Issuer.cbData;
            }
            return &io->u.cert.issuer;
        case CKA_SERIAL_NUMBER:
            if (0 == io->u.cert.serial.size) {
                /* not exactly right. This should be the encoded serial number, but
                 * it's the decoded serial number! */
                ckcapi_FetchSerial(io);
            }
            return &io->u.cert.serial;
        case CKA_VALUE:
            if (0 == io->u.cert.derCert.size) {
                io->u.cert.derCert.data =
                    io->u.cert.certContext->pbCertEncoded;
                io->u.cert.derCert.size =
                    io->u.cert.certContext->cbCertEncoded;
            }
            return &io->u.cert.derCert;
        case CKA_ID:
            if (!io->u.cert.hasID) {
                return NULL;
            }
            if (0 == io->id.size) {
                ckcapi_FetchID(io);
            }
            return &io->id;
        default:
            break;
    }
    return NULL;
}

const NSSItem *
ckcapi_FetchPubKeyAttribute(
    ckcapiInternalObject *io,
    CK_ATTRIBUTE_TYPE type)
{
    PRBool isCertType = (ckcapiCert == io->type);
    ckcapiKeyParams *kp = isCertType ? &io->u.cert.key : &io->u.key.key;

    switch (type) {
        case CKA_CLASS:
            return &ckcapi_pubKeyClassItem;
        case CKA_TOKEN:
        case CKA_LOCAL:
        case CKA_ENCRYPT:
        case CKA_VERIFY:
        case CKA_VERIFY_RECOVER:
            return &ckcapi_trueItem;
        case CKA_PRIVATE:
        case CKA_MODIFIABLE:
        case CKA_DERIVE:
        case CKA_WRAP:
            return &ckcapi_falseItem;
        case CKA_KEY_TYPE:
            return &ckcapi_rsaItem;
        case CKA_LABEL:
            if (!isCertType) {
                return &ckcapi_emptyItem;
            }
            if (0 == io->u.cert.label.size) {
                ckcapi_FetchLabel(io);
            }
            return &io->u.cert.label;
        case CKA_SUBJECT:
            if (!isCertType) {
                return &ckcapi_emptyItem;
            }
            if (0 == io->u.cert.subject.size) {
                PCCERT_CONTEXT certContext =
                    io->u.cert.certContext;
                io->u.cert.subject.data =
                    certContext->pCertInfo->Subject.pbData;
                io->u.cert.subject.size =
                    certContext->pCertInfo->Subject.cbData;
            }
            return &io->u.cert.subject;
        case CKA_MODULUS:
            if (0 == kp->modulus.size) {
                ckcapi_PopulateModulusExponent(io);
            }
            return &kp->modulus;
        case CKA_PUBLIC_EXPONENT:
            if (0 == kp->modulus.size) {
                ckcapi_PopulateModulusExponent(io);
            }
            return &kp->exponent;
        case CKA_ID:
            if (0 == io->id.size) {
                ckcapi_FetchID(io);
            }
            return &io->id;
        default:
            break;
    }
    return NULL;
}

const NSSItem *
ckcapi_FetchPrivKeyAttribute(
    ckcapiInternalObject *io,
    CK_ATTRIBUTE_TYPE type)
{
    PRBool isCertType = (ckcapiCert == io->type);
    ckcapiKeyParams *kp = isCertType ? &io->u.cert.key : &io->u.key.key;

    switch (type) {
        case CKA_CLASS:
            return &ckcapi_privKeyClassItem;
        case CKA_TOKEN:
        case CKA_LOCAL:
        case CKA_SIGN:
        case CKA_DECRYPT:
        case CKA_SIGN_RECOVER:
            return &ckcapi_trueItem;
        case CKA_SENSITIVE:
        case CKA_PRIVATE: /* should move in the future */
        case CKA_MODIFIABLE:
        case CKA_DERIVE:
        case CKA_UNWRAP:
        case CKA_EXTRACTABLE: /* will probably move in the future */
        case CKA_ALWAYS_SENSITIVE:
        case CKA_NEVER_EXTRACTABLE:
            return &ckcapi_falseItem;
        case CKA_KEY_TYPE:
            return &ckcapi_rsaItem;
        case CKA_LABEL:
            if (!isCertType) {
                return &ckcapi_emptyItem;
            }
            if (0 == io->u.cert.label.size) {
                ckcapi_FetchLabel(io);
            }
            return &io->u.cert.label;
        case CKA_SUBJECT:
            if (!isCertType) {
                return &ckcapi_emptyItem;
            }
            if (0 == io->u.cert.subject.size) {
                PCCERT_CONTEXT certContext =
                    io->u.cert.certContext;
                io->u.cert.subject.data =
                    certContext->pCertInfo->Subject.pbData;
                io->u.cert.subject.size =
                    certContext->pCertInfo->Subject.cbData;
            }
            return &io->u.cert.subject;
        case CKA_MODULUS:
            if (0 == kp->modulus.size) {
                ckcapi_PopulateModulusExponent(io);
            }
            return &kp->modulus;
        case CKA_PUBLIC_EXPONENT:
            if (0 == kp->modulus.size) {
                ckcapi_PopulateModulusExponent(io);
            }
            return &kp->exponent;
        case CKA_PRIVATE_EXPONENT:
            if (0 == kp->privateExponent.size) {
                ckcapi_FetchPrivateKey(io);
            }
            return &kp->privateExponent;
        case CKA_PRIME_1:
            if (0 == kp->privateExponent.size) {
                ckcapi_FetchPrivateKey(io);
            }
            return &kp->prime1;
        case CKA_PRIME_2:
            if (0 == kp->privateExponent.size) {
                ckcapi_FetchPrivateKey(io);
            }
            return &kp->prime2;
        case CKA_EXPONENT_1:
            if (0 == kp->privateExponent.size) {
                ckcapi_FetchPrivateKey(io);
            }
            return &kp->exponent1;
        case CKA_EXPONENT_2:
            if (0 == kp->privateExponent.size) {
                ckcapi_FetchPrivateKey(io);
            }
            return &kp->exponent2;
        case CKA_COEFFICIENT:
            if (0 == kp->privateExponent.size) {
                ckcapi_FetchPrivateKey(io);
            }
            return &kp->coefficient;
        case CKA_ID:
            if (0 == io->id.size) {
                ckcapi_FetchID(io);
            }
            return &io->id;
        default:
            return NULL;
    }
}

const NSSItem *
nss_ckcapi_FetchAttribute(
    ckcapiInternalObject *io,
    CK_ATTRIBUTE_TYPE type)
{
    CK_ULONG i;

    if (io->type == ckcapiRaw) {
        for (i = 0; i < io->u.raw.n; i++) {
            if (type == io->u.raw.types[i]) {
                return &io->u.raw.items[i];
            }
        }
        return NULL;
    }
    /* deal with the common attributes */
    switch (io->objClass) {
        case CKO_CERTIFICATE:
            return ckcapi_FetchCertAttribute(io, type);
        case CKO_PRIVATE_KEY:
            return ckcapi_FetchPrivKeyAttribute(io, type);
        case CKO_PUBLIC_KEY:
            return ckcapi_FetchPubKeyAttribute(io, type);
    }
    return NULL;
}

/*
 * check to see if the certificate already exists
 */
static PRBool
ckcapi_cert_exists(
    NSSItem *value,
    ckcapiInternalObject **io)
{
    int count, i;
    PRUint32 size = 0;
    ckcapiInternalObject **listp = NULL;
    CK_ATTRIBUTE myTemplate[2];
    CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
    CK_ULONG templateCount = 2;
    CK_RV error;
    PRBool found = PR_FALSE;

    myTemplate[0].type = CKA_CLASS;
    myTemplate[0].pValue = &cert_class;
    myTemplate[0].ulValueLen = sizeof(cert_class);
    myTemplate[1].type = CKA_VALUE;
    myTemplate[1].pValue = value->data;
    myTemplate[1].ulValueLen = value->size;

    count = nss_ckcapi_collect_all_certs(myTemplate, templateCount, &listp,
                                         &size, 0, &error);

    /* free them */
    if (count > 1) {
        *io = listp[0];
        found = PR_TRUE;
    }

    for (i = 1; i < count; i++) {
        nss_ckcapi_DestroyInternalObject(listp[i]);
    }
    nss_ZFreeIf(listp);
    return found;
}

static PRBool
ckcapi_cert_hasEmail(
    PCCERT_CONTEXT certContext)
{
    int count;

    count = CertGetNameString(certContext, CERT_NAME_EMAIL_TYPE,
                              0, NULL, NULL, 0);

    return count > 1 ? PR_TRUE : PR_FALSE;
}

static PRBool
ckcapi_cert_isRoot(
    PCCERT_CONTEXT certContext)
{
    return CertCompareCertificateName(certContext->dwCertEncodingType,
                                      &certContext->pCertInfo->Issuer, &certContext->pCertInfo->Subject);
}

static PRBool
ckcapi_cert_isCA(
    PCCERT_CONTEXT certContext)
{
    PCERT_EXTENSION extension;
    CERT_BASIC_CONSTRAINTS2_INFO basicInfo;
    DWORD size = sizeof(basicInfo);
    BOOL rc;

    extension = CertFindExtension(szOID_BASIC_CONSTRAINTS,
                                  certContext->pCertInfo->cExtension,
                                  certContext->pCertInfo->rgExtension);
    if ((PCERT_EXTENSION)NULL == extension) {
        return PR_FALSE;
    }
    rc = CryptDecodeObject(X509_ASN_ENCODING, szOID_BASIC_CONSTRAINTS2,
                           extension->Value.pbData, extension->Value.cbData,
                           0, &basicInfo, &size);
    if (!rc) {
        return PR_FALSE;
    }
    return (PRBool)basicInfo.fCA;
}

static CRYPT_KEY_PROV_INFO *
ckcapi_cert_getPrivateKeyInfo(
    PCCERT_CONTEXT certContext,
    NSSItem *keyID)
{
    BOOL rc;
    CRYPT_HASH_BLOB msKeyID;
    DWORD size = 0;
    CRYPT_KEY_PROV_INFO *prov = NULL;

    msKeyID.cbData = keyID->size;
    msKeyID.pbData = keyID->data;

    rc = CryptGetKeyIdentifierProperty(
        &msKeyID,
        CERT_KEY_PROV_INFO_PROP_ID,
        0, NULL, NULL, NULL, &size);
    if (!rc) {
        return (CRYPT_KEY_PROV_INFO *)NULL;
    }
    prov = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
    if ((CRYPT_KEY_PROV_INFO *)prov == NULL) {
        return (CRYPT_KEY_PROV_INFO *)NULL;
    }
    rc = CryptGetKeyIdentifierProperty(
        &msKeyID,
        CERT_KEY_PROV_INFO_PROP_ID,
        0, NULL, NULL, prov, &size);
    if (!rc) {
        nss_ZFreeIf(prov);
        return (CRYPT_KEY_PROV_INFO *)NULL;
    }

    return prov;
}

static CRYPT_KEY_PROV_INFO *
ckcapi_cert_getProvInfo(
    ckcapiInternalObject *io)
{
    BOOL rc;
    DWORD size = 0;
    CRYPT_KEY_PROV_INFO *prov = NULL;

    rc = CertGetCertificateContextProperty(
        io->u.cert.certContext,
        CERT_KEY_PROV_INFO_PROP_ID,
        NULL, &size);
    if (!rc) {
        return (CRYPT_KEY_PROV_INFO *)NULL;
    }
    prov = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
    if ((CRYPT_KEY_PROV_INFO *)prov == NULL) {
        return (CRYPT_KEY_PROV_INFO *)NULL;
    }
    rc = CertGetCertificateContextProperty(
        io->u.cert.certContext,
        CERT_KEY_PROV_INFO_PROP_ID,
        prov, &size);
    if (!rc) {
        nss_ZFreeIf(prov);
        return (CRYPT_KEY_PROV_INFO *)NULL;
    }

    return prov;
}

/* forward declaration */
static void
ckcapi_removeObjectFromHash(
    ckcapiInternalObject *io);

/*
 * Finalize - unneeded
 * Destroy
 * IsTokenObject - CK_TRUE
 * GetAttributeCount
 * GetAttributeTypes
 * GetAttributeSize
 * GetAttribute
 * SetAttribute
 * GetObjectSize
 */

static CK_RV
ckcapi_mdObject_Destroy(
    NSSCKMDObject *mdObject,
    NSSCKFWObject *fwObject,
    NSSCKMDSession *mdSession,
    NSSCKFWSession *fwSession,
    NSSCKMDToken *mdToken,
    NSSCKFWToken *fwToken,
    NSSCKMDInstance *mdInstance,
    NSSCKFWInstance *fwInstance)
{
    ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
    CK_OBJECT_CLASS objClass;
    BOOL rc;
    DWORD provType;
    DWORD msError;
    PRBool isCertType = (PRBool)(ckcapiCert == io->type);
    HCERTSTORE hStore = 0;

    if (ckcapiRaw == io->type) {
        /* there is not 'object write protected' error, use the next best thing */
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    objClass = io->objClass;
    if (CKO_CERTIFICATE == objClass) {
        PCCERT_CONTEXT certContext;

        /* get the store */
        hStore = CertOpenSystemStore(0, io->u.cert.certStore);
        if (0 == hStore) {
            rc = 0;
            goto loser;
        }
        certContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING, 0,
                                                 CERT_FIND_EXISTING, io->u.cert.certContext, NULL);
        if ((PCCERT_CONTEXT)NULL == certContext) {
            rc = 0;
            goto loser;
        }
        rc = CertDeleteCertificateFromStore(certContext);
    } else {
        char *provName = NULL;
        char *containerName = NULL;
        HCRYPTPROV hProv;
        CRYPT_HASH_BLOB msKeyID;

        if (0 == io->id.size) {
            ckcapi_FetchID(io);
        }

        if (isCertType) {
            CRYPT_KEY_PROV_INFO *provInfo = ckcapi_cert_getProvInfo(io);
            provName = nss_ckcapi_WideToUTF8(provInfo->pwszProvName);
            containerName = nss_ckcapi_WideToUTF8(provInfo->pwszContainerName);
            provType = provInfo->dwProvType;
            nss_ZFreeIf(provInfo);
        } else {
            provName = io->u.key.provName;
            containerName = io->u.key.containerName;
            provType = io->u.key.provInfo.dwProvType;
            io->u.key.provName = NULL;
            io->u.key.containerName = NULL;
        }
        /* first remove the key id pointer */
        msKeyID.cbData = io->id.size;
        msKeyID.pbData = io->id.data;
        rc = CryptSetKeyIdentifierProperty(&msKeyID,
                                           CERT_KEY_PROV_INFO_PROP_ID, CRYPT_KEYID_DELETE_FLAG, NULL, NULL, NULL);
        if (rc) {
            rc = CryptAcquireContext(&hProv, containerName, provName, provType,
                                     CRYPT_DELETEKEYSET);
        }
        nss_ZFreeIf(provName);
        nss_ZFreeIf(containerName);
    }
loser:

    if (hStore) {
        CertCloseStore(hStore, 0);
    }
    if (!rc) {
        msError = GetLastError();
        return CKR_GENERAL_ERROR;
    }

    /* remove it from the hash */
    ckcapi_removeObjectFromHash(io);

    /* free the puppy.. */
    nss_ckcapi_DestroyInternalObject(io);
    return CKR_OK;
}

static CK_BBOOL
ckcapi_mdObject_IsTokenObject(
    NSSCKMDObject *mdObject,
    NSSCKFWObject *fwObject,
    NSSCKMDSession *mdSession,
    NSSCKFWSession *fwSession,
    NSSCKMDToken *mdToken,
    NSSCKFWToken *fwToken,
    NSSCKMDInstance *mdInstance,
    NSSCKFWInstance *fwInstance)
{
    return CK_TRUE;
}

static CK_ULONG
ckcapi_mdObject_GetAttributeCount(
    NSSCKMDObject *mdObject,
    NSSCKFWObject *fwObject,
    NSSCKMDSession *mdSession,
    NSSCKFWSession *fwSession,
    NSSCKMDToken *mdToken,
    NSSCKFWToken *fwToken,
    NSSCKMDInstance *mdInstance,
    NSSCKFWInstance *fwInstance,
    CK_RV *pError)
{
    ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;

    if (ckcapiRaw == io->type) {
        return io->u.raw.n;
    }
    switch (io->objClass) {
        case CKO_CERTIFICATE:
            return certAttrsCount;
        case CKO_PUBLIC_KEY:
            return pubKeyAttrsCount;
        case CKO_PRIVATE_KEY:
            return privKeyAttrsCount;
        default:
            break;
    }
    return 0;
}

static CK_RV
ckcapi_mdObject_GetAttributeTypes(
    NSSCKMDObject *mdObject,
    NSSCKFWObject *fwObject,
    NSSCKMDSession *mdSession,
    NSSCKFWSession *fwSession,
    NSSCKMDToken *mdToken,
    NSSCKFWToken *fwToken,
    NSSCKMDInstance *mdInstance,
    NSSCKFWInstance *fwInstance,
    CK_ATTRIBUTE_TYPE_PTR typeArray,
    CK_ULONG ulCount)
{
    ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
    CK_ULONG i;
    CK_RV error = CKR_OK;
    const CK_ATTRIBUTE_TYPE *attrs = NULL;
    CK_ULONG size = ckcapi_mdObject_GetAttributeCount(
        mdObject, fwObject, mdSession, fwSession,
        mdToken, fwToken, mdInstance, fwInstance, &error);

    if (size != ulCount) {
        return CKR_BUFFER_TOO_SMALL;
    }
    if (io->type == ckcapiRaw) {
        attrs = io->u.raw.types;
    } else
        switch (io->objClass) {
            case CKO_CERTIFICATE:
                attrs =
                    certAttrs;
                break;
            case CKO_PUBLIC_KEY:
                attrs =
                    pubKeyAttrs;
                break;
            case CKO_PRIVATE_KEY:
                attrs =
                    privKeyAttrs;
                break;
            default:
                return CKR_OK;
        }

    for (i = 0; i < size; i++) {
        typeArray[i] = attrs[i];
    }

    return CKR_OK;
}

static CK_ULONG
ckcapi_mdObject_GetAttributeSize(
    NSSCKMDObject *mdObject,
    NSSCKFWObject *fwObject,
    NSSCKMDSession *mdSession,
    NSSCKFWSession *fwSession,
    NSSCKMDToken *mdToken,
    NSSCKFWToken *fwToken,
    NSSCKMDInstance *mdInstance,
    NSSCKFWInstance *fwInstance,
    CK_ATTRIBUTE_TYPE attribute,
    CK_RV *pError)
{
    ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;

    const NSSItem *b;

    b = nss_ckcapi_FetchAttribute(io, attribute);

    if ((const NSSItem *)NULL == b) {
        *pError = CKR_ATTRIBUTE_TYPE_INVALID;
        return 0;
    }
    return b->size;
}

static CK_RV
ckcapi_mdObject_SetAttribute(
    NSSCKMDObject *mdObject,
    NSSCKFWObject *fwObject,
    NSSCKMDSession *mdSession,
    NSSCKFWSession *fwSession,
    NSSCKMDToken *mdToken,
    NSSCKFWToken *fwToken,
    NSSCKMDInstance *mdInstance,
    NSSCKFWInstance *fwInstance,
    CK_ATTRIBUTE_TYPE attribute,
    NSSItem *value)
{
    return CKR_OK;
}

static NSSCKFWItem
ckcapi_mdObject_GetAttribute(
    NSSCKMDObject *mdObject,
    NSSCKFWObject *fwObject,
    NSSCKMDSession *mdSession,
    NSSCKFWSession *fwSession,
    NSSCKMDToken *mdToken,
    NSSCKFWToken *fwToken,
    NSSCKMDInstance *mdInstance,
    NSSCKFWInstance *fwInstance,
    CK_ATTRIBUTE_TYPE attribute,
    CK_RV *pError)
{
    NSSCKFWItem mdItem;
    ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;

    mdItem.needsFreeing = PR_FALSE;
    mdItem.item = (NSSItem *)nss_ckcapi_FetchAttribute(io, attribute);

    if ((NSSItem *)NULL == mdItem.item) {
        *pError = CKR_ATTRIBUTE_TYPE_INVALID;
    }

    return mdItem;
}

static CK_ULONG
ckcapi_mdObject_GetObjectSize(
    NSSCKMDObject *mdObject,
    NSSCKFWObject *fwObject,
    NSSCKMDSession *mdSession,
    NSSCKFWSession *fwSession,
    NSSCKMDToken *mdToken,
    NSSCKFWToken *fwToken,
    NSSCKMDInstance *mdInstance,
    NSSCKFWInstance *fwInstance,
    CK_RV *pError)
{
    ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
    CK_ULONG rv = 1;

    /* size is irrelevant to this token */
    return rv;
}

static const NSSCKMDObject
    ckcapi_prototype_mdObject = {
        (void *)NULL, /* etc */
        NULL,         /* Finalize */
        ckcapi_mdObject_Destroy,
        ckcapi_mdObject_IsTokenObject,
        ckcapi_mdObject_GetAttributeCount,
        ckcapi_mdObject_GetAttributeTypes,
        ckcapi_mdObject_GetAttributeSize,
        ckcapi_mdObject_GetAttribute,
        NULL, /* FreeAttribute */
        ckcapi_mdObject_SetAttribute,
        ckcapi_mdObject_GetObjectSize,
        (void *)NULL /* null terminator */
    };

static nssHash *ckcapiInternalObjectHash = NULL;

NSS_IMPLEMENT NSSCKMDObject *
nss_ckcapi_CreateMDObject(
    NSSArena *arena,
    ckcapiInternalObject *io,
    CK_RV *pError)
{
    if ((nssHash *)NULL == ckcapiInternalObjectHash) {
        ckcapiInternalObjectHash = nssHash_CreateItem(NULL, 10);
    }
    if (ckcapiCert == io->type) {
        /* the hash key, not a cryptographic key */
        NSSItem *key = &io->hashKey;
        ckcapiInternalObject *old_o = NULL;

        if (key->size == 0) {
            ckcapi_FetchHashKey(io);
        }
        old_o = (ckcapiInternalObject *)
            nssHash_Lookup(ckcapiInternalObjectHash, key);
        if (!old_o) {
            nssHash_Add(ckcapiInternalObjectHash, key, io);
        } else if (old_o != io) {
            nss_ckcapi_DestroyInternalObject(io);
            io = old_o;
        }
    }

    if ((void *)NULL == io->mdObject.etc) {
        (void)nsslibc_memcpy(&io->mdObject, &ckcapi_prototype_mdObject,
                             sizeof(ckcapi_prototype_mdObject));
        io->mdObject.etc = (void *)io;
    }
    return &io->mdObject;
}

static void
ckcapi_removeObjectFromHash(
    ckcapiInternalObject *io)
{
    NSSItem *key = &io->hashKey;

    if ((nssHash *)NULL == ckcapiInternalObjectHash) {
        return;
    }
    if (key->size == 0) {
        ckcapi_FetchHashKey(io);
    }
    nssHash_Remove(ckcapiInternalObjectHash, key);
    return;
}

void
nss_ckcapi_DestroyInternalObject(
    ckcapiInternalObject *io)
{
    switch (io->type) {
        case ckcapiRaw:
            return;
        case ckcapiCert:
            CertFreeCertificateContext(io->u.cert.certContext);
            nss_ZFreeIf(io->u.cert.labelData);
            nss_ZFreeIf(io->u.cert.key.privateKey);
            nss_ZFreeIf(io->u.cert.key.pubKey);
            nss_ZFreeIf(io->idData);
            break;
        case ckcapiBareKey:
            nss_ZFreeIf(io->u.key.provInfo.pwszContainerName);
            nss_ZFreeIf(io->u.key.provInfo.pwszProvName);
            nss_ZFreeIf(io->u.key.provName);
            nss_ZFreeIf(io->u.key.containerName);
            nss_ZFreeIf(io->u.key.key.privateKey);
            nss_ZFreeIf(io->u.key.key.pubKey);
            if (0 != io->u.key.hProv) {
                CryptReleaseContext(io->u.key.hProv, 0);
            }
            nss_ZFreeIf(io->idData);
            break;
    }
    nss_ZFreeIf(io);
    return;
}

static ckcapiInternalObject *
nss_ckcapi_CreateCertificate(
    NSSCKFWSession *fwSession,
    CK_ATTRIBUTE_PTR pTemplate,
    CK_ULONG ulAttributeCount,
    CK_RV *pError)
{
    NSSItem value;
    NSSItem keyID;
    char *storeStr;
    ckcapiInternalObject *io = NULL;
    PCCERT_CONTEXT certContext = NULL;
    PCCERT_CONTEXT storedCertContext = NULL;
    CRYPT_KEY_PROV_INFO *prov_info = NULL;
    char *nickname = NULL;
    HCERTSTORE hStore = 0;
    DWORD msError = 0;
    PRBool hasID;
    CK_RV dummy;
    BOOL rc;

    *pError = nss_ckcapi_GetAttribute(CKA_VALUE, pTemplate,
                                      ulAttributeCount, &value);

    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }

    *pError = nss_ckcapi_GetAttribute(CKA_ID, pTemplate,
                                      ulAttributeCount, &keyID);

    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }

    if (ckcapi_cert_exists(&value, &io)) {
        return io;
    }

    /* OK, we are creating a new one, figure out what store it belongs to..
   * first get a certContext handle.. */
    certContext = CertCreateCertificateContext(X509_ASN_ENCODING,
                                               value.data, value.size);
    if ((PCCERT_CONTEXT)NULL == certContext) {
        msError = GetLastError();
        *pError = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }

    /* do we have a private key laying around... */
    prov_info = ckcapi_cert_getPrivateKeyInfo(certContext, &keyID);
    if (prov_info) {
        CRYPT_DATA_BLOB msKeyID;
        storeStr = "My";
        hasID = PR_TRUE;
        rc = CertSetCertificateContextProperty(certContext,
                                               CERT_KEY_PROV_INFO_PROP_ID,
                                               0, prov_info);
        nss_ZFreeIf(prov_info);
        if (!rc) {
            msError = GetLastError();
            *pError = CKR_DEVICE_ERROR;
            goto loser;
        }
        msKeyID.cbData = keyID.size;
        msKeyID.pbData = keyID.data;
        rc = CertSetCertificateContextProperty(certContext,
                                               CERT_KEY_IDENTIFIER_PROP_ID,
                                               0, &msKeyID);
        if (!rc) {
            msError = GetLastError();
            *pError = CKR_DEVICE_ERROR;
            goto loser;
        }

        /* does it look like a CA */
    } else if (ckcapi_cert_isCA(certContext)) {
        storeStr = ckcapi_cert_isRoot(certContext) ? "CA" : "Root";
        /* does it look like an S/MIME cert */
    } else if (ckcapi_cert_hasEmail(certContext)) {
        storeStr = "AddressBook";
    } else {
        /* just pick a store */
        storeStr = "CA";
    }

    /* get the nickname, not an error if we can't find it */
    nickname = nss_ckcapi_GetStringAttribute(CKA_LABEL, pTemplate,
                                             ulAttributeCount, &dummy);
    if (nickname) {
        LPWSTR nicknameUTF16 = NULL;
        CRYPT_DATA_BLOB nicknameBlob;

        nicknameUTF16 = nss_ckcapi_UTF8ToWide(nickname);
        nss_ZFreeIf(nickname);
        nickname = NULL;
        if ((LPWSTR)NULL == nicknameUTF16) {
            *pError = CKR_HOST_MEMORY;
            goto loser;
        }
        nicknameBlob.cbData = nss_ckcapi_WideSize(nicknameUTF16);
        nicknameBlob.pbData = (BYTE *)nicknameUTF16;
        rc = CertSetCertificateContextProperty(certContext,
                                               CERT_FRIENDLY_NAME_PROP_ID, 0, &nicknameBlob);
        nss_ZFreeIf(nicknameUTF16);
        if (!rc) {
            msError = GetLastError();
            *pError = CKR_DEVICE_ERROR;
            goto loser;
        }
    }

    hStore = CertOpenSystemStore((HCRYPTPROV)NULL, storeStr);
    if (0 == hStore) {
        msError = GetLastError();
        *pError = CKR_DEVICE_ERROR;
        goto loser;
    }

    rc = CertAddCertificateContextToStore(hStore, certContext,
                                          CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, &storedCertContext);
    CertFreeCertificateContext(certContext);
    certContext = NULL;
    CertCloseStore(hStore, 0);
    hStore = 0;
    if (!rc) {
        msError = GetLastError();
        *pError = CKR_DEVICE_ERROR;
        goto loser;
    }

    io = nss_ZNEW(NULL, ckcapiInternalObject);
    if ((ckcapiInternalObject *)NULL == io) {
        *pError = CKR_HOST_MEMORY;
        goto loser;
    }
    io->type = ckcapiCert;
    io->objClass = CKO_CERTIFICATE;
    io->u.cert.certContext = storedCertContext;
    io->u.cert.hasID = hasID;
    return io;

loser:
    if (certContext) {
        CertFreeCertificateContext(certContext);
        certContext = NULL;
    }
    if (storedCertContext) {
        CertFreeCertificateContext(storedCertContext);
        storedCertContext = NULL;
    }
    if (0 != hStore) {
        CertCloseStore(hStore, 0);
    }
    return (ckcapiInternalObject *)NULL;
}

static char *
ckcapi_getDefaultProvider(
    CK_RV *pError)
{
    char *name = NULL;
    BOOL rc;
    DWORD nameLength = 0;

    rc = CryptGetDefaultProvider(PROV_RSA_FULL, NULL, CRYPT_USER_DEFAULT, NULL,
                                 &nameLength);
    if (!rc) {
        return (char *)NULL;
    }

    name = nss_ZNEWARRAY(NULL, char, nameLength);
    if ((char *)NULL == name) {
        return (char *)NULL;
    }
    rc = CryptGetDefaultProvider(PROV_RSA_FULL, NULL, CRYPT_USER_DEFAULT, name,
                                 &nameLength);
    if (!rc) {
        nss_ZFreeIf(name);
        return (char *)NULL;
    }

    return name;
}

static char *
ckcapi_getContainer(
    CK_RV *pError,
    NSSItem *id)
{
    RPC_STATUS rstat;
    UUID uuid;
    char *uuidStr;
    char *container;

    rstat = UuidCreate(&uuid);
    rstat = UuidToString(&uuid, &uuidStr);

    /* convert it from rcp memory to our own */
    container = nssUTF8_Duplicate(uuidStr, NULL);
    RpcStringFree(&uuidStr);

    return container;
}

static CK_RV
ckcapi_buildPrivateKeyBlob(
    NSSItem *keyBlob,
    NSSItem *modulus,
    NSSItem *publicExponent,
    NSSItem *privateExponent,
    NSSItem *prime1,
    NSSItem *prime2,
    NSSItem *exponent1,
    NSSItem *exponent2,
    NSSItem *coefficient,
    PRBool isKeyExchange)
{
    CAPI_RSA_KEY_BLOB *keyBlobData = NULL;
    unsigned char *target;
    unsigned long modSize = modulus->size;
    unsigned long dataSize;
    CK_RV error = CKR_OK;

    /* validate extras */
    if (privateExponent->size != modSize) {
        error = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }
    if (prime1->size != modSize / 2) {
        error = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }
    if (prime2->size != modSize / 2) {
        error = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }
    if (exponent1->size != modSize / 2) {
        error = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }
    if (exponent2->size != modSize / 2) {
        error = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }
    if (coefficient->size != modSize / 2) {
        error = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }
    dataSize = (modSize * 4) + (modSize / 2) + sizeof(CAPI_RSA_KEY_BLOB);
    keyBlobData = (CAPI_RSA_KEY_BLOB *)nss_ZAlloc(NULL, dataSize);
    if ((CAPI_RSA_KEY_BLOB *)NULL == keyBlobData) {
        error = CKR_HOST_MEMORY;
        goto loser;
    }

    keyBlobData->header.bType = PRIVATEKEYBLOB;
    keyBlobData->header.bVersion = 0x02;
    keyBlobData->header.reserved = 0x00;
    keyBlobData->header.aiKeyAlg = isKeyExchange ? CALG_RSA_KEYX : CALG_RSA_SIGN;
    keyBlobData->rsa.magic = 0x32415352;
    keyBlobData->rsa.bitlen = modSize * 8;
    keyBlobData->rsa.pubexp = nss_ckcapi_DataToInt(publicExponent, &error);
    if (CKR_OK != error) {
        goto loser;
    }

    target = &keyBlobData->data[CAPI_MODULUS_OFFSET(modSize)];
    nsslibc_memcpy(target, modulus->data, modulus->size);
    modulus->data = target;
    ckcapi_ReverseData(modulus);

    target = &keyBlobData->data[CAPI_PRIVATE_EXP_OFFSET(modSize)];
    nsslibc_memcpy(target, privateExponent->data, privateExponent->size);
    privateExponent->data = target;
    ckcapi_ReverseData(privateExponent);

    target = &keyBlobData->data[CAPI_PRIME_1_OFFSET(modSize)];
    nsslibc_memcpy(target, prime1->data, prime1->size);
    prime1->data = target;
    ckcapi_ReverseData(prime1);

    target = &keyBlobData->data[CAPI_PRIME_2_OFFSET(modSize)];
    nsslibc_memcpy(target, prime2->data, prime2->size);
    prime2->data = target;
    ckcapi_ReverseData(prime2);

    target = &keyBlobData->data[CAPI_EXPONENT_1_OFFSET(modSize)];
    nsslibc_memcpy(target, exponent1->data, exponent1->size);
    exponent1->data = target;
    ckcapi_ReverseData(exponent1);

    target = &keyBlobData->data[CAPI_EXPONENT_2_OFFSET(modSize)];
    nsslibc_memcpy(target, exponent2->data, exponent2->size);
    exponent2->data = target;
    ckcapi_ReverseData(exponent2);

    target = &keyBlobData->data[CAPI_COEFFICIENT_OFFSET(modSize)];
    nsslibc_memcpy(target, coefficient->data, coefficient->size);
    coefficient->data = target;
    ckcapi_ReverseData(coefficient);

    keyBlob->data = keyBlobData;
    keyBlob->size = dataSize;

    return CKR_OK;

loser:
    nss_ZFreeIf(keyBlobData);
    return error;
}

static ckcapiInternalObject *
nss_ckcapi_CreatePrivateKey(
    NSSCKFWSession *fwSession,
    CK_ATTRIBUTE_PTR pTemplate,
    CK_ULONG ulAttributeCount,
    CK_RV *pError)
{
    NSSItem modulus;
    NSSItem publicExponent;
    NSSItem privateExponent;
    NSSItem exponent1;
    NSSItem exponent2;
    NSSItem prime1;
    NSSItem prime2;
    NSSItem coefficient;
    NSSItem keyID;
    NSSItem keyBlob;
    ckcapiInternalObject *io = NULL;
    char *providerName = NULL;
    char *containerName = NULL;
    char *idData = NULL;
    CRYPT_KEY_PROV_INFO provInfo;
    CRYPT_HASH_BLOB msKeyID;
    CK_KEY_TYPE keyType;
    HCRYPTPROV hProv = 0;
    HCRYPTKEY hKey = 0;
    PRBool decrypt;
    DWORD keySpec;
    DWORD msError;
    BOOL rc;

    keyType = nss_ckcapi_GetULongAttribute(CKA_KEY_TYPE, pTemplate, ulAttributeCount, pError);
    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }
    if (CKK_RSA != keyType) {
        *pError = CKR_ATTRIBUTE_VALUE_INVALID;
        return (ckcapiInternalObject *)NULL;
    }

    decrypt = nss_ckcapi_GetBoolAttribute(CKA_DECRYPT,
                                          pTemplate, ulAttributeCount, pError);
    if (CKR_TEMPLATE_INCOMPLETE == *pError) {
        decrypt = PR_TRUE; /* default to true */
    }
    decrypt = decrypt || nss_ckcapi_GetBoolAttribute(CKA_UNWRAP,
                                                     pTemplate, ulAttributeCount, pError);
    if (CKR_TEMPLATE_INCOMPLETE == *pError) {
        decrypt = PR_TRUE; /* default to true */
    }
    keySpec = decrypt ? AT_KEYEXCHANGE : AT_SIGNATURE;

    *pError = nss_ckcapi_GetAttribute(CKA_MODULUS, pTemplate,
                                      ulAttributeCount, &modulus);
    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }
    *pError = nss_ckcapi_GetAttribute(CKA_PUBLIC_EXPONENT, pTemplate,
                                      ulAttributeCount, &publicExponent);
    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }
    *pError = nss_ckcapi_GetAttribute(CKA_PRIVATE_EXPONENT, pTemplate,
                                      ulAttributeCount, &privateExponent);
    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }
    *pError = nss_ckcapi_GetAttribute(CKA_PRIME_1, pTemplate,
                                      ulAttributeCount, &prime1);
    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }
    *pError = nss_ckcapi_GetAttribute(CKA_PRIME_2, pTemplate,
                                      ulAttributeCount, &prime2);
    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }
    *pError = nss_ckcapi_GetAttribute(CKA_EXPONENT_1, pTemplate,
                                      ulAttributeCount, &exponent1);
    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }
    *pError = nss_ckcapi_GetAttribute(CKA_EXPONENT_2, pTemplate,
                                      ulAttributeCount, &exponent2);
    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }
    *pError = nss_ckcapi_GetAttribute(CKA_COEFFICIENT, pTemplate,
                                      ulAttributeCount, &coefficient);
    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }
    *pError = nss_ckcapi_GetAttribute(CKA_ID, pTemplate,
                                      ulAttributeCount, &keyID);
    if (CKR_OK != *pError) {
        return (ckcapiInternalObject *)NULL;
    }
    providerName = ckcapi_getDefaultProvider(pError);
    if ((char *)NULL == providerName) {
        return (ckcapiInternalObject *)NULL;
    }
    containerName = ckcapi_getContainer(pError, &keyID);
    if ((char *)NULL == containerName) {
        goto loser;
    }
    rc = CryptAcquireContext(&hProv, containerName, providerName,
                             PROV_RSA_FULL, CRYPT_NEWKEYSET);
    if (!rc) {
        msError = GetLastError();
        *pError = CKR_DEVICE_ERROR;
        goto loser;
    }

    *pError = ckcapi_buildPrivateKeyBlob(
        &keyBlob,
        &modulus,
        &publicExponent,
        &privateExponent,
        &prime1,
        &prime2,
        &exponent1,
        &exponent2,
        &coefficient,
        decrypt);
    if (CKR_OK != *pError) {
        goto loser;
    }

    rc = CryptImportKey(hProv, keyBlob.data, keyBlob.size,
                        0, CRYPT_EXPORTABLE, &hKey);
    if (!rc) {
        msError = GetLastError();
        *pError = CKR_DEVICE_ERROR;
        goto loser;
    }

    idData = nss_ZNEWARRAY(NULL, char, keyID.size);
    if ((void *)NULL == idData) {
        *pError = CKR_HOST_MEMORY;
        goto loser;
    }
    nsslibc_memcpy(idData, keyID.data, keyID.size);

    provInfo.pwszContainerName = nss_ckcapi_UTF8ToWide(containerName);
    provInfo.pwszProvName = nss_ckcapi_UTF8ToWide(providerName);
    provInfo.dwProvType = PROV_RSA_FULL;
    provInfo.dwFlags = 0;
    provInfo.cProvParam = 0;
    provInfo.rgProvParam = NULL;
    provInfo.dwKeySpec = keySpec;

    msKeyID.cbData = keyID.size;
    msKeyID.pbData = keyID.data;

    rc = CryptSetKeyIdentifierProperty(&msKeyID, CERT_KEY_PROV_INFO_PROP_ID,
                                       0, NULL, NULL, &provInfo);
    if (!rc) {
        goto loser;
    }

    /* handle error here */
    io = nss_ZNEW(NULL, ckcapiInternalObject);
    if ((ckcapiInternalObject *)NULL == io) {
        *pError = CKR_HOST_MEMORY;
        goto loser;
    }
    io->type = ckcapiBareKey;
    io->objClass = CKO_PRIVATE_KEY;
    io->u.key.provInfo = provInfo;
    io->u.key.provName = providerName;
    io->u.key.containerName = containerName;
    io->u.key.hProv = hProv; /* save the handle */
    io->idData = idData;
    io->id.data = idData;
    io->id.size = keyID.size;
    /* done with the key handle */
    CryptDestroyKey(hKey);
    return io;

loser:
    nss_ZFreeIf(containerName);
    nss_ZFreeIf(providerName);
    nss_ZFreeIf(idData);
    if (0 != hProv) {
        CryptReleaseContext(hProv, 0);
    }
    if (0 != hKey) {
        CryptDestroyKey(hKey);
    }
    return (ckcapiInternalObject *)NULL;
}

NSS_EXTERN NSSCKMDObject *
nss_ckcapi_CreateObject(
    NSSCKFWSession *fwSession,
    CK_ATTRIBUTE_PTR pTemplate,
    CK_ULONG ulAttributeCount,
    CK_RV *pError)
{
    CK_OBJECT_CLASS objClass;
    ckcapiInternalObject *io = NULL;
    CK_BBOOL isToken;

    /*
     * only create token objects
     */
    isToken = nss_ckcapi_GetBoolAttribute(CKA_TOKEN, pTemplate,
                                          ulAttributeCount, pError);
    if (CKR_OK != *pError) {
        return (NSSCKMDObject *)NULL;
    }
    if (!isToken) {
        *pError = CKR_ATTRIBUTE_VALUE_INVALID;
        return (NSSCKMDObject *)NULL;
    }

    /*
     * only create keys and certs.
     */
    objClass = nss_ckcapi_GetULongAttribute(CKA_CLASS, pTemplate,
                                            ulAttributeCount, pError);
    if (CKR_OK != *pError) {
        return (NSSCKMDObject *)NULL;
    }
#ifdef notdef
    if (objClass == CKO_PUBLIC_KEY) {
        return CKR_OK; /* fake public key creation, happens as a side effect of
                        * private key creation */
    }
#endif
    if (objClass == CKO_CERTIFICATE) {
        io = nss_ckcapi_CreateCertificate(fwSession, pTemplate,
                                          ulAttributeCount, pError);
    } else if (objClass == CKO_PRIVATE_KEY) {
        io = nss_ckcapi_CreatePrivateKey(fwSession, pTemplate,
                                         ulAttributeCount, pError);
    } else {
        *pError = CKR_ATTRIBUTE_VALUE_INVALID;
    }

    if ((ckcapiInternalObject *)NULL == io) {
        return (NSSCKMDObject *)NULL;
    }
    return nss_ckcapi_CreateMDObject(NULL, io, pError);
}
