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:
sth 2003-06-03 13:57:52 +00:00
parent 7fe0ba8749
commit c8c2cf725b
8 changed files with 416 additions and 7 deletions

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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)
{