pkcs11/pkcs15-init: remove automagic software key generation. Remove software based secret key handling from PKCS#11.
Support for importing cleartext keys is left untouched, but all transparent key generation by either opensc-pkcs11.so or pkcs15-init is removed, to make the operation with cleartext keys visible to the user and his explicit wish. OpenSC is a PKCS#11 library for accessing keys protected by a smart card. Key material in software is not protected by smart cards and can leave a false sense of security to the user. http://www.opensc-project.org/pipermail/opensc-devel/2010-April/013877.html git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@4646 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
1f73d32e40
commit
9a63e03e9a
|
@ -133,12 +133,6 @@
|
|||
<command>pkcs15-init</command> will also store the the public portion of the
|
||||
key as a PKCS #15 public key object.
|
||||
</para>
|
||||
<para>
|
||||
By default, <command>pkcs15-init</command> will try to use the card's
|
||||
on-board key generation facilities, if available. If the card does not
|
||||
support on-board key generation, <command>pkcs15-init</command> will fall
|
||||
back to software key generation.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
|
|
|
@ -367,12 +367,6 @@ app opensc-pkcs11 {
|
|||
# Default: false
|
||||
# lock_login = true;
|
||||
|
||||
# Set this value to true if you want to allow off-card
|
||||
# keypair generation (in software on your pc)
|
||||
#
|
||||
# Default: false
|
||||
# soft_keygen_allowed = true;
|
||||
|
||||
# User PIN unblock style
|
||||
# none: PIN unblock is not possible with PKCS#11 API;
|
||||
# set_pin_in_unlogged_session: C_SetPIN() in unlogged session:
|
||||
|
|
|
@ -12,7 +12,7 @@ INCLUDES = -I$(top_srcdir)/src
|
|||
|
||||
OPENSC_PKCS11_INC = sc-pkcs11.h pkcs11.h pkcs11-opensc.h
|
||||
OPENSC_PKCS11_SRC = pkcs11-global.c pkcs11-session.c pkcs11-object.c misc.c slot.c \
|
||||
mechanism.c openssl.c secretkey.c framework-pkcs15.c \
|
||||
mechanism.c openssl.c framework-pkcs15.c \
|
||||
framework-pkcs15init.c debug.c opensc-pkcs11.exports \
|
||||
pkcs11-display.c pkcs11-display.h
|
||||
OPENSC_PKCS11_LIBS = $(OPTIONAL_OPENSSL_LIBS) $(PTHREAD_LIBS) \
|
||||
|
|
|
@ -6,7 +6,7 @@ TARGET2 = libpkcs11.lib
|
|||
TARGET3 = pkcs11-spy.dll
|
||||
|
||||
OBJECTS = pkcs11-global.obj pkcs11-session.obj pkcs11-object.obj misc.obj slot.obj \
|
||||
mechanism.obj openssl.obj secretkey.obj framework-pkcs15.obj \
|
||||
mechanism.obj openssl.obj framework-pkcs15.obj \
|
||||
framework-pkcs15init.obj debug.obj pkcs11-display.obj \
|
||||
$(TOPDIR)\win32\versioninfo.res
|
||||
OBJECTS2 = libpkcs11.obj \
|
||||
|
|
|
@ -1727,7 +1727,6 @@ static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card,
|
|||
struct sc_profile *profile = NULL;
|
||||
struct sc_pkcs15_pin_info *pin;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
|
||||
struct sc_pkcs15_card *p15card = fw_data->p15_card;
|
||||
struct sc_pkcs15init_keygen_args keygen_args;
|
||||
struct sc_pkcs15init_pubkeyargs pub_args;
|
||||
struct sc_pkcs15_object *priv_key_obj;
|
||||
|
@ -1852,41 +1851,6 @@ static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card,
|
|||
rv = sc_to_cryptoki_error(rc, "C_GenerateKeyPair");
|
||||
goto kpgen_done;
|
||||
}
|
||||
else {
|
||||
/* 3.b Try key pair generation in software, if allowed */
|
||||
|
||||
if (!sc_pkcs11_conf.soft_keygen_allowed) {
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "On card keypair gen not supported, software keypair gen not allowed");
|
||||
rv = CKR_FUNCTION_FAILED;
|
||||
goto kpgen_done;
|
||||
}
|
||||
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "Doing key pair generation in software\n");
|
||||
rv = sc_pkcs11_gen_keypair_soft(keytype, keybits,
|
||||
&keygen_args.prkey_args.key, &pub_args.key);
|
||||
if (rv != CKR_OK) {
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "sc_pkcs11_gen_keypair_soft failed: 0x%0x\n", rv);
|
||||
goto kpgen_done;
|
||||
}
|
||||
|
||||
rc = sc_pkcs15init_store_private_key(p15card, profile, &keygen_args.prkey_args, &priv_key_obj);
|
||||
|
||||
if (rc >= 0) {
|
||||
/* copy ID from private key(s) here to avoid bad link between private and public key */
|
||||
memcpy(&pub_args.id.value, &keygen_args.prkey_args.id.value, keygen_args.prkey_args.id.len);
|
||||
pub_args.id.len = keygen_args.prkey_args.id.len;
|
||||
rc = sc_pkcs15init_store_public_key(p15card, profile, &pub_args, &pub_key_obj);
|
||||
}
|
||||
|
||||
sc_pkcs15_erase_prkey(&keygen_args.prkey_args.key);
|
||||
sc_pkcs15_erase_pubkey(&pub_args.key);
|
||||
|
||||
if (rc < 0) {
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "private/public keys not stored: %d\n", rc);
|
||||
rv = sc_to_cryptoki_error(rc, "C_GenerateKeyPair");
|
||||
goto kpgen_done;
|
||||
}
|
||||
}
|
||||
|
||||
/* 4. Create new pkcs11 public and private key object */
|
||||
|
||||
|
@ -2465,9 +2429,9 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
|
|||
u8 decrypted[256];
|
||||
int buff_too_small, rv, flags = 0;
|
||||
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "Initiating unwrap/decryption.\n");
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "Initiating decryption.\n");
|
||||
|
||||
/* See which of the alternative keys supports unwrap/decrypt */
|
||||
/* See which of the alternative keys supports decrypt */
|
||||
prkey = (struct pkcs15_prkey_object *) obj;
|
||||
while (prkey
|
||||
&& !(prkey->prv_info->usage
|
||||
|
@ -2507,7 +2471,7 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
|
|||
|
||||
sc_unlock(ses->slot->card->card);
|
||||
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "Key unwrap/decryption complete. Result %d.\n", rv);
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "Key decryption complete. Result %d.\n", rv);
|
||||
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, "C_Decrypt");
|
||||
|
@ -2523,28 +2487,6 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
|
|||
return CKR_OK;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
pkcs15_prkey_unwrap(struct sc_pkcs11_session *ses, void *obj,
|
||||
CK_MECHANISM_PTR pMechanism,
|
||||
CK_BYTE_PTR pData, CK_ULONG ulDataLen,
|
||||
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
|
||||
void **result)
|
||||
{
|
||||
u8 unwrapped_key[256];
|
||||
CK_ULONG key_len = sizeof(unwrapped_key);
|
||||
int rc;
|
||||
|
||||
rc = pkcs15_prkey_decrypt(ses, obj, pMechanism, pData, ulDataLen,
|
||||
unwrapped_key, &key_len);
|
||||
|
||||
if (rc < 0)
|
||||
return sc_to_cryptoki_error(rc, NULL);
|
||||
return sc_pkcs11_create_secret_key(ses,
|
||||
unwrapped_key, key_len,
|
||||
pTemplate, ulAttributeCount,
|
||||
(struct sc_pkcs11_object **) result);
|
||||
}
|
||||
|
||||
struct sc_pkcs11_object_ops pkcs15_prkey_ops = {
|
||||
pkcs15_prkey_release,
|
||||
pkcs15_prkey_set_attribute,
|
||||
|
@ -2553,7 +2495,7 @@ struct sc_pkcs11_object_ops pkcs15_prkey_ops = {
|
|||
pkcs15_any_destroy,
|
||||
NULL,
|
||||
pkcs15_prkey_sign,
|
||||
pkcs15_prkey_unwrap,
|
||||
NULL, /* unwrap */
|
||||
pkcs15_prkey_decrypt
|
||||
};
|
||||
|
||||
|
|
|
@ -301,73 +301,6 @@ static void sc_pkcs11_openssl_md_release(sc_pkcs11_operation_t *op)
|
|||
op->priv_data = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
do_convert_bignum(sc_pkcs15_bignum_t *dst, BIGNUM *src)
|
||||
{
|
||||
if (src == 0)
|
||||
return 0;
|
||||
dst->len = BN_num_bytes(src);
|
||||
dst->data = malloc(dst->len);
|
||||
if (dst->data == NULL)
|
||||
return 0;
|
||||
BN_bn2bin(src, dst->data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
CK_RV
|
||||
sc_pkcs11_gen_keypair_soft(CK_KEY_TYPE keytype, CK_ULONG keybits,
|
||||
struct sc_pkcs15_prkey *privkey, struct sc_pkcs15_pubkey *pubkey)
|
||||
{
|
||||
switch (keytype) {
|
||||
case CKK_RSA: {
|
||||
RSA *rsa;
|
||||
BIO *err;
|
||||
struct sc_pkcs15_prkey_rsa *sc_priv = &privkey->u.rsa;
|
||||
struct sc_pkcs15_pubkey_rsa *sc_pub = &pubkey->u.rsa;
|
||||
|
||||
err = BIO_new(BIO_s_mem());
|
||||
rsa = RSA_generate_key(keybits, 0x10001, NULL, err);
|
||||
BIO_free(err);
|
||||
if (rsa == NULL) {
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "RSA_generate_key() failed\n");
|
||||
return CKR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
privkey->algorithm = pubkey->algorithm = SC_ALGORITHM_RSA;
|
||||
|
||||
if (!do_convert_bignum(&sc_priv->modulus, rsa->n)
|
||||
|| !do_convert_bignum(&sc_priv->exponent, rsa->e)
|
||||
|| !do_convert_bignum(&sc_priv->d, rsa->d)
|
||||
|| !do_convert_bignum(&sc_priv->p, rsa->p)
|
||||
|| !do_convert_bignum(&sc_priv->q, rsa->q)) {
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "do_convert_bignum() failed\n");
|
||||
RSA_free(rsa);
|
||||
return CKR_FUNCTION_FAILED;
|
||||
}
|
||||
if (rsa->iqmp && rsa->dmp1 && rsa->dmq1) {
|
||||
do_convert_bignum(&sc_priv->iqmp, rsa->iqmp);
|
||||
do_convert_bignum(&sc_priv->dmp1, rsa->dmp1);
|
||||
do_convert_bignum(&sc_priv->dmq1, rsa->dmq1);
|
||||
}
|
||||
|
||||
if (!do_convert_bignum(&sc_pub->modulus, rsa->n)
|
||||
|| !do_convert_bignum(&sc_pub->exponent, rsa->e)) {
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "do_convert_bignum() failed\n");
|
||||
RSA_free(rsa);
|
||||
return CKR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
RSA_free(rsa);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return CKR_MECHANISM_PARAM_INVALID;
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
|
||||
|
||||
static void reverse(unsigned char *buf, size_t len)
|
||||
|
|
|
@ -966,51 +966,7 @@ CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
CK_ULONG ulAttributeCount, /* # of attributes in template */
|
||||
CK_OBJECT_HANDLE_PTR phKey)
|
||||
{ /* gets handle of recovered key */
|
||||
CK_RV rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
struct sc_pkcs11_object *object, *result;
|
||||
|
||||
rv = sc_pkcs11_lock();
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
|
||||
if (pMechanism == NULL_PTR || (pTemplate == NULL_PTR && ulAttributeCount > 0)) {
|
||||
rv = CKR_ARGUMENTS_BAD;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = get_object_from_session(hSession, hUnwrappingKey, &session, &object);
|
||||
if (rv != CKR_OK) {
|
||||
if (rv == CKR_OBJECT_HANDLE_INVALID)
|
||||
rv = CKR_UNWRAPPING_KEY_HANDLE_INVALID;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(session->flags & CKF_RW_SESSION)) {
|
||||
rv = CKR_SESSION_READ_ONLY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (object->ops->sign == NULL_PTR) {
|
||||
rv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = object->ops->unwrap_key(session, object, pMechanism,
|
||||
pWrappedKey, ulWrappedKeyLen,
|
||||
pTemplate, ulAttributeCount, (void **)&result);
|
||||
|
||||
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_UnwrapKey() = %s", lookup_enum ( RV_T, rv ));
|
||||
|
||||
if (rv == CKR_OK) {
|
||||
result->handle = (long)result;
|
||||
list_append(&session->slot->objects, result);
|
||||
|
||||
}
|
||||
*phKey = result->handle;
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
|
|
|
@ -1,233 +0,0 @@
|
|||
/*
|
||||
* Secret key handling for PKCS#11
|
||||
*
|
||||
* This module deals only with secret keys that have been unwrapped
|
||||
* by the card. At the moment, we do not support key unwrapping
|
||||
* where the key remains on the token.
|
||||
*
|
||||
* Copyright (C) 2002 Olaf Kirch <okir@lst.de>
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sc-pkcs11.h"
|
||||
|
||||
struct pkcs11_secret_key {
|
||||
struct sc_pkcs11_object object;
|
||||
|
||||
char * label;
|
||||
CK_KEY_TYPE type;
|
||||
CK_BYTE_PTR value;
|
||||
CK_ULONG value_len;
|
||||
};
|
||||
|
||||
extern struct sc_pkcs11_object_ops pkcs11_secret_key_ops;
|
||||
|
||||
#define set_attr(var, attr) \
|
||||
if (attr->ulValueLen != sizeof(var)) \
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID; \
|
||||
memcpy(&var, attr->pValue, attr->ulValueLen);
|
||||
#define check_attr(attr, size) \
|
||||
if (attr->pValue == NULL_PTR) { \
|
||||
attr->ulValueLen = size; \
|
||||
return CKR_OK; \
|
||||
} \
|
||||
if (attr->ulValueLen < size) { \
|
||||
attr->ulValueLen = size; \
|
||||
return CKR_BUFFER_TOO_SMALL; \
|
||||
} \
|
||||
attr->ulValueLen = size;
|
||||
#define get_attr(attr, type, value) \
|
||||
check_attr(attr, sizeof(type)); \
|
||||
*(type *) (attr->pValue) = value;
|
||||
|
||||
CK_RV
|
||||
sc_pkcs11_create_secret_key(struct sc_pkcs11_session *session,
|
||||
const u8 *value, size_t value_len,
|
||||
CK_ATTRIBUTE_PTR _template,
|
||||
CK_ULONG attribute_count,
|
||||
struct sc_pkcs11_object **out)
|
||||
{
|
||||
struct pkcs11_secret_key *key;
|
||||
CK_ATTRIBUTE_PTR attr;
|
||||
int n, rv;
|
||||
|
||||
key = calloc(1, sizeof(*key));
|
||||
if (!key)
|
||||
return CKR_HOST_MEMORY;
|
||||
key->value = malloc(value_len);
|
||||
if (!key->value) {
|
||||
pkcs11_secret_key_ops.release(key);
|
||||
return CKR_HOST_MEMORY; /* XXX correct? */
|
||||
}
|
||||
memcpy(key->value, value, value_len);
|
||||
key->value_len = value_len;
|
||||
key->object.ops = &pkcs11_secret_key_ops;
|
||||
|
||||
/* Make sure the key type is given in the template */
|
||||
for (n = attribute_count, attr = _template; n--; attr++) {
|
||||
if (attr->type == CKA_KEY_TYPE) {
|
||||
set_attr(key->type, attr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n < 0) {
|
||||
pkcs11_secret_key_ops.release(key);
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
|
||||
/* Set all the other attributes */
|
||||
for (n = attribute_count, attr = _template; n--; attr++) {
|
||||
rv = key->object.ops->set_attribute(session, key, attr);
|
||||
if (rv != CKR_OK) {
|
||||
pkcs11_secret_key_ops.release(key);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
*out = (struct sc_pkcs11_object *) key;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
sc_pkcs11_secret_key_release(void *object)
|
||||
{
|
||||
struct pkcs11_secret_key *key;
|
||||
|
||||
key = (struct pkcs11_secret_key *) object;
|
||||
if (key) {
|
||||
if (key->value)
|
||||
free(key->value);
|
||||
if (key->label)
|
||||
free(key->label);
|
||||
free(key);
|
||||
}
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
sc_pkcs11_secret_key_set_attribute(struct sc_pkcs11_session *session,
|
||||
void *object, CK_ATTRIBUTE_PTR attr)
|
||||
{
|
||||
struct pkcs11_secret_key *key;
|
||||
CK_OBJECT_CLASS ck_class;
|
||||
CK_KEY_TYPE ck_key_type;
|
||||
CK_BBOOL ck_bbool;
|
||||
|
||||
key = (struct pkcs11_secret_key *) object;
|
||||
switch (attr->type) {
|
||||
case CKA_CLASS:
|
||||
set_attr(ck_class, attr);
|
||||
if (ck_class != CKO_SECRET_KEY)
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
break;
|
||||
case CKA_KEY_TYPE:
|
||||
set_attr(ck_key_type, attr);
|
||||
if (ck_key_type != key->type)
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
break;
|
||||
case CKA_LABEL:
|
||||
if (key->label)
|
||||
free(key->label);
|
||||
key->label = strdup((const char *) attr->pValue);
|
||||
break;
|
||||
case CKA_TOKEN:
|
||||
set_attr(ck_bbool, attr);
|
||||
if (!ck_bbool)
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
break;
|
||||
case CKA_VALUE:
|
||||
if (key->value)
|
||||
free(key->value);
|
||||
key->value = malloc(attr->ulValueLen);
|
||||
if (key->value == NULL)
|
||||
return CKR_HOST_MEMORY;
|
||||
key->value_len = attr->ulValueLen;
|
||||
memcpy(key->value, attr->pValue, key->value_len);
|
||||
break;
|
||||
case CKA_ENCRYPT:
|
||||
case CKA_DECRYPT:
|
||||
case CKA_SIGN:
|
||||
case CKA_VERIFY:
|
||||
case CKA_WRAP:
|
||||
case CKA_UNWRAP:
|
||||
case CKA_EXTRACTABLE:
|
||||
case CKA_ALWAYS_SENSITIVE:
|
||||
case CKA_NEVER_EXTRACTABLE:
|
||||
/* We ignore these for now, just making sure the argument
|
||||
* has the right size */
|
||||
set_attr(ck_bbool, attr);
|
||||
break;
|
||||
default:
|
||||
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
sc_pkcs11_secret_key_get_attribute(struct sc_pkcs11_session *session,
|
||||
void *object, CK_ATTRIBUTE_PTR attr)
|
||||
{
|
||||
struct pkcs11_secret_key *key;
|
||||
|
||||
key = (struct pkcs11_secret_key *) object;
|
||||
switch (attr->type) {
|
||||
case CKA_CLASS:
|
||||
get_attr(attr, CK_OBJECT_CLASS, CKO_SECRET_KEY);
|
||||
break;
|
||||
case CKA_KEY_TYPE:
|
||||
get_attr(attr, CK_KEY_TYPE, key->type);
|
||||
case CKA_VALUE:
|
||||
check_attr(attr, key->value_len);
|
||||
memcpy(attr->pValue, key->value, key->value_len);
|
||||
break;
|
||||
case CKA_VALUE_LEN:
|
||||
get_attr(attr, CK_ULONG, key->value_len);
|
||||
break;
|
||||
case CKA_SENSITIVE:
|
||||
case CKA_SIGN:
|
||||
case CKA_VERIFY:
|
||||
case CKA_WRAP:
|
||||
case CKA_UNWRAP:
|
||||
case CKA_NEVER_EXTRACTABLE:
|
||||
get_attr(attr, CK_BBOOL, 0);
|
||||
break;
|
||||
case CKA_ENCRYPT:
|
||||
case CKA_DECRYPT:
|
||||
case CKA_EXTRACTABLE:
|
||||
case CKA_ALWAYS_SENSITIVE:
|
||||
get_attr(attr, CK_BBOOL, 1);
|
||||
break;
|
||||
default:
|
||||
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
}
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
struct sc_pkcs11_object_ops pkcs11_secret_key_ops = {
|
||||
sc_pkcs11_secret_key_release,
|
||||
sc_pkcs11_secret_key_set_attribute,
|
||||
sc_pkcs11_secret_key_get_attribute,
|
||||
sc_pkcs11_any_cmp_attribute,
|
||||
NULL, /* destroy_object */
|
||||
NULL, /* get_size */
|
||||
NULL, /* sign */
|
||||
NULL, /* unwrap_key */
|
||||
NULL /* decrypt */
|
||||
};
|
|
@ -107,7 +107,6 @@ static int get_key_callback(struct sc_profile *,
|
|||
int method, int reference,
|
||||
const u8 *, size_t, u8 *, size_t *);
|
||||
|
||||
static int do_generate_key_soft(int, unsigned int, EVP_PKEY **);
|
||||
static int do_read_private_key(const char *, const char *,
|
||||
EVP_PKEY **, X509 **, unsigned int);
|
||||
static int do_read_public_key(const char *, const char *, EVP_PKEY **);
|
||||
|
@ -124,7 +123,6 @@ enum {
|
|||
OPT_EXTRACTABLE,
|
||||
OPT_UNPROTECTED,
|
||||
OPT_AUTHORITY,
|
||||
OPT_SOFT_KEYGEN,
|
||||
OPT_ASSERT_PRISTINE,
|
||||
OPT_SECRET,
|
||||
OPT_PUBKEY_LABEL,
|
||||
|
@ -185,7 +183,6 @@ const struct option options[] = {
|
|||
|
||||
{ "extractable", no_argument, NULL, OPT_EXTRACTABLE },
|
||||
{ "insecure", no_argument, NULL, OPT_UNPROTECTED },
|
||||
{ "soft", no_argument, NULL, OPT_SOFT_KEYGEN },
|
||||
{ "use-default-transport-keys",
|
||||
no_argument, NULL, 'T' },
|
||||
{ "no-prompt", no_argument, NULL, OPT_NO_PROMPT },
|
||||
|
@ -319,7 +316,6 @@ static unsigned int opt_actions;
|
|||
static int opt_extractable = 0,
|
||||
opt_unprotected = 0,
|
||||
opt_authority = 0,
|
||||
opt_softkeygen = 0,
|
||||
opt_no_prompt = 0,
|
||||
opt_no_sopin = 0,
|
||||
opt_use_defkeys = 0,
|
||||
|
@ -1401,8 +1397,7 @@ static int
|
|||
do_generate_key(struct sc_profile *profile, const char *spec)
|
||||
{
|
||||
struct sc_pkcs15init_keygen_args keygen_args;
|
||||
unsigned int evp_algo, keybits = 1024;
|
||||
EVP_PKEY *pkey;
|
||||
unsigned int keybits = 1024;
|
||||
int r;
|
||||
|
||||
memset(&keygen_args, 0, sizeof(keygen_args));
|
||||
|
@ -1419,11 +1414,9 @@ do_generate_key(struct sc_profile *profile, const char *spec)
|
|||
/* Parse the key spec given on the command line */
|
||||
if (!strncasecmp(spec, "rsa", 3)) {
|
||||
keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_RSA;
|
||||
evp_algo = EVP_PKEY_RSA;
|
||||
spec += 3;
|
||||
} else if (!strncasecmp(spec, "dsa", 3)) {
|
||||
keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_DSA;
|
||||
evp_algo = EVP_PKEY_DSA;
|
||||
spec += 3;
|
||||
} else if (!strncasecmp(spec, "gost2001", strlen("gost2001"))) {
|
||||
keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_GOSTR3410;
|
||||
|
@ -1431,7 +1424,6 @@ do_generate_key(struct sc_profile *profile, const char *spec)
|
|||
/* FIXME: now only SC_PKCS15_PARAMSET_GOSTR3410_A */
|
||||
keygen_args.prkey_args.gost_params.gostr3410 =
|
||||
SC_PKCS15_PARAMSET_GOSTR3410_A;
|
||||
evp_algo = 0; /* FIXME */
|
||||
spec += strlen("gost2001");
|
||||
} else {
|
||||
util_error("Unknown algorithm \"%s\"", spec);
|
||||
|
@ -1449,32 +1441,7 @@ do_generate_key(struct sc_profile *profile, const char *spec)
|
|||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
}
|
||||
|
||||
if (!opt_softkeygen) {
|
||||
r = sc_pkcs15init_generate_key(p15card, profile, &keygen_args,
|
||||
keybits, NULL);
|
||||
if (r >= 0 || r != SC_ERROR_NOT_SUPPORTED)
|
||||
return r;
|
||||
if (verbose)
|
||||
printf("Warning: card doesn't support on-board "
|
||||
"key generation.\n"
|
||||
"Trying software generation\n");
|
||||
}
|
||||
|
||||
/* Generate the key ourselves */
|
||||
if ((r = do_generate_key_soft(evp_algo, keybits, &pkey)) < 0
|
||||
|| (r = do_convert_private_key(&keygen_args.prkey_args.key, pkey) ) < 0)
|
||||
goto out;
|
||||
|
||||
r = sc_pkcs15init_store_private_key(p15card,
|
||||
profile, &keygen_args.prkey_args, NULL);
|
||||
|
||||
/* Store public key portion on card */
|
||||
if (r >= 0)
|
||||
r = do_store_public_key(profile, pkey);
|
||||
|
||||
out:
|
||||
EVP_PKEY_free(pkey);
|
||||
r = sc_pkcs15init_generate_key(p15card, profile, &keygen_args, keybits, NULL);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -1854,46 +1821,6 @@ get_key_callback(struct sc_profile *profile,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a private key
|
||||
*/
|
||||
static int do_generate_key_soft(int algorithm, unsigned int bits,
|
||||
EVP_PKEY **res)
|
||||
{
|
||||
*res = EVP_PKEY_new();
|
||||
switch (algorithm) {
|
||||
case EVP_PKEY_RSA: {
|
||||
RSA *rsa;
|
||||
BIO *err;
|
||||
|
||||
err = BIO_new(BIO_s_mem());
|
||||
rsa = RSA_generate_key(bits, 0x10001, NULL, err);
|
||||
BIO_free(err);
|
||||
if (rsa == 0)
|
||||
util_fatal("RSA key generation error");
|
||||
EVP_PKEY_assign_RSA(*res, rsa);
|
||||
break;
|
||||
}
|
||||
case EVP_PKEY_DSA: {
|
||||
DSA *dsa;
|
||||
int r = 0;
|
||||
|
||||
dsa = DSA_generate_parameters(bits,
|
||||
NULL, 0, NULL,
|
||||
NULL, NULL, NULL);
|
||||
if (dsa)
|
||||
r = DSA_generate_key(dsa);
|
||||
if (r == 0 || dsa == 0)
|
||||
util_fatal("DSA key generation error");
|
||||
EVP_PKEY_assign_DSA(*res, dsa);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
util_fatal("Unable to generate key: unsupported algorithm");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a private key
|
||||
*/
|
||||
|
@ -2579,9 +2506,6 @@ handle_option(const struct option *opt)
|
|||
case OPT_AUTHORITY:
|
||||
opt_authority = 1;
|
||||
break;
|
||||
case OPT_SOFT_KEYGEN:
|
||||
opt_softkeygen = 1;
|
||||
break;
|
||||
case OPT_APPLICATION_NAME:
|
||||
opt_application_name = optarg;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue