|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* COPYRIGHT (c) International Business Machines Corp. 2001-2017
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* This program is provided under the terms of the Common Public License,
|
|
Packit |
8681c6 |
* version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
|
|
Packit |
8681c6 |
* software constitutes recipient's acceptance of CPL-1.0 terms which can be
|
|
Packit |
8681c6 |
* found in the file LICENSE file or at
|
|
Packit |
8681c6 |
* https://opensource.org/licenses/cpl1.0.php
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/***************************************************************************
|
|
Packit |
8681c6 |
Change Log
|
|
Packit |
8681c6 |
==========
|
|
Packit |
8681c6 |
4/25/03 Kapil Sood (kapil@corrent.com)
|
|
Packit |
8681c6 |
Added DH key pair generation and DH shared key derivation
|
|
Packit |
8681c6 |
functions.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
****************************************************************************/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// File: key_mgr.c
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include <pthread.h>
|
|
Packit |
8681c6 |
#include <stdlib.h>
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include <string.h> // for memcmp() et al
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include "pkcs11types.h"
|
|
Packit |
8681c6 |
#include "defs.h"
|
|
Packit |
8681c6 |
#include "host_defs.h"
|
|
Packit |
8681c6 |
#include "h_extern.h"
|
|
Packit |
8681c6 |
#include "tok_spec_struct.h"
|
|
Packit |
8681c6 |
#include "trace.h"
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include <openssl/crypto.h>
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
static CK_BBOOL true = TRUE, false = FALSE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV key_mgr_generate_key(STDLL_TokData_t *tokdata,
|
|
Packit |
8681c6 |
SESSION *sess,
|
|
Packit |
8681c6 |
CK_MECHANISM *mech,
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *pTemplate,
|
|
Packit |
8681c6 |
CK_ULONG ulCount, CK_OBJECT_HANDLE *handle)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
OBJECT *key_obj = NULL;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *new_attr = NULL;
|
|
Packit |
8681c6 |
CK_ULONG i, keyclass, subclass = 0;
|
|
Packit |
8681c6 |
CK_BBOOL flag;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!sess || !mech || !handle) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (!pTemplate && (ulCount != 0)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// it's silly but Cryptoki allows the user to specify the CKA_CLASS
|
|
Packit |
8681c6 |
// in the template. so we have to iterate through the provided template
|
|
Packit |
8681c6 |
// and make sure that if CKA_CLASS is CKO_SECRET_KEY, if it is present.
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// it would have been more logical for Cryptoki to forbid specifying
|
|
Packit |
8681c6 |
// the CKA_CLASS attribute when generating a key
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
for (i = 0; i < ulCount; i++) {
|
|
Packit |
8681c6 |
if (pTemplate[i].type == CKA_CLASS) {
|
|
Packit |
8681c6 |
keyclass = *(CK_OBJECT_CLASS *) pTemplate[i].pValue;
|
|
Packit |
8681c6 |
if (keyclass != CKO_SECRET_KEY) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (pTemplate[i].type == CKA_KEY_TYPE)
|
|
Packit |
8681c6 |
subclass = *(CK_ULONG *) pTemplate[i].pValue;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
switch (mech->mechanism) {
|
|
Packit |
8681c6 |
case CKM_DES_KEY_GEN:
|
|
Packit |
8681c6 |
if (subclass != 0 && subclass != CKK_DES) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
subclass = CKK_DES;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_DES3_KEY_GEN:
|
|
Packit |
8681c6 |
if (subclass != 0 && subclass != CKK_DES3) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
subclass = CKK_DES3;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#if !(NOCDMF)
|
|
Packit |
8681c6 |
case CKM_CDMF_KEY_GEN:
|
|
Packit |
8681c6 |
if (subclass != 0 && subclass != CKK_CDMF) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
subclass = CKK_CDMF;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
case CKM_SSL3_PRE_MASTER_KEY_GEN:
|
|
Packit |
8681c6 |
if (subclass != 0 && subclass != CKK_GENERIC_SECRET) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (mech->ulParameterLen != sizeof(CK_VERSION)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_PARAM_INVALID));
|
|
Packit |
8681c6 |
return CKR_MECHANISM_PARAM_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
subclass = CKK_GENERIC_SECRET;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_AES_KEY_GEN:
|
|
Packit |
8681c6 |
if (subclass != 0 && subclass != CKK_AES) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
subclass = CKK_AES;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_GENERIC_SECRET_KEY_GEN:
|
|
Packit |
8681c6 |
if (subclass != 0 && subclass != CKK_GENERIC_SECRET) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
subclass = CKK_GENERIC_SECRET;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
|
|
Packit |
8681c6 |
return CKR_MECHANISM_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_create_skel(tokdata, sess,
|
|
Packit |
8681c6 |
pTemplate, ulCount,
|
|
Packit |
8681c6 |
MODE_KEYGEN,
|
|
Packit |
8681c6 |
CKO_SECRET_KEY, subclass, &key_obj);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_create_skel failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// at this point, 'key_obj' should contain a skeleton key. depending on
|
|
Packit |
8681c6 |
// the key type, we may need to extract one or more attributes from
|
|
Packit |
8681c6 |
// the object prior to generating the key data (ie. variable key length)
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
switch (mech->mechanism) {
|
|
Packit |
8681c6 |
case CKM_DES_KEY_GEN:
|
|
Packit |
8681c6 |
rc = ckm_des_key_gen(tokdata, key_obj->template);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_DES3_KEY_GEN:
|
|
Packit |
8681c6 |
rc = ckm_des3_key_gen(tokdata, key_obj->template);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#if !(NOCDMF)
|
|
Packit |
8681c6 |
case CKM_CDMF_KEY_GEN:
|
|
Packit |
8681c6 |
rc = ckm_cdmf_key_gen(tokdata, key_obj->template);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
case CKM_SSL3_PRE_MASTER_KEY_GEN:
|
|
Packit |
8681c6 |
rc = ckm_ssl3_pre_master_key_gen(tokdata, key_obj->template, mech);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#ifndef NOAES
|
|
Packit |
8681c6 |
case CKM_AES_KEY_GEN:
|
|
Packit |
8681c6 |
rc = ckm_aes_key_gen(tokdata, key_obj->template);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
case CKM_GENERIC_SECRET_KEY_GEN:
|
|
Packit |
8681c6 |
rc = ckm_generic_secret_key_gen(tokdata, key_obj->template);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
|
|
Packit |
8681c6 |
rc = CKR_MECHANISM_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Key generation failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// we can now set CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE
|
|
Packit |
8681c6 |
// to their appropriate values. this only applies to CKO_SECRET_KEY
|
|
Packit |
8681c6 |
// and CKO_PRIVATE_KEY objects
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
flag = template_attribute_find(key_obj->template, CKA_SENSITIVE, &attr);
|
|
Packit |
8681c6 |
if (flag == TRUE) {
|
|
Packit |
8681c6 |
flag = *(CK_BBOOL *) attr->pValue;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_ALWAYS_SENSITIVE, &flag, sizeof(CK_BBOOL),
|
|
Packit |
8681c6 |
&new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build attribute failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to find CKA_SENSITIVE in key object template.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
flag = template_attribute_find(key_obj->template, CKA_EXTRACTABLE, &attr);
|
|
Packit |
8681c6 |
if (flag == TRUE) {
|
|
Packit |
8681c6 |
flag = *(CK_BBOOL *) attr->pValue;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_NEVER_EXTRACTABLE, &true, sizeof(CK_BBOOL),
|
|
Packit |
8681c6 |
&new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (flag == TRUE)
|
|
Packit |
8681c6 |
*(CK_BBOOL *) new_attr->pValue = FALSE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
template_update_attribute(key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to find CKA_EXTRACTABLE in key object template.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* add/update CKA_LOCAL with value true to the template */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_LOCAL, &true, sizeof(CK_BBOOL), &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// at this point, the key should be fully constructed...assign
|
|
Packit |
8681c6 |
// an object handle and store the key
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
rc = object_mgr_create_final(tokdata, sess, key_obj, handle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_create_final failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
error:
|
|
Packit |
8681c6 |
if (key_obj)
|
|
Packit |
8681c6 |
object_free(key_obj);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
*handle = 0;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV key_mgr_generate_key_pair(STDLL_TokData_t *tokdata,
|
|
Packit |
8681c6 |
SESSION *sess,
|
|
Packit |
8681c6 |
CK_MECHANISM *mech,
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *publ_tmpl,
|
|
Packit |
8681c6 |
CK_ULONG publ_count,
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *priv_tmpl,
|
|
Packit |
8681c6 |
CK_ULONG priv_count,
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE *publ_key_handle,
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE *priv_key_handle)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
OBJECT *publ_key_obj = NULL;
|
|
Packit |
8681c6 |
OBJECT *priv_key_obj = NULL;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *new_attr = NULL;
|
|
Packit |
8681c6 |
CK_ULONG i, keyclass, subclass = 0;
|
|
Packit |
8681c6 |
CK_BBOOL flag;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!sess || !mech || !publ_key_handle || !priv_key_handle) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (!publ_tmpl && (publ_count != 0)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (!priv_tmpl && (priv_count != 0)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// it's silly but Cryptoki allows the user to specify the CKA_CLASS
|
|
Packit |
8681c6 |
// in the template. so we have to iterate through the provided template
|
|
Packit |
8681c6 |
// and make sure that if CKA_CLASS is valid, if it is present.
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// it would have been more logical for Cryptoki to forbid specifying
|
|
Packit |
8681c6 |
// the CKA_CLASS attribute when generating a key
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
for (i = 0; i < publ_count; i++) {
|
|
Packit |
8681c6 |
if (publ_tmpl[i].type == CKA_CLASS) {
|
|
Packit |
8681c6 |
keyclass = *(CK_OBJECT_CLASS *) publ_tmpl[i].pValue;
|
|
Packit |
8681c6 |
if (keyclass != CKO_PUBLIC_KEY) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (publ_tmpl[i].type == CKA_KEY_TYPE)
|
|
Packit |
8681c6 |
subclass = *(CK_ULONG *) publ_tmpl[i].pValue;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
for (i = 0; i < priv_count; i++) {
|
|
Packit |
8681c6 |
if (priv_tmpl[i].type == CKA_CLASS) {
|
|
Packit |
8681c6 |
keyclass = *(CK_OBJECT_CLASS *) priv_tmpl[i].pValue;
|
|
Packit |
8681c6 |
if (keyclass != CKO_PRIVATE_KEY) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (priv_tmpl[i].type == CKA_KEY_TYPE) {
|
|
Packit |
8681c6 |
CK_ULONG temp = *(CK_ULONG *) priv_tmpl[i].pValue;
|
|
Packit |
8681c6 |
if (temp != subclass) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
switch (mech->mechanism) {
|
|
Packit |
8681c6 |
case CKM_RSA_PKCS_KEY_PAIR_GEN:
|
|
Packit |
8681c6 |
if (subclass != 0 && subclass != CKK_RSA) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
subclass = CKK_RSA;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_EC_KEY_PAIR_GEN:
|
|
Packit |
8681c6 |
if (subclass != 0 && subclass != CKK_EC) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
subclass = CKK_EC;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#if !(NODSA)
|
|
Packit |
8681c6 |
case CKM_DSA_KEY_PAIR_GEN:
|
|
Packit |
8681c6 |
if (subclass != 0 && subclass != CKK_DSA) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
subclass = CKK_DSA;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
/* Begin code contributed by Corrent corp. */
|
|
Packit |
8681c6 |
#if !(NODH)
|
|
Packit |
8681c6 |
case CKM_DH_PKCS_KEY_PAIR_GEN:
|
|
Packit |
8681c6 |
if (subclass != 0 && subclass != CKK_DH) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
subclass = CKK_DH;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
/* End code contributed by Corrent corp. */
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
|
|
Packit |
8681c6 |
return CKR_MECHANISM_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_create_skel(tokdata, sess,
|
|
Packit |
8681c6 |
publ_tmpl, publ_count,
|
|
Packit |
8681c6 |
MODE_KEYGEN,
|
|
Packit |
8681c6 |
CKO_PUBLIC_KEY, subclass, &publ_key_obj);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_create_skel failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
rc = object_mgr_create_skel(tokdata, sess,
|
|
Packit |
8681c6 |
priv_tmpl, priv_count,
|
|
Packit |
8681c6 |
MODE_KEYGEN,
|
|
Packit |
8681c6 |
CKO_PRIVATE_KEY, subclass, &priv_key_obj);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_create_skel failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// at this point, 'key_obj' should contain a skeleton key. depending on
|
|
Packit |
8681c6 |
// the key type, we may need to extract one or more attributes from
|
|
Packit |
8681c6 |
// the object prior to generating the key data (ie. variable key length)
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
switch (mech->mechanism) {
|
|
Packit |
8681c6 |
case CKM_RSA_PKCS_KEY_PAIR_GEN:
|
|
Packit |
8681c6 |
rc = ckm_rsa_key_pair_gen(tokdata, publ_key_obj->template,
|
|
Packit |
8681c6 |
priv_key_obj->template);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_EC_KEY_PAIR_GEN:
|
|
Packit |
8681c6 |
rc = ckm_ec_key_pair_gen(tokdata, publ_key_obj->template,
|
|
Packit |
8681c6 |
priv_key_obj->template);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#if !(NODSA)
|
|
Packit |
8681c6 |
case CKM_DSA_KEY_PAIR_GEN:
|
|
Packit |
8681c6 |
rc = ckm_dsa_key_pair_gen(tokdata, publ_key_obj->template,
|
|
Packit |
8681c6 |
priv_key_obj->template);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Begin code contributed by Corrent corp. */
|
|
Packit |
8681c6 |
#if !(NODH)
|
|
Packit |
8681c6 |
case CKM_DH_PKCS_KEY_PAIR_GEN:
|
|
Packit |
8681c6 |
rc = ckm_dh_pkcs_key_pair_gen(tokdata, publ_key_obj->template,
|
|
Packit |
8681c6 |
priv_key_obj->template);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
/* End code contributed by Corrent corp. */
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
|
|
Packit |
8681c6 |
rc = CKR_MECHANISM_INVALID;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("Key Generation failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// we can now set CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE
|
|
Packit |
8681c6 |
// to their appropriate values. this only applies to CKO_SECRET_KEY
|
|
Packit |
8681c6 |
// and CKO_PRIVATE_KEY objects
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
flag =
|
|
Packit |
8681c6 |
template_attribute_find(priv_key_obj->template, CKA_SENSITIVE, &attr);
|
|
Packit |
8681c6 |
if (flag == TRUE) {
|
|
Packit |
8681c6 |
flag = *(CK_BBOOL *) attr->pValue;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_ALWAYS_SENSITIVE, &flag, sizeof(CK_BBOOL),
|
|
Packit |
8681c6 |
&new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to find CKA_SENSITIVE in key object template.\n");
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
flag =
|
|
Packit |
8681c6 |
template_attribute_find(priv_key_obj->template, CKA_EXTRACTABLE, &attr);
|
|
Packit |
8681c6 |
if (flag == TRUE) {
|
|
Packit |
8681c6 |
flag = *(CK_BBOOL *) attr->pValue;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_NEVER_EXTRACTABLE, &true, sizeof(CK_BBOOL),
|
|
Packit |
8681c6 |
&new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (flag == TRUE)
|
|
Packit |
8681c6 |
*(CK_BBOOL *) new_attr->pValue = false;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
template_update_attribute(priv_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to find CKA_EXTRACTABLE in key object template.\n");
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* add/update CKA_LOCAL with value true to the keypair templates */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_LOCAL, &true, sizeof(CK_BBOOL), &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(publ_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_LOCAL, &true, sizeof(CK_BBOOL), &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// at this point, the keys should be fully constructed...assign
|
|
Packit |
8681c6 |
// object handles and store the keys
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
rc = object_mgr_create_final(tokdata, sess, publ_key_obj, publ_key_handle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_create_final failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
rc = object_mgr_create_final(tokdata, sess, priv_key_obj, priv_key_handle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_create_final failed.\n");
|
|
Packit |
8681c6 |
object_mgr_destroy_object(tokdata, sess, *publ_key_handle);
|
|
Packit |
8681c6 |
publ_key_obj = NULL;
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
error:
|
|
Packit |
8681c6 |
if (publ_key_obj)
|
|
Packit |
8681c6 |
object_free(publ_key_obj);
|
|
Packit |
8681c6 |
if (priv_key_obj)
|
|
Packit |
8681c6 |
object_free(priv_key_obj);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
*publ_key_handle = 0;
|
|
Packit |
8681c6 |
*priv_key_handle = 0;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV key_mgr_wrap_key(STDLL_TokData_t *tokdata,
|
|
Packit |
8681c6 |
SESSION *sess,
|
|
Packit |
8681c6 |
CK_BBOOL length_only,
|
|
Packit |
8681c6 |
CK_MECHANISM *mech,
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE h_wrapping_key,
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE h_key,
|
|
Packit |
8681c6 |
CK_BYTE *wrapped_key, CK_ULONG *wrapped_key_len)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
ENCR_DECR_CONTEXT *ctx = NULL;
|
|
Packit |
8681c6 |
OBJECT *key1_obj = NULL;
|
|
Packit |
8681c6 |
OBJECT *key2_obj = NULL;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
CK_BYTE *data = NULL;
|
|
Packit |
8681c6 |
CK_ULONG data_len;
|
|
Packit |
8681c6 |
CK_OBJECT_CLASS class;
|
|
Packit |
8681c6 |
CK_KEY_TYPE keytype;
|
|
Packit |
8681c6 |
CK_BBOOL flag;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!sess || !wrapped_key_len) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_find_in_map1(tokdata, h_wrapping_key, &key1_obj, READ_LOCK);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_WRAPPING_KEY_HANDLE_INVALID));
|
|
Packit |
8681c6 |
if (rc == CKR_OBJECT_HANDLE_INVALID)
|
|
Packit |
8681c6 |
return CKR_WRAPPING_KEY_HANDLE_INVALID;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
object_put(tokdata, key1_obj, TRUE);
|
|
Packit |
8681c6 |
key1_obj = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_find_in_map1(tokdata, h_key, &key2_obj, READ_LOCK);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to acquire key from specified handle");
|
|
Packit |
8681c6 |
if (rc == CKR_OBJECT_HANDLE_INVALID)
|
|
Packit |
8681c6 |
return CKR_KEY_HANDLE_INVALID;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// is the key-to-be-wrapped EXTRACTABLE?
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
rc = template_attribute_find(key2_obj->template, CKA_EXTRACTABLE, &attr);
|
|
Packit |
8681c6 |
if (rc == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to find CKA_EXTRACTABLE in key template.\n");
|
|
Packit |
8681c6 |
// could happen if user tries to wrap a public key
|
|
Packit |
8681c6 |
rc = CKR_KEY_NOT_WRAPPABLE;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
flag = *(CK_BBOOL *) attr->pValue;
|
|
Packit |
8681c6 |
if (flag == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_KEY_UNEXTRACTABLE));
|
|
Packit |
8681c6 |
rc = CKR_KEY_UNEXTRACTABLE;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// what kind of key are we trying to wrap? make sure the mechanism is
|
|
Packit |
8681c6 |
// allowed to wrap this kind of key
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
rc = template_attribute_find(key2_obj->template, CKA_CLASS, &attr);
|
|
Packit |
8681c6 |
if (rc == FALSE) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("CKA_CLASS is missing for key to be wrapped.\n");
|
|
Packit |
8681c6 |
rc = CKR_KEY_NOT_WRAPPABLE;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
class = *(CK_OBJECT_CLASS *) attr->pValue;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// pkcs11v2-20rc3, page 178
|
|
Packit |
8681c6 |
// C_WrapKey can be used in following situations:
|
|
Packit |
8681c6 |
// - To wrap any secret key with a public key that supports encryption
|
|
Packit |
8681c6 |
// and decryption.
|
|
Packit |
8681c6 |
// - To wrap any secret key with any other secret key. Consideration
|
|
Packit |
8681c6 |
// must be given to key size and mechanism strength or the token may
|
|
Packit |
8681c6 |
// not allow the operation.
|
|
Packit |
8681c6 |
// - To wrap a private key with any secret key.
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// These can be deduced to:
|
|
Packit |
8681c6 |
// A public key or a secret key can be used to wrap a secret key.
|
|
Packit |
8681c6 |
// A secret key can be used to wrap a private key.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
switch (mech->mechanism) {
|
|
Packit |
8681c6 |
#if !(NOCDMF)
|
|
Packit |
8681c6 |
case CKM_CDMF_CBC:
|
|
Packit |
8681c6 |
case CKM_CDMF_CBC_PAD:
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
case CKM_DES_CBC:
|
|
Packit |
8681c6 |
case CKM_DES3_ECB:
|
|
Packit |
8681c6 |
case CKM_DES3_CBC:
|
|
Packit |
8681c6 |
case CKM_AES_CTR:
|
|
Packit |
8681c6 |
case CKM_DES_CBC_PAD:
|
|
Packit |
8681c6 |
case CKM_DES3_CBC_PAD:
|
|
Packit |
8681c6 |
case CKM_AES_CBC_PAD:
|
|
Packit |
8681c6 |
case CKM_AES_OFB:
|
|
Packit |
8681c6 |
case CKM_AES_CFB8:
|
|
Packit |
8681c6 |
case CKM_AES_CFB64:
|
|
Packit |
8681c6 |
case CKM_AES_CFB128:
|
|
Packit |
8681c6 |
if ((class != CKO_SECRET_KEY) && (class != CKO_PRIVATE_KEY)) {
|
|
Packit |
8681c6 |
TRACE_ERROR
|
|
Packit |
8681c6 |
("Specified mechanism only wraps secret & private keys.\n");
|
|
Packit |
8681c6 |
rc = CKR_KEY_NOT_WRAPPABLE;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_CDMF_ECB:
|
|
Packit |
8681c6 |
case CKM_DES_ECB:
|
|
Packit |
8681c6 |
case CKM_AES_ECB:
|
|
Packit |
8681c6 |
case CKM_AES_CBC:
|
|
Packit |
8681c6 |
case CKM_RSA_PKCS_OAEP:
|
|
Packit |
8681c6 |
case CKM_RSA_PKCS:
|
|
Packit |
8681c6 |
case CKM_RSA_X_509:
|
|
Packit |
8681c6 |
if (class != CKO_SECRET_KEY) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Specified mechanism only wraps secret keys.\n");
|
|
Packit |
8681c6 |
rc = CKR_KEY_NOT_WRAPPABLE;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
TRACE_ERROR("The mechanism does not support wrapping keys.\n");
|
|
Packit |
8681c6 |
rc = CKR_MECHANISM_INVALID;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// extract the secret data to be wrapped
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
rc = template_attribute_find(key2_obj->template, CKA_KEY_TYPE, &attr);
|
|
Packit |
8681c6 |
if (rc == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to find CKA_KEY_TYPE in key template.\n");
|
|
Packit |
8681c6 |
rc = CKR_KEY_NOT_WRAPPABLE;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
keytype = *(CK_KEY_TYPE *) attr->pValue;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
switch (keytype) {
|
|
Packit |
8681c6 |
#if !(NOCDMF)
|
|
Packit |
8681c6 |
case CKK_CDMF:
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
case CKK_DES:
|
|
Packit |
8681c6 |
rc = des_wrap_get_data(key2_obj->template, length_only, &data,
|
|
Packit |
8681c6 |
&data_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("des_wrap_get_data failed.\n");
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKK_DES3:
|
|
Packit |
8681c6 |
rc = des3_wrap_get_data(key2_obj->template, length_only, &data,
|
|
Packit |
8681c6 |
&data_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("des3_wrap_get_data failed.\n");
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKK_RSA:
|
|
Packit |
8681c6 |
rc = rsa_priv_wrap_get_data(key2_obj->template, length_only, &data,
|
|
Packit |
8681c6 |
&data_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("rsa_priv_wrap_get_data failed.\n");
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#if !(NODSA)
|
|
Packit |
8681c6 |
case CKK_DSA:
|
|
Packit |
8681c6 |
rc = dsa_priv_wrap_get_data(key2_obj->template, length_only, &data,
|
|
Packit |
8681c6 |
&data_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("dsa_priv_wrap_get_data failed.\n");
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
case CKK_GENERIC_SECRET:
|
|
Packit |
8681c6 |
rc = generic_secret_wrap_get_data(key2_obj->template, length_only,
|
|
Packit |
8681c6 |
&data, &data_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("generic_secret_wrap_get_data failed.\n");
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#ifndef NOAES
|
|
Packit |
8681c6 |
case CKK_AES:
|
|
Packit |
8681c6 |
rc = aes_wrap_get_data(key2_obj->template, length_only, &data,
|
|
Packit |
8681c6 |
&data_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("aes_wrap_get_data failed.\n");
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
case CKK_EC:
|
|
Packit |
8681c6 |
rc = ecdsa_priv_wrap_get_data(key2_obj->template, length_only, &data,
|
|
Packit |
8681c6 |
&data_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("ecdsa_priv_wrap_get_data failed with rc=%s.\n",
|
|
Packit |
8681c6 |
ock_err(rc));
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_KEY_NOT_WRAPPABLE));
|
|
Packit |
8681c6 |
rc = CKR_KEY_NOT_WRAPPABLE;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// we might need to format the wrapped data based on the mechanism
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
switch (mech->mechanism) {
|
|
Packit |
8681c6 |
#if !(NOCMF)
|
|
Packit |
8681c6 |
case CKM_CDMF_ECB:
|
|
Packit |
8681c6 |
case CKM_CDMF_CBC:
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
case CKM_DES_ECB:
|
|
Packit |
8681c6 |
case CKM_DES_CBC:
|
|
Packit |
8681c6 |
case CKM_DES3_ECB:
|
|
Packit |
8681c6 |
case CKM_DES3_CBC:
|
|
Packit |
8681c6 |
rc = ckm_des_wrap_format(tokdata, length_only, &data, &data_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("ckm_des_wrap_format failed.\n");
|
|
Packit |
8681c6 |
if (data) {
|
|
Packit |
8681c6 |
OPENSSL_cleanse(data, data_len);
|
|
Packit |
8681c6 |
free(data);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#ifndef NOAES
|
|
Packit |
8681c6 |
case CKM_AES_ECB:
|
|
Packit |
8681c6 |
case CKM_AES_CBC:
|
|
Packit |
8681c6 |
case CKM_AES_CTR:
|
|
Packit |
8681c6 |
case CKM_AES_OFB:
|
|
Packit |
8681c6 |
case CKM_AES_CFB8:
|
|
Packit |
8681c6 |
case CKM_AES_CFB64:
|
|
Packit |
8681c6 |
case CKM_AES_CFB128:
|
|
Packit |
8681c6 |
rc = ckm_aes_wrap_format(tokdata, length_only, &data, &data_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("ckm_aes_wrap_format failed.\n");
|
|
Packit |
8681c6 |
if (data) {
|
|
Packit |
8681c6 |
OPENSSL_cleanse(data, data_len);
|
|
Packit |
8681c6 |
free(data);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
#if !(NOCMF)
|
|
Packit |
8681c6 |
case CKM_CDMF_CBC_PAD:
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
case CKM_DES_CBC_PAD:
|
|
Packit |
8681c6 |
case CKM_DES3_CBC_PAD:
|
|
Packit |
8681c6 |
case CKM_AES_CBC_PAD:
|
|
Packit |
8681c6 |
// these mechanisms pad themselves
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
case CKM_RSA_PKCS_OAEP:
|
|
Packit |
8681c6 |
case CKM_RSA_PKCS:
|
|
Packit |
8681c6 |
case CKM_RSA_X_509:
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
|
|
Packit |
8681c6 |
if (data) {
|
|
Packit |
8681c6 |
OPENSSL_cleanse(data, data_len);
|
|
Packit |
8681c6 |
free(data);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
rc = CKR_MECHANISM_INVALID;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
ctx = (ENCR_DECR_CONTEXT *) malloc(sizeof(ENCR_DECR_CONTEXT));
|
|
Packit |
8681c6 |
if (!ctx) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
Packit |
8681c6 |
if (data) {
|
|
Packit |
8681c6 |
OPENSSL_cleanse(data, data_len);
|
|
Packit |
8681c6 |
free(data);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
rc = CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
memset(ctx, 0x0, sizeof(ENCR_DECR_CONTEXT));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// prepare to do the encryption
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
rc = encr_mgr_init(tokdata, sess, ctx, OP_WRAP, mech, h_wrapping_key);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("encr_mgr_init failed.\n");
|
|
Packit |
8681c6 |
free(ctx);
|
|
Packit |
8681c6 |
if (data) {
|
|
Packit |
8681c6 |
OPENSSL_cleanse(data, data_len);
|
|
Packit |
8681c6 |
free(data);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// do the encryption and clean up. at this point, 'value' may or may not
|
|
Packit |
8681c6 |
// be NULL depending on 'length_only'
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
rc = encr_mgr_encrypt(tokdata, sess, length_only,
|
|
Packit |
8681c6 |
ctx, data, data_len, wrapped_key, wrapped_key_len);
|
|
Packit |
8681c6 |
if (data != NULL) {
|
|
Packit |
8681c6 |
OPENSSL_cleanse(data, data_len);
|
|
Packit |
8681c6 |
free(data);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
encr_mgr_cleanup(ctx);
|
|
Packit |
8681c6 |
free(ctx);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
done:
|
|
Packit |
8681c6 |
object_put(tokdata, key2_obj, TRUE);
|
|
Packit |
8681c6 |
key2_obj = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV key_mgr_unwrap_key(STDLL_TokData_t *tokdata,
|
|
Packit |
8681c6 |
SESSION *sess,
|
|
Packit |
8681c6 |
CK_MECHANISM *mech,
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attributes,
|
|
Packit |
8681c6 |
CK_ULONG attrib_count,
|
|
Packit |
8681c6 |
CK_BYTE *wrapped_key,
|
|
Packit |
8681c6 |
CK_ULONG wrapped_key_len,
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE h_unwrapping_key,
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE *h_unwrapped_key)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
ENCR_DECR_CONTEXT *ctx = NULL;
|
|
Packit |
8681c6 |
OBJECT *key_obj = NULL, *tmp_obj = NULL;
|
|
Packit |
8681c6 |
CK_BYTE *data = NULL;
|
|
Packit |
8681c6 |
CK_ULONG data_len;
|
|
Packit |
8681c6 |
CK_ULONG keyclass = 0, keytype = 0;
|
|
Packit |
8681c6 |
CK_ULONG i;
|
|
Packit |
8681c6 |
CK_BBOOL found_class, found_type, fromend, isopaque = FALSE;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!sess || !wrapped_key || !h_unwrapped_key) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_find_in_map1(tokdata, h_unwrapping_key, &tmp_obj, READ_LOCK);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to acquire key from specified handle");
|
|
Packit |
8681c6 |
if (rc == CKR_OBJECT_HANDLE_INVALID)
|
|
Packit |
8681c6 |
return CKR_WRAPPING_KEY_HANDLE_INVALID;
|
|
Packit |
8681c6 |
else
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (template_attribute_find(tmp_obj->template, CKA_IBM_OPAQUE, &attr) ==
|
|
Packit |
8681c6 |
TRUE) {
|
|
Packit |
8681c6 |
isopaque = TRUE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
object_put(tokdata, tmp_obj, TRUE);
|
|
Packit |
8681c6 |
tmp_obj = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
found_class = FALSE;
|
|
Packit |
8681c6 |
found_type = FALSE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* pkcs11v2-20
|
|
Packit |
8681c6 |
* C_WrapKey can be used in following situations:
|
|
Packit |
8681c6 |
* - To wrap any secret key with a public key that supports encryption
|
|
Packit |
8681c6 |
* and decryption.
|
|
Packit |
8681c6 |
* - To wrap any secret key with any other secret key. Consideration
|
|
Packit |
8681c6 |
* must be given to key size and mechanism strength or the token may
|
|
Packit |
8681c6 |
* not allow the operation.
|
|
Packit |
8681c6 |
* - To wrap a private key with any secret key.
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* extract key type and key class from the passed in attributes
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
for (i = 0; i < attrib_count; i++) {
|
|
Packit |
8681c6 |
switch (attributes[i].type) {
|
|
Packit |
8681c6 |
case CKA_CLASS:
|
|
Packit |
8681c6 |
keyclass = *(CK_OBJECT_CLASS *) attributes[i].pValue;
|
|
Packit |
8681c6 |
found_class = TRUE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKA_KEY_TYPE:
|
|
Packit |
8681c6 |
keytype = *(CK_KEY_TYPE *) attributes[i].pValue;
|
|
Packit |
8681c6 |
found_type = TRUE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// we need both key class and key type in template.
|
|
Packit |
8681c6 |
// we can be a bit lenient for private key since can extract key type
|
|
Packit |
8681c6 |
// from BER-encoded information.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (found_class == FALSE ||
|
|
Packit |
8681c6 |
(found_type == FALSE && keyclass != CKO_PRIVATE_KEY)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCOMPLETE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
switch (mech->mechanism) {
|
|
Packit |
8681c6 |
case CKM_CDMF_ECB:
|
|
Packit |
8681c6 |
case CKM_DES_ECB:
|
|
Packit |
8681c6 |
case CKM_AES_ECB:
|
|
Packit |
8681c6 |
case CKM_AES_CBC:
|
|
Packit |
8681c6 |
case CKM_RSA_PKCS_OAEP:
|
|
Packit |
8681c6 |
case CKM_RSA_PKCS:
|
|
Packit |
8681c6 |
case CKM_RSA_X_509:
|
|
Packit |
8681c6 |
if (keyclass != CKO_SECRET_KEY) {
|
|
Packit |
8681c6 |
TRACE_ERROR("The specified mechanism unwraps secret keys only.\n");
|
|
Packit |
8681c6 |
return CKR_ARGUMENTS_BAD;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#if !(NOCMF)
|
|
Packit |
8681c6 |
case CKM_CDMF_CBC:
|
|
Packit |
8681c6 |
case CKM_CDMF_CBC_PAD:
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
case CKM_DES_CBC:
|
|
Packit |
8681c6 |
case CKM_DES3_ECB:
|
|
Packit |
8681c6 |
case CKM_DES3_CBC:
|
|
Packit |
8681c6 |
case CKM_AES_CTR:
|
|
Packit |
8681c6 |
case CKM_AES_OFB:
|
|
Packit |
8681c6 |
case CKM_AES_CFB8:
|
|
Packit |
8681c6 |
case CKM_AES_CFB64:
|
|
Packit |
8681c6 |
case CKM_AES_CFB128:
|
|
Packit |
8681c6 |
case CKM_DES_CBC_PAD:
|
|
Packit |
8681c6 |
case CKM_DES3_CBC_PAD:
|
|
Packit |
8681c6 |
case CKM_AES_CBC_PAD:
|
|
Packit |
8681c6 |
if ((keyclass != CKO_SECRET_KEY) && (keyclass != CKO_PRIVATE_KEY)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Specified mech unwraps secret & private keys only.\n");
|
|
Packit |
8681c6 |
return CKR_ARGUMENTS_BAD;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
TRACE_ERROR("The specified mechanism cannot unwrap keys.\n");
|
|
Packit |
8681c6 |
return CKR_MECHANISM_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// looks okay... do the decryption
|
|
Packit |
8681c6 |
ctx = (ENCR_DECR_CONTEXT *) malloc(sizeof(ENCR_DECR_CONTEXT));
|
|
Packit |
8681c6 |
if (!ctx) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
Packit |
8681c6 |
return CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
memset(ctx, 0x0, sizeof(ENCR_DECR_CONTEXT));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = decr_mgr_init(tokdata, sess, ctx, OP_UNWRAP, mech, h_unwrapping_key);
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = decr_mgr_decrypt(tokdata, sess,
|
|
Packit |
8681c6 |
TRUE,
|
|
Packit |
8681c6 |
ctx, wrapped_key, wrapped_key_len, data, &data_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("decr_mgr_decrypt failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
data = (CK_BYTE *) malloc(data_len);
|
|
Packit |
8681c6 |
if (!data) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
Packit |
8681c6 |
rc = CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = decr_mgr_decrypt(tokdata, sess,
|
|
Packit |
8681c6 |
FALSE,
|
|
Packit |
8681c6 |
ctx, wrapped_key, wrapped_key_len, data, &data_len);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
decr_mgr_cleanup(ctx);
|
|
Packit |
8681c6 |
free(ctx);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("decr_mgr_decrypt failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// if we use X.509, the data will be padded from the front with zeros.
|
|
Packit |
8681c6 |
// PKCS #11 specifies that for this mechanism, CK_VALUE is to be read
|
|
Packit |
8681c6 |
// from the end of the data.
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Note: the PKCS #11 reference implementation gets this wrong.
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
if (mech->mechanism == CKM_RSA_X_509)
|
|
Packit |
8681c6 |
fromend = TRUE;
|
|
Packit |
8681c6 |
else
|
|
Packit |
8681c6 |
fromend = FALSE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// extract the key type from the PrivateKeyInfo::AlgorithmIndicator
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
if (keyclass == CKO_PRIVATE_KEY) {
|
|
Packit |
8681c6 |
rc = key_mgr_get_private_key_type(data, data_len, &keytype);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("key_mgr_get_private_key_type failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// we have decrypted the wrapped key data. we also
|
|
Packit |
8681c6 |
// know what type of key it is. now we need to construct a new key
|
|
Packit |
8681c6 |
// object...
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_create_skel(tokdata, sess,
|
|
Packit |
8681c6 |
attributes, attrib_count,
|
|
Packit |
8681c6 |
MODE_UNWRAP, keyclass, keytype, &key_obj);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_create_skel failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// at this point, 'key_obj' should contain a skeleton key. depending on
|
|
Packit |
8681c6 |
// the key type. we're now ready to plug in the decrypted key data.
|
|
Packit |
8681c6 |
// in some cases, the data will be BER-encoded so we'll need to decode it.
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// this routine also ensires that CKA_EXTRACTABLE == FALSE,
|
|
Packit |
8681c6 |
// CKA_ALWAYS_SENSITIVE == FALSE and CKA_LOCAL == FALSE
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
switch (keyclass) {
|
|
Packit |
8681c6 |
case CKO_SECRET_KEY:
|
|
Packit |
8681c6 |
rc = secret_key_unwrap(tokdata, key_obj->template, keytype, data,
|
|
Packit |
8681c6 |
data_len, fromend, isopaque);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKO_PRIVATE_KEY:
|
|
Packit |
8681c6 |
rc = priv_key_unwrap(key_obj->template, keytype, data, data_len,
|
|
Packit |
8681c6 |
isopaque);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
rc = CKR_WRAPPED_KEY_INVALID;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("key_unwrap failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// at this point, the key should be fully constructed...assign
|
|
Packit |
8681c6 |
// an object handle and store the key
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
rc = object_mgr_create_final(tokdata, sess, key_obj, h_unwrapped_key);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_create_final failed.\n");
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (data) {
|
|
Packit |
8681c6 |
OPENSSL_cleanse(data, data_len);
|
|
Packit |
8681c6 |
free(data);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
error:
|
|
Packit |
8681c6 |
if (key_obj)
|
|
Packit |
8681c6 |
object_free(key_obj);
|
|
Packit |
8681c6 |
if (data) {
|
|
Packit |
8681c6 |
OPENSSL_cleanse(data, data_len);
|
|
Packit |
8681c6 |
free(data);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV key_mgr_get_private_key_type(CK_BYTE *keydata,
|
|
Packit |
8681c6 |
CK_ULONG keylen, CK_KEY_TYPE *keytype)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_BYTE *alg = NULL;
|
|
Packit |
8681c6 |
CK_BYTE *priv_key = NULL;
|
|
Packit |
8681c6 |
CK_ULONG alg_len;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = ber_decode_PrivateKeyInfo(keydata, keylen, &alg, &alg_len, &priv_key);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// check the entire AlgorithmIdentifier for RSA
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
if (alg_len >= ber_rsaEncryptionLen) {
|
|
Packit |
8681c6 |
if (memcmp(alg, ber_rsaEncryption, ber_rsaEncryptionLen) == 0) {
|
|
Packit |
8681c6 |
*keytype = CKK_RSA;
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Check only the OBJECT IDENTIFIER for DSA
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
if (alg_len >= ber_idDSALen) {
|
|
Packit |
8681c6 |
if (memcmp(alg, ber_idDSA, ber_idDSALen) == 0) {
|
|
Packit |
8681c6 |
*keytype = CKK_DSA;
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Check only the OBJECT IDENTIFIER for EC
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
if (alg_len >= der_AlgIdECBaseLen) {
|
|
Packit |
8681c6 |
if (memcmp(alg, ber_idEC, ber_idECLen) == 0) {
|
|
Packit |
8681c6 |
*keytype = CKK_EC;
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE));
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCOMPLETE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV key_mgr_derive_key(STDLL_TokData_t *tokdata,
|
|
Packit |
8681c6 |
SESSION *sess,
|
|
Packit |
8681c6 |
CK_MECHANISM *mech,
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE base_key,
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE *derived_key,
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
if (!sess || !mech) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (!pTemplate && (ulCount != 0)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
switch (mech->mechanism) {
|
|
Packit |
8681c6 |
case CKM_SSL3_MASTER_KEY_DERIVE:
|
|
Packit |
8681c6 |
if (!derived_key) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
return ssl3_master_key_derive(tokdata, sess, mech, base_key,
|
|
Packit |
8681c6 |
pTemplate, ulCount, derived_key);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_SSL3_KEY_AND_MAC_DERIVE:
|
|
Packit |
8681c6 |
return ssl3_key_and_mac_derive(tokdata, sess, mech, base_key,
|
|
Packit |
8681c6 |
pTemplate, ulCount);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
/* Begin code contributed by Corrent corp. */
|
|
Packit |
8681c6 |
#ifndef NODH
|
|
Packit |
8681c6 |
case CKM_DH_PKCS_DERIVE:
|
|
Packit |
8681c6 |
if (!derived_key) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
return dh_pkcs_derive(tokdata, sess, mech, base_key,
|
|
Packit |
8681c6 |
pTemplate, ulCount, derived_key);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
/* End code contributed by Corrent corp. */
|
|
Packit |
8681c6 |
case CKM_ECDH1_DERIVE:
|
|
Packit |
8681c6 |
if (!derived_key) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s received bad argument(s)\n", __func__);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
return ecdh_pkcs_derive(tokdata, sess, mech, base_key, pTemplate,
|
|
Packit |
8681c6 |
ulCount, derived_key);
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
|
|
Packit |
8681c6 |
return CKR_MECHANISM_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|