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