First implementation of C_GenerateKeyPair()
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1179 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
7fe0ba8749
commit
c8c2cf725b
|
@ -190,5 +190,11 @@ app opensc-pkcs11 {
|
|||
#
|
||||
# Default: false
|
||||
cache_pins = false;
|
||||
|
||||
# Set this value to false if you want to enfore on-card
|
||||
# keypair generation
|
||||
#
|
||||
# Default: true
|
||||
soft_keygen_allowed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -815,7 +815,7 @@ static CK_RV pkcs15_create_private_key(struct sc_pkcs11_card *p11card,
|
|||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
if (key_type != CKK_RSA)
|
||||
return CKR_FUNCTION_NOT_SUPPORTED; /* XXX correct code? */
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
args.key.algorithm = SC_ALGORITHM_RSA;
|
||||
rsa = &args.key.u.rsa;
|
||||
|
||||
|
@ -909,7 +909,7 @@ static CK_RV pkcs15_create_public_key(struct sc_pkcs11_card *p11card,
|
|||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
if (key_type != CKK_RSA)
|
||||
return CKR_FUNCTION_NOT_SUPPORTED; /* XXX correct code? */
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
args.key.algorithm = SC_ALGORITHM_RSA;
|
||||
rsa = &args.key.u.rsa;
|
||||
|
||||
|
@ -991,7 +991,7 @@ static CK_RV pkcs15_create_certificate(struct sc_pkcs11_card *p11card,
|
|||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
if (cert_type != CKC_X_509)
|
||||
return CKR_FUNCTION_NOT_SUPPORTED; /* XXX correct code? */
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
|
||||
rv = CKR_OK;
|
||||
while (ulCount--) {
|
||||
|
@ -1097,6 +1097,235 @@ static CK_RV pkcs15_create_object(struct sc_pkcs11_card *p11card,
|
|||
sc_pkcs15init_unbind(profile);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
get_X509_usage_privk(CK_ATTRIBUTE_PTR pTempl, CK_ULONG ulCount, unsigned long *x509_usage)
|
||||
{
|
||||
CK_ULONG i;
|
||||
for (i = 0; i < ulCount; i++) {
|
||||
CK_ATTRIBUTE_TYPE typ = pTempl[i].type;
|
||||
CK_BBOOL *val = (CK_BBOOL *) pTempl[i].pValue;
|
||||
if (val == NULL)
|
||||
continue;
|
||||
if (typ == CKA_SIGN && *val)
|
||||
*x509_usage |= 1;
|
||||
if (typ == CKA_UNWRAP && *val)
|
||||
*x509_usage |= 4;
|
||||
if (typ == CKA_DECRYPT && *val)
|
||||
*x509_usage |= 8;
|
||||
if (typ == CKA_DERIVE && *val)
|
||||
*x509_usage |= 16;
|
||||
if (typ == CKA_VERIFY || typ == CKA_WRAP || typ == CKA_ENCRYPT) {
|
||||
debug(context, "get_X509_usage_privk(): invalid typ = 0x%0x\n", typ);
|
||||
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
}
|
||||
}
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
get_X509_usage_pubk(CK_ATTRIBUTE_PTR pTempl, CK_ULONG ulCount, unsigned long *x509_usage)
|
||||
{
|
||||
CK_ULONG i;
|
||||
for (i = 0; i < ulCount; i++) {
|
||||
CK_ATTRIBUTE_TYPE typ = pTempl[i].type;
|
||||
CK_BBOOL *val = (CK_BBOOL *) pTempl[i].pValue;
|
||||
if (val == NULL)
|
||||
continue;
|
||||
if (typ == CKA_VERIFY && *val)
|
||||
*x509_usage |= 1;
|
||||
if (typ == CKA_WRAP && *val)
|
||||
*x509_usage |= 4;
|
||||
if (typ == CKA_ENCRYPT && *val)
|
||||
*x509_usage |= 8;
|
||||
if (typ == CKA_DERIVE && *val)
|
||||
*x509_usage |= 16;
|
||||
if (typ == CKA_SIGN || typ == CKA_UNWRAP || typ == CKA_DECRYPT) {
|
||||
debug(context, "get_X509_usage_pubk(): invalid typ = 0x%0x\n", typ);
|
||||
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
}
|
||||
}
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
/* FIXME: check for the public exponent in public key template and use this value */
|
||||
CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card, struct sc_pkcs11_slot *slot,
|
||||
CK_MECHANISM_PTR pMechanism,
|
||||
CK_ATTRIBUTE_PTR pPubTpl, CK_ULONG ulPubCnt,
|
||||
CK_ATTRIBUTE_PTR pPrivTpl, CK_ULONG ulPrivCnt,
|
||||
CK_OBJECT_HANDLE_PTR phPubKey, CK_OBJECT_HANDLE_PTR phPrivKey) /* gets priv. key handle */
|
||||
{
|
||||
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 pkcs15_slot_data *p15_data = slot_data(slot->fw_data);
|
||||
struct sc_pkcs15_card *p15card = fw_data->p15_card;
|
||||
struct sc_pkcs15init_prkeyargs priv_args;
|
||||
struct sc_pkcs15init_pubkeyargs pub_args;
|
||||
struct sc_pkcs15_object *priv_key_obj;
|
||||
struct sc_pkcs15_object *pub_key_obj;
|
||||
struct sc_pkcs15_id id;
|
||||
size_t len;
|
||||
CK_KEY_TYPE keytype = CKK_RSA;
|
||||
CK_ULONG keybits;
|
||||
char pub_label[SC_PKCS15_MAX_LABEL_SIZE];
|
||||
char priv_label[SC_PKCS15_MAX_LABEL_SIZE];
|
||||
int j, rc, rv = CKR_OK;
|
||||
|
||||
debug(context, "Keypair generation, mech = 0x%0x\n", pMechanism->mechanism);
|
||||
|
||||
if (pMechanism->mechanism != CKM_RSA_PKCS_KEY_PAIR_GEN)
|
||||
return CKR_MECHANISM_INVALID;
|
||||
|
||||
rc = sc_pkcs15init_bind(p11card->card, "pkcs15", &profile);
|
||||
if (rc < 0)
|
||||
return sc_to_cryptoki_error(rc, p11card->reader);
|
||||
|
||||
memset(&priv_args, 0, sizeof(priv_args));
|
||||
memset(&pub_args, 0, sizeof(pub_args));
|
||||
|
||||
/* 1. Convert the pkcs11 attributes to pkcs15init args */
|
||||
|
||||
if ((pin = slot_data_pin_info(slot->fw_data)) != NULL)
|
||||
priv_args.auth_id = pub_args.auth_id = pin->auth_id;
|
||||
|
||||
rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_KEY_TYPE,
|
||||
&keytype, NULL);
|
||||
if (rv == CKR_OK && keytype != CKK_RSA) {
|
||||
rv = CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
goto kpgen_done;
|
||||
}
|
||||
priv_args.key.algorithm = pub_args.key.algorithm = SC_ALGORITHM_RSA;
|
||||
|
||||
rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_MODULUS_BITS,
|
||||
&keybits, NULL);
|
||||
if (rv != CKR_OK)
|
||||
keybits = 1024; /* Default key size */
|
||||
/* To do: check allowed values of keybits */
|
||||
|
||||
id.len = SC_PKCS15_MAX_ID_SIZE;
|
||||
rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_ID,
|
||||
&id.value, &id.len);
|
||||
if (rv == CKR_OK)
|
||||
priv_args.id = pub_args.id = id;
|
||||
|
||||
len = sizeof(priv_label);
|
||||
rv = attr_find(pPrivTpl, ulPrivCnt, CKA_LABEL, priv_label, &len);
|
||||
if (rv != CKR_OK) {
|
||||
priv_label[SC_PKCS15_MAX_LABEL_SIZE - 1] = '\0';
|
||||
priv_args.label = priv_label;
|
||||
}
|
||||
len = sizeof(pub_label);
|
||||
rv = attr_find(pPubTpl, ulPubCnt, CKA_LABEL, pub_label, &len);
|
||||
if (rv != CKR_OK) {
|
||||
pub_label[SC_PKCS15_MAX_LABEL_SIZE - 1] = '\0';
|
||||
pub_args.label = pub_label;
|
||||
}
|
||||
|
||||
rv = get_X509_usage_privk(pPrivTpl, ulPrivCnt, &priv_args.x509_usage);
|
||||
if (rv == CKR_OK)
|
||||
rv = get_X509_usage_pubk(pPubTpl, ulPubCnt, &priv_args.x509_usage);
|
||||
if (rv != CKR_OK)
|
||||
goto kpgen_done;
|
||||
pub_args.x509_usage = priv_args.x509_usage;
|
||||
|
||||
/* 2. Supply the user PIN to the profile */
|
||||
|
||||
if (p15_data->pin[CKU_USER].len != 0)
|
||||
sc_profile_set_secret(profile, SC_AC_CHV, 1,
|
||||
p15_data->pin[CKU_USER].value, p15_data->pin[CKU_USER].len);
|
||||
else
|
||||
debug(context, "User PIN not cached, keypair gen will probably fail\n");
|
||||
|
||||
/* 3.a Try on-card key pair generation */
|
||||
rc = sc_pkcs15init_generate_key(fw_data->p15_card, profile,
|
||||
&priv_args, keybits, &priv_key_obj);
|
||||
if (rc >= 0) {
|
||||
id = ((sc_pkcs15_prkey_info *) priv_key_obj->data)->id;
|
||||
rc = sc_pkcs15_find_pubkey_by_id(fw_data->p15_card, &id, &pub_key_obj);
|
||||
if (rc != 0) {
|
||||
debug(context, "sc_pkcs15_find_pubkey_by_id returned %d\n", rc);
|
||||
rv = sc_to_cryptoki_error(rc, p11card->reader);
|
||||
goto kpgen_done;
|
||||
}
|
||||
}
|
||||
else if (rc != SC_ERROR_NOT_SUPPORTED) {
|
||||
debug(context, "sc_pkcs15init_generate_key returned %d\n", rc);
|
||||
rv = sc_to_cryptoki_error(rc, p11card->reader);
|
||||
goto kpgen_done;
|
||||
}
|
||||
else {
|
||||
/* 3.b Try key pair generation in software, if allowed */
|
||||
|
||||
if (!sc_pkcs11_conf.soft_keygen_allowed) {
|
||||
debug(context, "On card keypair gen not supported, software keypair gen not allowed");
|
||||
rv = CKR_FUNCTION_FAILED;
|
||||
goto kpgen_done;
|
||||
}
|
||||
|
||||
debug(context, "Doing key pair generation in software\n");
|
||||
rv = sc_pkcs11_gen_keypair_soft(keytype, keybits,
|
||||
&priv_args.key, &pub_args.key);
|
||||
if (rv != CKR_OK) {
|
||||
debug(context, "sc_pkcs11_gen_keypair_soft failed: 0x%0x\n", rv);
|
||||
goto kpgen_done;
|
||||
}
|
||||
|
||||
/* Write the new public and private keys to the pkcs15 files */
|
||||
rc = sc_pkcs15init_store_private_key(p15card, profile,
|
||||
&priv_args, &priv_key_obj);
|
||||
if (rc >= 0)
|
||||
rc = sc_pkcs15init_store_public_key(p15card, profile,
|
||||
&pub_args, &pub_key_obj);
|
||||
if (rc < 0) {
|
||||
debug(context, "private/public keys not stored: %d\n", rc);
|
||||
rv = sc_to_cryptoki_error(rc, p11card->reader);
|
||||
goto kpgen_done;
|
||||
}
|
||||
}
|
||||
|
||||
/* 4. Create new pkcs11 public and private key object */
|
||||
|
||||
rc = __pkcs15_create_prkey_object(fw_data, priv_key_obj);
|
||||
if (rc == 0)
|
||||
__pkcs15_create_pubkey_object(fw_data, pub_key_obj);
|
||||
if (rc != 0) {
|
||||
debug(context, "__pkcs15_create_pr/pubkey_object returned %d\n", rc);
|
||||
rv = sc_to_cryptoki_error(rc, p11card->reader);
|
||||
goto kpgen_done;
|
||||
}
|
||||
|
||||
id = ((sc_pkcs15_prkey_info *) priv_key_obj->data)->id;
|
||||
|
||||
rc = 0;
|
||||
for (j = 0; j < fw_data->num_objects; j++) {
|
||||
struct pkcs15_any_object *obj = fw_data->objects[j];
|
||||
|
||||
if (is_privkey(obj)) {
|
||||
struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object*) obj;
|
||||
if (sc_pkcs15_compare_id(&prkey->prv_info->id, &id)) {
|
||||
pkcs15_add_object(slot, obj, phPrivKey);
|
||||
rc++;
|
||||
}
|
||||
}
|
||||
if (is_pubkey(obj)) {
|
||||
struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) obj;
|
||||
if (sc_pkcs15_compare_id(&pubkey->pub_info->id, &id)) {
|
||||
pkcs15_add_object(slot, obj, phPubKey);
|
||||
rc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rc != 2) {
|
||||
debug(context, "Err: should have gotten 2 pkcs11 objects, got %d\n", rc);
|
||||
rv = CKR_GENERAL_ERROR;
|
||||
}
|
||||
|
||||
kpgen_done:
|
||||
sc_pkcs15init_unbind(profile);
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct sc_pkcs11_framework_ops framework_pkcs15 = {
|
||||
|
@ -1110,7 +1339,8 @@ struct sc_pkcs11_framework_ops framework_pkcs15 = {
|
|||
NULL, /* init_token */
|
||||
#ifdef USE_PKCS15_INIT
|
||||
pkcs15_init_pin,
|
||||
pkcs15_create_object
|
||||
pkcs15_create_object,
|
||||
pkcs15_gen_keypair,
|
||||
#else
|
||||
NULL,
|
||||
NULL
|
||||
|
@ -1831,7 +2061,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
|
|||
/* Register generic mechanisms */
|
||||
sc_pkcs11_register_generic_mechanisms(p11card);
|
||||
|
||||
mech_info.flags = CKF_HW | CKF_SIGN | CKF_UNWRAP;
|
||||
mech_info.flags = CKF_HW | CKF_SIGN | CKF_UNWRAP | CKF_GENERATE_KEY_PAIR;
|
||||
mech_info.ulMinKeySize = ~0;
|
||||
mech_info.ulMaxKeySize = 0;
|
||||
|
||||
|
|
|
@ -246,6 +246,19 @@ CK_RV attr_find(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
|
|||
return attr_extract(pTemplate, ptr, sizep);
|
||||
}
|
||||
|
||||
CK_RV attr_find2(CK_ATTRIBUTE_PTR pTemp1, CK_ULONG ulCount1,
|
||||
CK_ATTRIBUTE_PTR pTemp2, CK_ULONG ulCount2,
|
||||
CK_ULONG type, void *ptr, size_t *sizep)
|
||||
{
|
||||
CK_RV rv;
|
||||
|
||||
rv = attr_find(pTemp1, ulCount1, type, ptr, sizep);
|
||||
if (rv != CKR_OK)
|
||||
rv = attr_find(pTemp2, ulCount2, type, ptr, sizep);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV attr_find_ptr(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
|
||||
CK_ULONG type, void **ptr, size_t *sizep)
|
||||
{
|
||||
|
@ -291,6 +304,7 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, struct sc_context *ct
|
|||
conf->hide_empty_tokens = 0;
|
||||
conf->lock_login = 1;
|
||||
conf->cache_pins = 0;
|
||||
conf->soft_keygen_allowed = 1;
|
||||
|
||||
for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
|
||||
blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
|
||||
|
@ -308,4 +322,5 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, struct sc_context *ct
|
|||
conf->hide_empty_tokens = scconf_get_bool(conf_block, "hide_empty_tokens", 0);
|
||||
conf->lock_login = scconf_get_bool(conf_block, "lock_login", 1);
|
||||
conf->cache_pins = scconf_get_bool(conf_block, "cache_pins", 0);
|
||||
conf->soft_keygen_allowed = scconf_get_bool(conf_block, "soft_keygen_allowed", 1);
|
||||
}
|
||||
|
|
|
@ -170,4 +170,68 @@ sc_pkcs11_openssl_add_gen_rand(struct sc_pkcs11_session *session,
|
|||
return r == 1 ? CKR_OK : CKR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
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 = (u8 *) malloc(dst->len);
|
||||
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) {
|
||||
debug(context, "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)) {
|
||||
debug(context, "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)) {
|
||||
debug(context, "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;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -762,7 +762,30 @@ CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession, /* the
|
|||
CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */
|
||||
CK_OBJECT_HANDLE_PTR phPrivateKey) /* gets priv. key handle */
|
||||
{
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
struct sc_pkcs11_session *session;
|
||||
struct sc_pkcs11_slot *slot;
|
||||
int rv;
|
||||
|
||||
rv = sc_pkcs11_lock();
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
goto out;
|
||||
|
||||
slot = session->slot;
|
||||
if (slot->card->framework->gen_keypair == NULL) {
|
||||
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
} else {
|
||||
rv = slot->card->framework->gen_keypair(slot->card, slot,
|
||||
pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount,
|
||||
pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
|
||||
phPublicKey, phPrivateKey);
|
||||
}
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_WrapKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
|
|
|
@ -84,6 +84,7 @@ struct sc_pkcs11_config {
|
|||
unsigned char hide_empty_tokens;
|
||||
unsigned char lock_login;
|
||||
unsigned char cache_pins;
|
||||
unsigned char soft_keygen_allowed;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -159,6 +160,12 @@ struct sc_pkcs11_framework_ops {
|
|||
struct sc_pkcs11_slot *,
|
||||
CK_ATTRIBUTE_PTR, CK_ULONG,
|
||||
CK_OBJECT_HANDLE_PTR);
|
||||
CK_RV (*gen_keypair)(struct sc_pkcs11_card *p11card,
|
||||
struct sc_pkcs11_slot *slot,
|
||||
CK_MECHANISM_PTR pMechanism,
|
||||
CK_ATTRIBUTE_PTR pPubKeyTempl, CK_ULONG ulPubKeyAttrCnt,
|
||||
CK_ATTRIBUTE_PTR pPrivKeyTempl, CK_ULONG ulPrivKeyAttrCnt,
|
||||
CK_OBJECT_HANDLE_PTR phPubKey, CK_OBJECT_HANDLE_PTR phPrivKey);
|
||||
};
|
||||
|
||||
|
||||
|
@ -343,6 +350,8 @@ int sc_pkcs11_any_cmp_attribute(struct sc_pkcs11_session *,
|
|||
|
||||
/* Get attributes from template (misc.c) */
|
||||
CK_RV attr_find(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ULONG, void *, size_t *);
|
||||
CK_RV attr_find2(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG,
|
||||
CK_ULONG, void *, size_t *);
|
||||
CK_RV attr_find_ptr(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ULONG, void **, size_t *);
|
||||
CK_RV attr_find_var(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ULONG, void *, size_t *);
|
||||
CK_RV attr_extract(CK_ATTRIBUTE_PTR, void *, size_t *);
|
||||
|
@ -384,6 +393,8 @@ CK_RV sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *,
|
|||
/* Random generation functions */
|
||||
CK_RV sc_pkcs11_openssl_add_seed_rand(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG);
|
||||
CK_RV sc_pkcs11_openssl_add_gen_rand(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG);
|
||||
CK_RV sc_pkcs11_gen_keypair_soft(CK_KEY_TYPE keytype, CK_ULONG keybits,
|
||||
struct sc_pkcs15_prkey *privkey, struct sc_pkcs15_pubkey *pubkey);
|
||||
#endif
|
||||
|
||||
/* Load configuration defaults */
|
||||
|
|
|
@ -820,6 +820,7 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card,
|
|||
struct sc_pkcs15_pubkey_info *key_info;
|
||||
sc_pkcs15_pubkey_t key;
|
||||
sc_pkcs15_der_t der_encoded;
|
||||
sc_path_t *path;
|
||||
const char *label;
|
||||
unsigned int keybits, type, usage;
|
||||
int r;
|
||||
|
@ -875,6 +876,12 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card,
|
|||
r = sc_pkcs15init_store_data(p15card, profile,
|
||||
type, &der_encoded, &key_info->path);
|
||||
|
||||
path = &((sc_pkcs15_pubkey_info *) object->data)->path;
|
||||
if (path->count == 0) {
|
||||
path->index = 0;
|
||||
path->count = -1;
|
||||
}
|
||||
|
||||
/* Update the PuKDF */
|
||||
if (r >= 0)
|
||||
r = sc_pkcs15init_add_object(p15card, profile,
|
||||
|
@ -1059,6 +1066,10 @@ sc_pkcs15init_store_data(struct sc_pkcs15_card *p15card,
|
|||
p15init_error("Unable to allocate file");
|
||||
goto done;
|
||||
}
|
||||
if (file->path.count == 0) {
|
||||
file->path.index = 0;
|
||||
file->path.count = -1;
|
||||
}
|
||||
r = sc_pkcs15init_update_file(profile, p15card->card,
|
||||
file, data->value, data->len);
|
||||
*path = file->path;
|
||||
|
|
|
@ -56,6 +56,7 @@ const struct option options[] = {
|
|||
{ "login", 0, 0, 'l' },
|
||||
{ "pin", 1, 0, 'p' },
|
||||
{ "change-pin", 0, 0, 'c' },
|
||||
{ "keypairgen", 0, 0, 'k' },
|
||||
{ "slot", 1, 0, OPT_SLOT },
|
||||
{ "slot-label", 1, 0, OPT_SLOT_LABEL },
|
||||
{ "input-file", 1, 0, 'i' },
|
||||
|
@ -80,6 +81,7 @@ const char *option_help[] = {
|
|||
"Log into the token first (not needed when using --pin)",
|
||||
"Supply PIN on the command line (if used in scripts: careful!)",
|
||||
"Change your (user) PIN",
|
||||
"Key pair generation",
|
||||
"Specify number of the slot to use",
|
||||
"Specify label of the slot to use",
|
||||
"Specify the input file",
|
||||
|
@ -127,6 +129,7 @@ static void show_cert(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
|
|||
static void sign_data(CK_SLOT_ID,
|
||||
CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
|
||||
static void hash_data(CK_SLOT_ID, CK_SESSION_HANDLE);
|
||||
static void gen_keypair(CK_SLOT_ID, CK_SESSION_HANDLE);
|
||||
static int find_object(CK_SESSION_HANDLE, CK_OBJECT_CLASS,
|
||||
CK_OBJECT_HANDLE_PTR,
|
||||
const unsigned char *, size_t id_len, int obj_index);
|
||||
|
@ -165,6 +168,7 @@ main(int argc, char * const argv[])
|
|||
int do_list_objects = 0;
|
||||
int do_sign = 0;
|
||||
int do_hash = 0;
|
||||
int do_gen_keypair = 0;
|
||||
int do_test = 0;
|
||||
int need_session = 0;
|
||||
int opt_login = 0;
|
||||
|
@ -173,7 +177,7 @@ main(int argc, char * const argv[])
|
|||
CK_RV rv;
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "ILMOhi:lm:o:p:scqt",
|
||||
c = getopt_long(argc, argv, "ILMOghi:lm:o:p:scqt",
|
||||
options, &long_optind);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
@ -200,6 +204,11 @@ main(int argc, char * const argv[])
|
|||
do_hash = 1;
|
||||
action_count++;
|
||||
break;
|
||||
case 'g':
|
||||
need_session |= NEED_SESSION_RW;
|
||||
do_gen_keypair = 1;
|
||||
action_count++;
|
||||
break;
|
||||
case 'i':
|
||||
opt_input = optarg;
|
||||
break;
|
||||
|
@ -380,6 +389,9 @@ skip_login:
|
|||
if (do_hash)
|
||||
hash_data(opt_slot, session);
|
||||
|
||||
if (do_gen_keypair)
|
||||
gen_keypair(opt_slot, session);
|
||||
|
||||
if (do_test)
|
||||
p11_test(opt_slot, session);
|
||||
|
||||
|
@ -687,6 +699,43 @@ hash_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
|
|||
close(fd);
|
||||
}
|
||||
|
||||
void
|
||||
gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
|
||||
{
|
||||
CK_SESSION_HANDLE hSession;
|
||||
CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
|
||||
CK_MECHANISM mechanism = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
|
||||
CK_ULONG modulusBits = 768;
|
||||
CK_BYTE publicExponent[] = { 3 };
|
||||
CK_BBOOL true = TRUE;
|
||||
CK_ATTRIBUTE publicKeyTemplate[] = {
|
||||
{CKA_ENCRYPT, &true, sizeof(true)},
|
||||
{CKA_VERIFY, &true, sizeof(true)},
|
||||
{CKA_WRAP, &true, sizeof(true)},
|
||||
{CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
|
||||
{CKA_PUBLIC_EXPONENT, publicExponent, sizeof
|
||||
(publicExponent)}
|
||||
};
|
||||
CK_ATTRIBUTE privateKeyTemplate[] = {
|
||||
{CKA_TOKEN, &true, sizeof(true)},
|
||||
{CKA_PRIVATE, &true, sizeof(true)},
|
||||
{CKA_SENSITIVE, &true, sizeof(true)},
|
||||
{CKA_DECRYPT, &true, sizeof(true)},
|
||||
{CKA_SIGN, &true, sizeof(true)},
|
||||
{CKA_UNWRAP, &true, sizeof(true)}
|
||||
};
|
||||
CK_RV rv;
|
||||
|
||||
rv = p11->C_GenerateKeyPair(session, &mechanism,
|
||||
publicKeyTemplate, 5, privateKeyTemplate, 6, &hPublicKey, &hPrivateKey);
|
||||
if (rv != CKR_OK)
|
||||
p11_fatal("C_GenerateKeyPair", rv);
|
||||
|
||||
printf("Key pair generated:\n");
|
||||
show_object(session, hPrivateKey);
|
||||
show_object(session, hPublicKey);
|
||||
}
|
||||
|
||||
CK_SLOT_ID
|
||||
find_slot_by_label(const char *label)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue