
/* 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/. */
/*
 * This file PKCS #12 fuctions that should really be moved to the
 * PKCS #12 directory, however we can't do that in a point release
 * because that will break binary compatibility, so we keep them here for now.
 */

#include "seccomon.h"
#include "secmod.h"
#include "secmodi.h"
#include "secmodti.h"
#include "secmodt.h"
#include "pkcs11.h"
#include "pk11func.h"
#include "secitem.h"
#include "keyhi.h"
#include "secoid.h"
#include "secasn1.h"
#include "secerr.h"
#include "prerror.h"

/* These data structures should move to a common .h file shared between the
 * wrappers and the pkcs 12 code. */

/*
** RSA Raw Private Key structures
*/

/* member names from PKCS#1, section 7.2 */
struct SECKEYRSAPrivateKeyStr {
    PLArenaPool *arena;
    SECItem version;
    SECItem modulus;
    SECItem publicExponent;
    SECItem privateExponent;
    SECItem prime1;
    SECItem prime2;
    SECItem exponent1;
    SECItem exponent2;
    SECItem coefficient;
};
typedef struct SECKEYRSAPrivateKeyStr SECKEYRSAPrivateKey;

/*
** DSA Raw Private Key structures
*/

struct SECKEYDSAPrivateKeyStr {
    SECKEYPQGParams params;
    SECItem privateValue;
};
typedef struct SECKEYDSAPrivateKeyStr SECKEYDSAPrivateKey;

/*
** Diffie-Hellman Raw Private Key structures
** Structure member names suggested by PKCS#3.
*/
struct SECKEYDHPrivateKeyStr {
    PLArenaPool *arena;
    SECItem prime;
    SECItem base;
    SECItem privateValue;
};
typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey;

/*
** Elliptic Curve Private Key structures
** <https://tools.ietf.org/html/rfc5915#section-3>
*/
struct SECKEYECPrivateKeyStr {
    PLArenaPool *arena;
    SECItem version;
    SECItem curveOID;    /* optional/ignored */
    SECItem publicValue; /* required (for now) */
    SECItem privateValue;
};
typedef struct SECKEYECPrivateKeyStr SECKEYECPrivateKey;

/*
** raw private key object
*/
struct SECKEYRawPrivateKeyStr {
    PLArenaPool *arena;
    KeyType keyType;
    union {
        SECKEYRSAPrivateKey rsa;
        SECKEYDSAPrivateKey dsa;
        SECKEYDHPrivateKey dh;
        SECKEYECPrivateKey ec;
    } u;
};
typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey;

SEC_ASN1_MKSUB(SEC_AnyTemplate)
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)

/* ASN1 Templates for new decoder/encoder */
/*
 * Attribute value for PKCS8 entries (static?)
 */
const SEC_ASN1Template SECKEY_AttributeTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(SECKEYAttribute) },
    { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) },
    { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(SECKEYAttribute, attrValue),
      SEC_ASN1_SUB(SEC_AnyTemplate) },
    { 0 }
};

const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = {
    { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate },
};

const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo, version) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(SECKEYPrivateKeyInfo, algorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo, privateKey) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
      offsetof(SECKEYPrivateKeyInfo, attributes),
      SECKEY_SetOfAttributeTemplate },
    { 0 }
};

const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = {
    { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate }
};

const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.version) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.modulus) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.publicExponent) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.privateExponent) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.prime1) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.prime2) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.exponent1) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.exponent2) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.coefficient) },
    { 0 }
};

const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[] = {
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dsa.privateValue) },
};

const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = {
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.privateValue) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.base) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.prime) },
};

SEC_ASN1_MKSUB(SEC_BitStringTemplate)
SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)

const SEC_ASN1Template SECKEY_ECPrivateKeyExportTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) },
    { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.ec.version) },
    { SEC_ASN1_OCTET_STRING,
      offsetof(SECKEYRawPrivateKey, u.ec.privateValue) },
    /* This value will always be ignored. u.ec.curveOID will always be
     * overriden with the outer AlgorithmID.parameters. */
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
          SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
          SEC_ASN1_XTRN | 0,
      offsetof(SECKEYRawPrivateKey, u.ec.curveOID),
      SEC_ASN1_SUB(SEC_ObjectIDTemplate) },
    /* The public value is optional per RFC, but required in NSS. We
     * can't do scalar mult on ECs to get a raw point with PK11 APIs. */
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
          SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
          SEC_ASN1_XTRN | 1,
      offsetof(SECKEYRawPrivateKey, u.ec.publicValue),
      SEC_ASN1_SUB(SEC_BitStringTemplate) },
    { 0 }
};

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

const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = {
    { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate }
};

SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate)

/*
 * See bugzilla bug 125359
 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
 * all of the templates above that en/decode into integers must be converted
 * from ASN.1's signed integer type.  This is done by marking either the
 * source or destination (encoding or decoding, respectively) type as
 * siUnsignedInteger.
 */

static void
prepare_rsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
{
    key->u.rsa.modulus.type = siUnsignedInteger;
    key->u.rsa.publicExponent.type = siUnsignedInteger;
    key->u.rsa.privateExponent.type = siUnsignedInteger;
    key->u.rsa.prime1.type = siUnsignedInteger;
    key->u.rsa.prime2.type = siUnsignedInteger;
    key->u.rsa.exponent1.type = siUnsignedInteger;
    key->u.rsa.exponent2.type = siUnsignedInteger;
    key->u.rsa.coefficient.type = siUnsignedInteger;
}

static void
prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
{
    key->u.dsa.privateValue.type = siUnsignedInteger;
    key->u.dsa.params.prime.type = siUnsignedInteger;
    key->u.dsa.params.subPrime.type = siUnsignedInteger;
    key->u.dsa.params.base.type = siUnsignedInteger;
}

static void
prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
{
    key->u.dh.privateValue.type = siUnsignedInteger;
    key->u.dh.prime.type = siUnsignedInteger;
    key->u.dh.base.type = siUnsignedInteger;
}

static void
prepare_ec_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
{
    key->u.ec.version.type = siUnsignedInteger;
    key->u.ec.curveOID.type = siUnsignedInteger;
    key->u.ec.privateValue.type = siUnsignedInteger;
    key->u.ec.publicValue.type = siUnsignedInteger;
}

SECStatus
PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI,
                             SECItem *nickname, SECItem *publicValue, PRBool isPerm,
                             PRBool isPrivate, unsigned int keyUsage, void *wincx)
{
    return PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPKI,
                                                    nickname, publicValue,
                                                    isPerm, isPrivate, keyUsage,
                                                    NULL, wincx);
}

SECStatus
PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
                                         SECItem *nickname, SECItem *publicValue,
                                         PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
                                         SECKEYPrivateKey **privk, void *wincx)
{
    SECKEYPrivateKeyInfo *pki = NULL;
    PLArenaPool *temparena = NULL;
    SECStatus rv = SECFailure;

    temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!temparena)
        return rv;
    pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo);
    if (!pki) {
        PORT_FreeArena(temparena, PR_FALSE);
        return rv;
    }
    pki->arena = temparena;

    rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate,
                            derPKI);
    if (rv != SECSuccess) {
        /* If SEC_ASN1DecodeItem fails, we cannot assume anything about the
         * validity of the data in pki. The best we can do is free the arena
         * and return. */
        PORT_FreeArena(temparena, PR_TRUE);
        return rv;
    }
    if (pki->privateKey.data == NULL) {
        /* If SEC_ASN1DecodeItems succeeds but SECKEYPrivateKeyInfo.privateKey
         * is a zero-length octet string, free the arena and return a failure
         * to avoid trying to zero the corresponding SECItem in
         * SECKEY_DestroyPrivateKeyInfo(). */
        PORT_FreeArena(temparena, PR_TRUE);
        PORT_SetError(SEC_ERROR_BAD_KEY);
        return SECFailure;
    }

    rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
                                               publicValue, isPerm, isPrivate,
                                               keyUsage, privk, wincx);

    /* this zeroes the key and frees the arena */
    SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/);
    return rv;
}

SECStatus
PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
                               SECItem *nickname, SECItem *publicValue, PRBool isPerm,
                               PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey **privk,
                               void *wincx)
{
    CK_BBOOL cktrue = CK_TRUE;
    CK_BBOOL ckfalse = CK_FALSE;
    CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
    CK_KEY_TYPE keyType = CKK_RSA;
    CK_OBJECT_HANDLE objectID;
    CK_ATTRIBUTE theTemplate[20];
    int templateCount = 0;
    SECStatus rv = SECFailure;
    CK_ATTRIBUTE *attrs;
    CK_ATTRIBUTE *signedattr = NULL;
    int signedcount = 0;
    CK_ATTRIBUTE *ap;
    SECItem *ck_id = NULL;

    attrs = theTemplate;

    PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
    attrs++;
    PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
    attrs++;
    PK11_SETATTRS(attrs, CKA_TOKEN, isPerm ? &cktrue : &ckfalse,
                  sizeof(CK_BBOOL));
    attrs++;
    PK11_SETATTRS(attrs, CKA_SENSITIVE, isPrivate ? &cktrue : &ckfalse,
                  sizeof(CK_BBOOL));
    attrs++;
    PK11_SETATTRS(attrs, CKA_PRIVATE, isPrivate ? &cktrue : &ckfalse,
                  sizeof(CK_BBOOL));
    attrs++;

    switch (lpk->keyType) {
        case rsaKey:
            keyType = CKK_RSA;
            PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ? &cktrue : &ckfalse,
                          sizeof(CK_BBOOL));
            attrs++;
            PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ? &cktrue : &ckfalse,
                          sizeof(CK_BBOOL));
            attrs++;
            PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue : &ckfalse,
                          sizeof(CK_BBOOL));
            attrs++;
            PK11_SETATTRS(attrs, CKA_SIGN_RECOVER,
                          (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue
                                                            : &ckfalse,
                          sizeof(CK_BBOOL));
            attrs++;
            ck_id = PK11_MakeIDFromPubKey(&lpk->u.rsa.modulus);
            if (ck_id == NULL) {
                goto loser;
            }
            PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
            attrs++;
            if (nickname) {
                PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
                attrs++;
            }
            signedattr = attrs;
            PK11_SETATTRS(attrs, CKA_MODULUS, lpk->u.rsa.modulus.data,
                          lpk->u.rsa.modulus.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
                          lpk->u.rsa.publicExponent.data,
                          lpk->u.rsa.publicExponent.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_PRIVATE_EXPONENT,
                          lpk->u.rsa.privateExponent.data,
                          lpk->u.rsa.privateExponent.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_PRIME_1,
                          lpk->u.rsa.prime1.data,
                          lpk->u.rsa.prime1.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_PRIME_2,
                          lpk->u.rsa.prime2.data,
                          lpk->u.rsa.prime2.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_EXPONENT_1,
                          lpk->u.rsa.exponent1.data,
                          lpk->u.rsa.exponent1.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_EXPONENT_2,
                          lpk->u.rsa.exponent2.data,
                          lpk->u.rsa.exponent2.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_COEFFICIENT,
                          lpk->u.rsa.coefficient.data,
                          lpk->u.rsa.coefficient.len);
            attrs++;
            break;
        case dsaKey:
            keyType = CKK_DSA;
            /* To make our intenal PKCS #11 module work correctly with
             * our database, we need to pass in the public key value for
             * this dsa key. We have a netscape only CKA_ value to do this.
             * Only send it to internal slots */
            if (publicValue == NULL) {
                goto loser;
            }
            if (PK11_IsInternal(slot)) {
                PK11_SETATTRS(attrs, CKA_NSS_DB,
                              publicValue->data, publicValue->len);
                attrs++;
            }
            PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL));
            attrs++;
            PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &cktrue, sizeof(CK_BBOOL));
            attrs++;
            if (nickname) {
                PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
                attrs++;
            }
            ck_id = PK11_MakeIDFromPubKey(publicValue);
            if (ck_id == NULL) {
                goto loser;
            }
            PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
            attrs++;
            signedattr = attrs;
            PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dsa.params.prime.data,
                          lpk->u.dsa.params.prime.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_SUBPRIME, lpk->u.dsa.params.subPrime.data,
                          lpk->u.dsa.params.subPrime.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dsa.params.base.data,
                          lpk->u.dsa.params.base.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dsa.privateValue.data,
                          lpk->u.dsa.privateValue.len);
            attrs++;
            break;
        case dhKey:
            keyType = CKK_DH;
            /* To make our intenal PKCS #11 module work correctly with
             * our database, we need to pass in the public key value for
             * this dh key. We have a netscape only CKA_ value to do this.
             * Only send it to internal slots */
            if (PK11_IsInternal(slot)) {
                PK11_SETATTRS(attrs, CKA_NSS_DB,
                              publicValue->data, publicValue->len);
                attrs++;
            }
            PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));
            attrs++;
            if (nickname) {
                PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
                attrs++;
            }
            ck_id = PK11_MakeIDFromPubKey(publicValue);
            if (ck_id == NULL) {
                goto loser;
            }
            PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
            attrs++;
            signedattr = attrs;
            PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dh.prime.data,
                          lpk->u.dh.prime.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dh.base.data,
                          lpk->u.dh.base.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dh.privateValue.data,
                          lpk->u.dh.privateValue.len);
            attrs++;
            break;
        case ecKey:
            keyType = CKK_EC;
            if (lpk->u.ec.publicValue.len == 0) {
                goto loser;
            }
            if (PK11_IsInternal(slot)) {
                PK11_SETATTRS(attrs, CKA_NSS_DB,
                              lpk->u.ec.publicValue.data,
                              lpk->u.ec.publicValue.len);
                attrs++;
            }
            PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue : &ckfalse,
                          sizeof(CK_BBOOL));
            attrs++;
            PK11_SETATTRS(attrs, CKA_SIGN_RECOVER,
                          (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue
                                                            : &ckfalse,
                          sizeof(CK_BBOOL));
            attrs++;
            PK11_SETATTRS(attrs, CKA_DERIVE, (keyUsage & KU_KEY_AGREEMENT) ? &cktrue : &ckfalse,
                          sizeof(CK_BBOOL));
            attrs++;
            if (nickname) {
                PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
                attrs++;
            }
            ck_id = PK11_MakeIDFromPubKey(&lpk->u.ec.publicValue);
            if (ck_id == NULL) {
                goto loser;
            }
            PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
            attrs++;
            /* No signed attrs for EC */
            /* curveOID always is a copy of AlgorithmID.parameters. */
            PK11_SETATTRS(attrs, CKA_EC_PARAMS, lpk->u.ec.curveOID.data,
                          lpk->u.ec.curveOID.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.ec.privateValue.data,
                          lpk->u.ec.privateValue.len);
            attrs++;
            PK11_SETATTRS(attrs, CKA_EC_POINT, lpk->u.ec.publicValue.data,
                          lpk->u.ec.publicValue.len);
            attrs++;
            break;
        default:
            PORT_SetError(SEC_ERROR_BAD_KEY);
            goto loser;
    }
    templateCount = attrs - theTemplate;
    PORT_Assert(templateCount <= sizeof(theTemplate) / sizeof(CK_ATTRIBUTE));
    if (lpk->keyType != ecKey) {
        PORT_Assert(signedattr);
        signedcount = attrs - signedattr;
        for (ap = signedattr; signedcount; ap++, signedcount--) {
            pk11_SignedToUnsigned(ap);
        }
    }

    rv = PK11_CreateNewObject(slot, CK_INVALID_HANDLE,
                              theTemplate, templateCount, isPerm, &objectID);

    /* create and return a SECKEYPrivateKey */
    if (rv == SECSuccess && privk != NULL) {
        *privk = PK11_MakePrivKey(slot, lpk->keyType, !isPerm, objectID, wincx);
        if (*privk == NULL) {
            rv = SECFailure;
        }
    }
loser:
    if (ck_id) {
        SECITEM_ZfreeItem(ck_id, PR_TRUE);
    }
    return rv;
}

SECStatus
PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
                                      SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue,
                                      PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
                                      SECKEYPrivateKey **privk, void *wincx)
{
    SECStatus rv = SECFailure;
    SECKEYRawPrivateKey *lpk = NULL;
    const SEC_ASN1Template *keyTemplate, *paramTemplate;
    void *paramDest = NULL;
    PLArenaPool *arena = NULL;

    arena = PORT_NewArena(2048);
    if (!arena) {
        return SECFailure;
    }

    /* need to change this to use RSA/DSA keys */
    lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena,
                                                  sizeof(SECKEYRawPrivateKey));
    if (lpk == NULL) {
        goto loser;
    }
    lpk->arena = arena;

    switch (SECOID_GetAlgorithmTag(&pki->algorithm)) {
        case SEC_OID_PKCS1_RSA_ENCRYPTION:
            prepare_rsa_priv_key_export_for_asn1(lpk);
            keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
            paramTemplate = NULL;
            paramDest = NULL;
            lpk->keyType = rsaKey;
            break;
        case SEC_OID_ANSIX9_DSA_SIGNATURE:
            prepare_dsa_priv_key_export_for_asn1(lpk);
            keyTemplate = SECKEY_DSAPrivateKeyExportTemplate;
            paramTemplate = SECKEY_PQGParamsTemplate;
            paramDest = &(lpk->u.dsa.params);
            lpk->keyType = dsaKey;
            break;
        case SEC_OID_X942_DIFFIE_HELMAN_KEY:
            if (!publicValue) {
                goto loser;
            }
            prepare_dh_priv_key_export_for_asn1(lpk);
            keyTemplate = SECKEY_DHPrivateKeyExportTemplate;
            paramTemplate = NULL;
            paramDest = NULL;
            lpk->keyType = dhKey;
            break;
        case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
            prepare_ec_priv_key_export_for_asn1(lpk);
            keyTemplate = SECKEY_ECPrivateKeyExportTemplate;
            paramTemplate = NULL;
            paramDest = NULL;
            lpk->keyType = ecKey;
            break;

        default:
            keyTemplate = NULL;
            paramTemplate = NULL;
            paramDest = NULL;
            break;
    }

    if (!keyTemplate) {
        goto loser;
    }

    /* decode the private key and any algorithm parameters */
    rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
    if (rv != SECSuccess) {
        goto loser;
    }

    if (lpk->keyType == ecKey) {
        /* Convert length in bits to length in bytes. */
        lpk->u.ec.publicValue.len >>= 3;

        /* Always override curveOID, we're ignoring any given value. */
        rv = SECITEM_CopyItem(arena, &lpk->u.ec.curveOID,
                              &pki->algorithm.parameters);
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    if (paramDest && paramTemplate) {
        rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate,
                                &(pki->algorithm.parameters));
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    rv = PK11_ImportAndReturnPrivateKey(slot, lpk, nickname, publicValue, isPerm,
                                        isPrivate, keyUsage, privk, wincx);

loser:
    if (arena != NULL) {
        PORT_FreeArena(arena, PR_TRUE);
    }

    return rv;
}

SECStatus
PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, SECKEYPrivateKeyInfo *pki,
                          SECItem *nickname, SECItem *publicValue, PRBool isPerm,
                          PRBool isPrivate, unsigned int keyUsage, void *wincx)
{
    return PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
                                                 publicValue, isPerm, isPrivate, keyUsage, NULL, wincx);
}

SECItem *
PK11_ExportDERPrivateKeyInfo(SECKEYPrivateKey *pk, void *wincx)
{
    SECKEYPrivateKeyInfo *pki = PK11_ExportPrivKeyInfo(pk, wincx);
    SECItem *derPKI;

    if (!pki) {
        return NULL;
    }
    derPKI = SEC_ASN1EncodeItem(NULL, NULL, pki,
                                SECKEY_PrivateKeyInfoTemplate);
    SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE);
    return derPKI;
}

static PRBool
ReadAttribute(SECKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
              PLArenaPool *arena, SECItem *output)
{
    SECStatus rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, type,
                                      arena, output);
    return rv == SECSuccess;
}

/*
 * The caller is responsible for freeing the return value by passing it to
 * SECKEY_DestroyPrivateKeyInfo(..., PR_TRUE).
 */
SECKEYPrivateKeyInfo *
PK11_ExportPrivKeyInfo(SECKEYPrivateKey *pk, void *wincx)
{
    /* PrivateKeyInfo version (always zero) */
    const unsigned char pkiVersion = 0;
    /* RSAPrivateKey version (always zero) */
    const unsigned char rsaVersion = 0;
    /* ECPrivateKey version (always one) */
    const unsigned char ecVersion = 1;
    PLArenaPool *arena = NULL;
    SECKEYRawPrivateKey rawKey;
    SECKEYPrivateKeyInfo *pki;
    SECItem *encoded;
    const SEC_ASN1Template *keyTemplate;
    SECStatus rv;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        goto loser;
    }
    memset(&rawKey, 0, sizeof(rawKey));
    rawKey.keyType = pk->keyType;
    pki = PORT_ArenaZNew(arena, SECKEYPrivateKeyInfo);
    if (!pki) {
        goto loser;
    }

    switch (pk->keyType) {
        case rsaKey: {
            rawKey.u.rsa.version.type = siUnsignedInteger;
            rawKey.u.rsa.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
            if (!rawKey.u.rsa.version.data) {
                goto loser;
            }

            rawKey.u.rsa.version.data[0] = rsaVersion;
            rawKey.u.rsa.version.len = 1;

            /* Read the component attributes of the private key */
            prepare_rsa_priv_key_export_for_asn1(&rawKey);
            if (!ReadAttribute(pk, CKA_MODULUS, arena, &rawKey.u.rsa.modulus) ||
                !ReadAttribute(pk, CKA_PUBLIC_EXPONENT, arena,
                               &rawKey.u.rsa.publicExponent) ||
                !ReadAttribute(pk, CKA_PRIVATE_EXPONENT, arena,
                               &rawKey.u.rsa.privateExponent) ||
                !ReadAttribute(pk, CKA_PRIME_1, arena, &rawKey.u.rsa.prime1) ||
                !ReadAttribute(pk, CKA_PRIME_2, arena, &rawKey.u.rsa.prime2) ||
                !ReadAttribute(pk, CKA_EXPONENT_1, arena,
                               &rawKey.u.rsa.exponent1) ||
                !ReadAttribute(pk, CKA_EXPONENT_2, arena,
                               &rawKey.u.rsa.exponent2) ||
                !ReadAttribute(pk, CKA_COEFFICIENT, arena,
                               &rawKey.u.rsa.coefficient)) {
                goto loser;
            }

            keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;

            rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_PKCS1_RSA_ENCRYPTION, NULL);
            if (rv != SECSuccess) {
                goto loser;
            }

        } break;
        case ecKey: {
            rawKey.u.ec.version.type = siUnsignedInteger;
            rawKey.u.ec.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
            if (!rawKey.u.ec.version.data) {
                goto loser;
            }
            rawKey.u.ec.version.data[0] = ecVersion;
            rawKey.u.ec.version.len = 1;

            SECItem curveOID;
            /* Read the component attributes of the private key */
            prepare_ec_priv_key_export_for_asn1(&rawKey);
            if (!ReadAttribute(pk, CKA_VALUE, arena,
                               &rawKey.u.ec.privateValue) ||
                !ReadAttribute(pk, CKA_EC_PARAMS, arena, &curveOID)) {
                goto loser;
            }
            if (!ReadAttribute(pk, CKA_EC_POINT, arena,
                               &rawKey.u.ec.publicValue)) {
                SECKEYPublicKey *pubk = SECKEY_ConvertToPublicKey(pk);
                if (pubk == NULL)
                    goto loser;
                rv = SECITEM_CopyItem(arena, &rawKey.u.ec.publicValue, &pubk->u.ec.publicValue);
                SECKEY_DestroyPublicKey(pubk);
                if (rv != SECSuccess) {
                    goto loser;
                }
            }

            keyTemplate = SECKEY_ECPrivateKeyExportTemplate;
            /* Convert length in bytes to length in bits. */
            rawKey.u.ec.publicValue.len <<= 3;

            rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_ANSIX962_EC_PUBLIC_KEY, &curveOID);
            if (rv != SECSuccess) {
                goto loser;
            }

        } break;
        default: {
            PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
            goto loser;
        }
    }

    encoded = SEC_ASN1EncodeItem(arena, &pki->privateKey, &rawKey, keyTemplate);
    if (!encoded) {
        goto loser;
    }
    pki->version.type = siUnsignedInteger;
    pki->version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
    if (!pki->version.data) {
        goto loser;
    }
    pki->version.data[0] = pkiVersion;
    pki->version.len = 1;
    pki->arena = arena;

    return pki;

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