Skip to content

Commit

Permalink
Add PKCS11_generate_ec_key() for private EC key generation
Browse files Browse the repository at this point in the history
Signed-off-by: Vesa Jääskeläinen <[email protected]>
  • Loading branch information
vesajaaskelainen committed Dec 15, 2020
1 parent d03aa89 commit 350d6a1
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/libp11-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,10 @@ extern int pkcs11_generate_key(PKCS11_TOKEN * token,
int algorithm, unsigned int bits,
char *label, unsigned char* id, size_t id_len);

/* Generate and store a private EC key on the token */
extern int pkcs11_generate_ec_key(PKCS11_TOKEN * token, const char *curve,
char *label, unsigned char* id, size_t id_len);

/* Get the RSA key modulus size (in bytes) */
extern int pkcs11_get_key_size(PKCS11_KEY *);

Expand Down
1 change: 1 addition & 0 deletions src/libp11.exports
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ PKCS11_init_token
PKCS11_init_pin
PKCS11_change_pin
PKCS11_generate_key
PKCS11_generate_ec_key
PKCS11_store_private_key
PKCS11_store_public_key
PKCS11_store_certificate
Expand Down
14 changes: 14 additions & 0 deletions src/libp11.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,20 @@ P11_DEPRECATED_FUNC extern int PKCS11_get_key_modulus(PKCS11_KEY *, BIGNUM **);
/* Get the RSA key public exponent as BIGNUM */
P11_DEPRECATED_FUNC extern int PKCS11_get_key_exponent(PKCS11_KEY *, BIGNUM **);

/**
* Generate a private EC key on the token
*
* @param token token returned by PKCS11_find_token()
* @param curve EC curve name
* @param label label for this key
* @param id bytes to use as the id value
* @param id_len length of the id value
* @retval 0 success
* @retval -1 error
*/
extern int PKCS11_generate_ec_key(PKCS11_TOKEN *token, const char *curve,
char *label, unsigned char* id, size_t id_len);

/* Sign with the EC private key */
P11_DEPRECATED_FUNC extern int PKCS11_ecdsa_sign(
const unsigned char *m, unsigned int m_len,
Expand Down
8 changes: 8 additions & 0 deletions src/p11_front.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,14 @@ int PKCS11_generate_key(PKCS11_TOKEN *token,
return pkcs11_generate_key(token, algorithm, bits, label, id, id_len);
}

int PKCS11_generate_ec_key(PKCS11_TOKEN *token, const char *curve,
char *label, unsigned char *id, size_t id_len)
{
if (check_token_fork(token) < 0)
return -1;
return pkcs11_generate_ec_key(token, curve, label, id, id_len);
}

int PKCS11_get_key_size(PKCS11_KEY *key)
{
if (check_key_fork(key) < 0)
Expand Down
92 changes: 92 additions & 0 deletions src/p11_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,98 @@ int pkcs11_generate_key(PKCS11_TOKEN *token, int algorithm, unsigned int bits,
return 0;
}

/**
* Generate a keyPair directly on token
*/
int pkcs11_generate_ec_key(PKCS11_TOKEN *token, const char *curve,
char *label, unsigned char* id, size_t id_len) {

PKCS11_SLOT *slot = TOKEN2SLOT(token);
PKCS11_CTX *ctx = TOKEN2CTX(token);
PKCS11_SLOT_private *spriv = PRIVSLOT(slot);

CK_ATTRIBUTE pubkey_attrs[32];
CK_ATTRIBUTE privkey_attrs[32];
unsigned int n_pub = 0, n_priv = 0;
CK_MECHANISM mechanism = {
CKM_EC_KEY_PAIR_GEN, NULL_PTR, 0
};
CK_OBJECT_HANDLE pub_key_obj, priv_key_obj;
int rv;

unsigned char *ecdsa_params = NULL;
int ecdsa_params_len = 0;
unsigned char *tmp = NULL;
ASN1_OBJECT *curve_obj = NULL;
int curve_nid = NID_undef;

/* make sure we have a session */
if (!spriv->haveSession && PKCS11_open_session(slot, 1))
return -1;

curve_nid = EC_curve_nist2nid(curve);
if (curve_nid == NID_undef)
curve_nid = OBJ_sn2nid(curve);
if (curve_nid == NID_undef)
curve_nid = OBJ_ln2nid(curve);
if (curve_nid == NID_undef)
return -1;

curve_obj = OBJ_nid2obj(curve_nid);
if (!curve_obj)
return -1;
ecdsa_params_len = i2d_ASN1_OBJECT(curve_obj, NULL);
ecdsa_params = (unsigned char *)OPENSSL_malloc(ecdsa_params_len);
if (!ecdsa_params)
return -1;
tmp = ecdsa_params;
i2d_ASN1_OBJECT(curve_obj, &tmp);

/* pubkey attributes */
pkcs11_addattr(pubkey_attrs + n_pub++, CKA_ID, id, id_len);
if (label)
pkcs11_addattr_s(pubkey_attrs + n_pub++, CKA_LABEL, label);
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_TOKEN, TRUE);
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_DERIVE, TRUE);
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_WRAP, FALSE);
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_VERIFY, TRUE);
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_VERIFY_RECOVER, FALSE);
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_ENCRYPT, FALSE);
pkcs11_addattr(pubkey_attrs + n_pub++, CKA_ECDSA_PARAMS, ecdsa_params, ecdsa_params_len);

/* privkey attributes */
pkcs11_addattr(privkey_attrs + n_priv++, CKA_ID, id, id_len);
if (label)
pkcs11_addattr_s(privkey_attrs + n_priv++, CKA_LABEL, label);
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_TOKEN, TRUE);
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_PRIVATE, TRUE);
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_SENSITIVE, TRUE);
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_DERIVE, TRUE);
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_UNWRAP, FALSE);
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_SIGN, TRUE);
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_DECRYPT, FALSE);

/* call the pkcs11 module to create the key pair */
rv = CRYPTOKI_call(ctx, C_GenerateKeyPair(
spriv->session,
&mechanism,
pubkey_attrs,
n_pub,
privkey_attrs,
n_priv,
&pub_key_obj,
&priv_key_obj
));

/* zap all memory allocated when building the template */
pkcs11_zap_attrs(privkey_attrs, n_priv);
pkcs11_zap_attrs(pubkey_attrs, n_pub);
OPENSSL_free(ecdsa_params);

CRYPTOKI_checkerr(CKR_F_PKCS11_GENERATE_KEY, rv);
return 0;
}

/*
* Store a private key on the token
*/
Expand Down

0 comments on commit 350d6a1

Please sign in to comment.