Skip to content

Commit 350d6a1

Browse files
Add PKCS11_generate_ec_key() for private EC key generation
Signed-off-by: Vesa Jääskeläinen <vesa.jaaskelainen@vaisala.com>
1 parent d03aa89 commit 350d6a1

File tree

5 files changed

+119
-0
lines changed

5 files changed

+119
-0
lines changed

src/libp11-int.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ extern int pkcs11_generate_key(PKCS11_TOKEN * token,
336336
int algorithm, unsigned int bits,
337337
char *label, unsigned char* id, size_t id_len);
338338

339+
/* Generate and store a private EC key on the token */
340+
extern int pkcs11_generate_ec_key(PKCS11_TOKEN * token, const char *curve,
341+
char *label, unsigned char* id, size_t id_len);
342+
339343
/* Get the RSA key modulus size (in bytes) */
340344
extern int pkcs11_get_key_size(PKCS11_KEY *);
341345

src/libp11.exports

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ PKCS11_init_token
2929
PKCS11_init_pin
3030
PKCS11_change_pin
3131
PKCS11_generate_key
32+
PKCS11_generate_ec_key
3233
PKCS11_store_private_key
3334
PKCS11_store_public_key
3435
PKCS11_store_certificate

src/libp11.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,20 @@ P11_DEPRECATED_FUNC extern int PKCS11_get_key_modulus(PKCS11_KEY *, BIGNUM **);
452452
/* Get the RSA key public exponent as BIGNUM */
453453
P11_DEPRECATED_FUNC extern int PKCS11_get_key_exponent(PKCS11_KEY *, BIGNUM **);
454454

455+
/**
456+
* Generate a private EC key on the token
457+
*
458+
* @param token token returned by PKCS11_find_token()
459+
* @param curve EC curve name
460+
* @param label label for this key
461+
* @param id bytes to use as the id value
462+
* @param id_len length of the id value
463+
* @retval 0 success
464+
* @retval -1 error
465+
*/
466+
extern int PKCS11_generate_ec_key(PKCS11_TOKEN *token, const char *curve,
467+
char *label, unsigned char* id, size_t id_len);
468+
455469
/* Sign with the EC private key */
456470
P11_DEPRECATED_FUNC extern int PKCS11_ecdsa_sign(
457471
const unsigned char *m, unsigned int m_len,

src/p11_front.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,14 @@ int PKCS11_generate_key(PKCS11_TOKEN *token,
290290
return pkcs11_generate_key(token, algorithm, bits, label, id, id_len);
291291
}
292292

293+
int PKCS11_generate_ec_key(PKCS11_TOKEN *token, const char *curve,
294+
char *label, unsigned char *id, size_t id_len)
295+
{
296+
if (check_token_fork(token) < 0)
297+
return -1;
298+
return pkcs11_generate_ec_key(token, curve, label, id, id_len);
299+
}
300+
293301
int PKCS11_get_key_size(PKCS11_KEY *key)
294302
{
295303
if (check_key_fork(key) < 0)

src/p11_key.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,98 @@ int pkcs11_generate_key(PKCS11_TOKEN *token, int algorithm, unsigned int bits,
194194
return 0;
195195
}
196196

197+
/**
198+
* Generate a keyPair directly on token
199+
*/
200+
int pkcs11_generate_ec_key(PKCS11_TOKEN *token, const char *curve,
201+
char *label, unsigned char* id, size_t id_len) {
202+
203+
PKCS11_SLOT *slot = TOKEN2SLOT(token);
204+
PKCS11_CTX *ctx = TOKEN2CTX(token);
205+
PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
206+
207+
CK_ATTRIBUTE pubkey_attrs[32];
208+
CK_ATTRIBUTE privkey_attrs[32];
209+
unsigned int n_pub = 0, n_priv = 0;
210+
CK_MECHANISM mechanism = {
211+
CKM_EC_KEY_PAIR_GEN, NULL_PTR, 0
212+
};
213+
CK_OBJECT_HANDLE pub_key_obj, priv_key_obj;
214+
int rv;
215+
216+
unsigned char *ecdsa_params = NULL;
217+
int ecdsa_params_len = 0;
218+
unsigned char *tmp = NULL;
219+
ASN1_OBJECT *curve_obj = NULL;
220+
int curve_nid = NID_undef;
221+
222+
/* make sure we have a session */
223+
if (!spriv->haveSession && PKCS11_open_session(slot, 1))
224+
return -1;
225+
226+
curve_nid = EC_curve_nist2nid(curve);
227+
if (curve_nid == NID_undef)
228+
curve_nid = OBJ_sn2nid(curve);
229+
if (curve_nid == NID_undef)
230+
curve_nid = OBJ_ln2nid(curve);
231+
if (curve_nid == NID_undef)
232+
return -1;
233+
234+
curve_obj = OBJ_nid2obj(curve_nid);
235+
if (!curve_obj)
236+
return -1;
237+
ecdsa_params_len = i2d_ASN1_OBJECT(curve_obj, NULL);
238+
ecdsa_params = (unsigned char *)OPENSSL_malloc(ecdsa_params_len);
239+
if (!ecdsa_params)
240+
return -1;
241+
tmp = ecdsa_params;
242+
i2d_ASN1_OBJECT(curve_obj, &tmp);
243+
244+
/* pubkey attributes */
245+
pkcs11_addattr(pubkey_attrs + n_pub++, CKA_ID, id, id_len);
246+
if (label)
247+
pkcs11_addattr_s(pubkey_attrs + n_pub++, CKA_LABEL, label);
248+
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_TOKEN, TRUE);
249+
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_DERIVE, TRUE);
250+
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_WRAP, FALSE);
251+
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_VERIFY, TRUE);
252+
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_VERIFY_RECOVER, FALSE);
253+
pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_ENCRYPT, FALSE);
254+
pkcs11_addattr(pubkey_attrs + n_pub++, CKA_ECDSA_PARAMS, ecdsa_params, ecdsa_params_len);
255+
256+
/* privkey attributes */
257+
pkcs11_addattr(privkey_attrs + n_priv++, CKA_ID, id, id_len);
258+
if (label)
259+
pkcs11_addattr_s(privkey_attrs + n_priv++, CKA_LABEL, label);
260+
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_TOKEN, TRUE);
261+
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_PRIVATE, TRUE);
262+
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_SENSITIVE, TRUE);
263+
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_DERIVE, TRUE);
264+
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_UNWRAP, FALSE);
265+
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_SIGN, TRUE);
266+
pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_DECRYPT, FALSE);
267+
268+
/* call the pkcs11 module to create the key pair */
269+
rv = CRYPTOKI_call(ctx, C_GenerateKeyPair(
270+
spriv->session,
271+
&mechanism,
272+
pubkey_attrs,
273+
n_pub,
274+
privkey_attrs,
275+
n_priv,
276+
&pub_key_obj,
277+
&priv_key_obj
278+
));
279+
280+
/* zap all memory allocated when building the template */
281+
pkcs11_zap_attrs(privkey_attrs, n_priv);
282+
pkcs11_zap_attrs(pubkey_attrs, n_pub);
283+
OPENSSL_free(ecdsa_params);
284+
285+
CRYPTOKI_checkerr(CKR_F_PKCS11_GENERATE_KEY, rv);
286+
return 0;
287+
}
288+
197289
/*
198290
* Store a private key on the token
199291
*/

0 commit comments

Comments
 (0)