47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll/*
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * The Initial Developer of the Original Code is International
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Business Machines Corporation. Portions created by IBM
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Corporation are Copyright (C) 2005 International Business
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Machines Corporation. All Rights Reserved.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll *
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * This program is free software; you can redistribute it and/or modify
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * it under the terms of the Common Public License as published by
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * IBM Corporation; either version 1 of the License, or (at your option)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * any later version.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll *
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * This program is distributed in the hope that it will be useful,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * but WITHOUT ANY WARRANTY; without even the implied warranty of
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Common Public License for more details.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll *
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * You should have received a copy of the Common Public License
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * along with this program; if not, a copy can be viewed at
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * http://www.opensource.org/licenses/cpl1.0.php.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll */
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll/* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll/*
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Use is subject to license terms.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll */
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll#include "tpmtok_int.h"
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersollstatic CK_BBOOL true = TRUE, false = FALSE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersollstatic CK_RV
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersollkey_mgr_get_private_key_type(
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BYTE *keydata,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG keylen,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_KEY_TYPE *keytype)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll{
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BYTE *alg = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BYTE *priv_key = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG alg_len;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_RV rc;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = ber_decode_PrivateKeyInfo(keydata, keylen, &alg,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll &alg_len, &priv_key);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (rc);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (alg_len >= ber_rsaEncryptionLen) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (memcmp(alg, ber_rsaEncryption,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ber_rsaEncryptionLen) == 0) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll *keytype = CKK_RSA;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_OK);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_TEMPLATE_INCOMPLETE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll}
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys IngersollCK_RV
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersollkey_mgr_generate_key_pair(SESSION * sess,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_MECHANISM * mech,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ATTRIBUTE * publ_tmpl,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG publ_count,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ATTRIBUTE * priv_tmpl,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG priv_count,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_OBJECT_HANDLE * publ_key_handle,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_OBJECT_HANDLE * priv_key_handle)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll{
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll OBJECT * publ_key_obj = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll OBJECT * priv_key_obj = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ATTRIBUTE * attr = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ATTRIBUTE * new_attr = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG i, keyclass, subclass = 0;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BBOOL flag;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_RV rc;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! sess || ! mech || ! publ_key_handle || ! priv_key_handle) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! publ_tmpl && (publ_count != 0)) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! priv_tmpl && (priv_count != 0)) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll for (i = 0; i < publ_count; i++) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (publ_tmpl[i].type == CKA_CLASS) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll keyclass = *(CK_OBJECT_CLASS *)publ_tmpl[i].pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (keyclass != CKO_PUBLIC_KEY) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (publ_tmpl[i].type == CKA_KEY_TYPE)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll subclass = *(CK_ULONG *)publ_tmpl[i].pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll for (i = 0; i < priv_count; i++) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (priv_tmpl[i].type == CKA_CLASS) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll keyclass = *(CK_OBJECT_CLASS *)priv_tmpl[i].pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (keyclass != CKO_PRIVATE_KEY) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (priv_tmpl[i].type == CKA_KEY_TYPE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG temp = *(CK_ULONG *)priv_tmpl[i].pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (temp != subclass) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll switch (mech->mechanism) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKM_RSA_PKCS_KEY_PAIR_GEN:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (subclass != 0 && subclass != CKK_RSA) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll subclass = CKK_RSA;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll default:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_MECHANISM_INVALID);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = object_mgr_create_skel(sess,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll publ_tmpl, publ_count, MODE_KEYGEN,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CKO_PUBLIC_KEY, subclass, &publ_key_obj);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = object_mgr_create_skel(sess,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll priv_tmpl, priv_count, MODE_KEYGEN,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CKO_PRIVATE_KEY, subclass, &priv_key_obj);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll switch (mech->mechanism) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKM_RSA_PKCS_KEY_PAIR_GEN:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = ckm_rsa_key_pair_gen(
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll sess->hContext,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll publ_key_obj->template,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll priv_key_obj->template);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll default:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = CKR_MECHANISM_INVALID;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll /*
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * we can now set CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * to their appropriate values. this only applies to CKO_SECRET_KEY
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * and CKO_PRIVATE_KEY objects
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll */
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll flag = template_attribute_find(priv_key_obj->template,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CKA_SENSITIVE, &attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (flag == TRUE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll flag = *(CK_BBOOL *)attr->pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = build_attribute(CKA_ALWAYS_SENSITIVE, &flag,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll sizeof (CK_BBOOL), &new_attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll (void) template_update_attribute(priv_key_obj->template,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll new_attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll } else {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = CKR_FUNCTION_FAILED;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll flag = template_attribute_find(priv_key_obj->template,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CKA_EXTRACTABLE, &attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (flag == TRUE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll flag = *(CK_BBOOL *)attr->pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = build_attribute(CKA_NEVER_EXTRACTABLE, &true,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll sizeof (CK_BBOOL), &new_attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (flag == TRUE)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll *(CK_BBOOL *)new_attr->pValue = false;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll (void) template_update_attribute(priv_key_obj->template,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll new_attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll } else {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = CKR_FUNCTION_FAILED;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = object_mgr_create_final(sess, publ_key_obj, publ_key_handle);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = object_mgr_create_final(sess, priv_key_obj, priv_key_handle);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll (void) object_mgr_destroy_object(sess, *publ_key_handle);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll publ_key_obj = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (rc);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersollerror:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (publ_key_obj)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll (void) object_free(publ_key_obj);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (priv_key_obj)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll (void) object_free(priv_key_obj);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll *publ_key_handle = 0;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll *priv_key_handle = 0;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (rc);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll}
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys IngersollCK_RV
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersollkey_mgr_wrap_key(SESSION * sess,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BBOOL length_only,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_MECHANISM * mech,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_OBJECT_HANDLE h_wrapping_key,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_OBJECT_HANDLE h_key,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BYTE * wrapped_key,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG * wrapped_key_len) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ENCR_DECR_CONTEXT * ctx = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll OBJECT * key1_obj = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll OBJECT * key2_obj = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ATTRIBUTE * attr = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BYTE * data = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG data_len;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_OBJECT_CLASS class;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_KEY_TYPE keytype;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BBOOL flag;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_RV rc;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! sess || ! wrapped_key_len) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = object_mgr_find_in_map1(sess->hContext, h_wrapping_key, &key1_obj);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_WRAPPING_KEY_HANDLE_INVALID);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = object_mgr_find_in_map1(sess->hContext, h_key, &key2_obj);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_HANDLE_INVALID);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = template_attribute_find(key2_obj->template,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CKA_EXTRACTABLE, &attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc == FALSE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_NOT_WRAPPABLE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll } else {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll flag = *(CK_BBOOL *)attr->pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (flag == FALSE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_NOT_WRAPPABLE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = template_attribute_find(key2_obj->template, CKA_CLASS, &attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc == FALSE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_NOT_WRAPPABLE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll } else
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll class = *(CK_OBJECT_CLASS *)attr->pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll switch (mech->mechanism) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKM_RSA_PKCS:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (class != CKO_SECRET_KEY) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_NOT_WRAPPABLE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll default:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_NOT_WRAPPABLE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = template_attribute_find(key2_obj->template,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CKA_KEY_TYPE, &attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc == FALSE)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_NOT_WRAPPABLE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll else
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll keytype = *(CK_KEY_TYPE *)attr->pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll switch (keytype) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKK_RSA:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = rsa_priv_wrap_get_data(key2_obj->template, length_only,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll &data, &data_len);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (rc);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKK_GENERIC_SECRET:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = generic_secret_wrap_get_data(key2_obj->template,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll length_only, &data, &data_len);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (rc);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll default:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_NOT_WRAPPABLE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll switch (mech->mechanism) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKM_RSA_PKCS:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll default:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_NOT_WRAPPABLE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx = (ENCR_DECR_CONTEXT *)malloc(sizeof (ENCR_DECR_CONTEXT));
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! ctx) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_HOST_MEMORY);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll (void) memset(ctx, 0x0, sizeof (ENCR_DECR_CONTEXT));
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = encr_mgr_init(sess, ctx, OP_WRAP, mech, h_wrapping_key);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (rc);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = encr_mgr_encrypt(sess, length_only,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx, data, data_len, wrapped_key, wrapped_key_len);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (data != NULL) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll free(data);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll (void) encr_mgr_cleanup(ctx);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll free(ctx);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (rc);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll}
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys IngersollCK_RV
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersollkey_mgr_unwrap_key(SESSION * sess,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_MECHANISM * mech,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ATTRIBUTE * attributes,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG attrib_count,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BYTE * wrapped_key,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG wrapped_key_len,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_OBJECT_HANDLE h_unwrapping_key,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_OBJECT_HANDLE * h_unwrapped_key)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll{
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ENCR_DECR_CONTEXT * ctx = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll OBJECT * key_obj = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BYTE * data = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG data_len;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG keyclass, keytype;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG i;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BBOOL found_class, found_type, fromend;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_RV rc;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! sess || ! wrapped_key || ! h_unwrapped_key) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = object_mgr_find_in_map1(sess->hContext, h_unwrapping_key,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll &key_obj);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_WRAPPING_KEY_HANDLE_INVALID);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll found_class = FALSE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll found_type = FALSE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll switch (mech->mechanism) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKM_RSA_PKCS:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll keyclass = CKO_SECRET_KEY;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll found_class = TRUE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll for (i = 0; i < attrib_count; i++) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll switch (attributes[i].type) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKA_CLASS:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll keyclass = *(CK_OBJECT_CLASS *)attributes[i].pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll found_class = TRUE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKA_KEY_TYPE:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll keytype = *(CK_KEY_TYPE *)attributes[i].pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll found_type = TRUE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (found_class == FALSE || (found_type == FALSE && keyclass !=
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CKO_PRIVATE_KEY)) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_TEMPLATE_INCOMPLETE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll switch (mech->mechanism) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKM_RSA_PKCS:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (keyclass != CKO_SECRET_KEY) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll default:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_MECHANISM_INVALID);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx = (ENCR_DECR_CONTEXT *)malloc(sizeof (ENCR_DECR_CONTEXT));
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! ctx) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_HOST_MEMORY);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll (void) memset(ctx, 0x0, sizeof (ENCR_DECR_CONTEXT));
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = decr_mgr_init(sess, ctx, OP_UNWRAP, mech, h_unwrapping_key);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (rc);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = decr_mgr_decrypt(sess,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll TRUE, ctx, wrapped_key, wrapped_key_len,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll data, &data_len);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll data = (CK_BYTE *)malloc(data_len);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! data) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = CKR_HOST_MEMORY;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = decr_mgr_decrypt(sess,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll FALSE, ctx, wrapped_key, wrapped_key_len,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll data, &data_len);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll (void) decr_mgr_cleanup(ctx);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll free(ctx);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll /*
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * if we use X.509, the data will be padded from the front with zeros.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * PKCS #11 specifies that for this mechanism, CK_VALUE is to be read
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * from the end of the data.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll *
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Note: the PKCS #11 reference implementation gets this wrong.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll */
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (mech->mechanism == CKM_RSA_X_509)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll fromend = TRUE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll else
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll fromend = FALSE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (keyclass == CKO_PRIVATE_KEY) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = key_mgr_get_private_key_type(data, data_len, &keytype);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = object_mgr_create_skel(sess,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll attributes, attrib_count,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll MODE_UNWRAP, keyclass, keytype,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll &key_obj);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll switch (keyclass) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKO_SECRET_KEY:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = secret_key_unwrap(key_obj->template, keytype, data,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll data_len, fromend);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKO_PRIVATE_KEY:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = priv_key_unwrap(key_obj->template, keytype,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll data, data_len);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll default:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = CKR_WRAPPED_KEY_INVALID;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = object_mgr_create_final(sess, key_obj, h_unwrapped_key);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll goto error;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (data) free(data);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (rc);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersollerror:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (key_obj) (void) object_free(key_obj);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (data) free(data);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (rc);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll}