@@ -33,8 +33,8 @@ static int rsa_ex_index = 0;
3333static RSA_METHOD * pkcs11_rsa_method = NULL ;
3434
3535#if OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_VERSION_NUMBER < 0x40000000L && !defined(OPENSSL_NO_ENGINE )
36- static EVP_PKEY_METHOD * pkey_method_rsa = NULL ;
3736static ENGINE * pkey_engine_rsa = NULL ;
37+ static int pkey_engine_rsa_ex_index = -1 ;
3838#endif /* OpenSSL 3.x with ENGINE support */
3939
4040static RSA * pkcs11_get1_rsa (PKCS11_OBJECT_private * key )
@@ -247,14 +247,13 @@ static int pkcs11_pkey_engine_meths(ENGINE *engine,
247247{
248248 static int pkey_nids [] = { EVP_PKEY_RSA , 0 };
249249
250- (void )engine ;
251250 if (!pmeth ) {
252251 * nids = pkey_nids ;
253252 return 1 ;
254253 }
255254 if (nid == EVP_PKEY_RSA ) {
256- * pmeth = pkey_method_rsa ;
257- return 1 ;
255+ * pmeth = ENGINE_get_ex_data ( engine , pkey_engine_rsa_ex_index ) ;
256+ return * pmeth != NULL ;
258257 }
259258 * pmeth = NULL ;
260259 return 0 ;
@@ -263,24 +262,34 @@ static int pkcs11_pkey_engine_meths(ENGINE *engine,
263262/* Initialize an ENGINE that selects the RSA method only for libp11 keys. */
264263static int pkcs11_pkey_method_rsa_new (void )
265264{
265+ EVP_PKEY_METHOD * pkey_method_rsa ;
266+ ENGINE * engine ;
267+
266268 if (pkey_engine_rsa )
267269 return 1 ;
268270
269271 pkey_method_rsa = pkcs11_pkey_method_rsa ();
270272 if (!pkey_method_rsa )
271273 return 0 ;
272- pkey_engine_rsa = ENGINE_new ();
273- if (!pkey_engine_rsa ||
274- !ENGINE_set_id (pkey_engine_rsa , "libp11-rsa-key" ) ||
275- !ENGINE_set_name (pkey_engine_rsa , "libp11 RSA key method" ) ||
276- !ENGINE_set_pkey_meths (pkey_engine_rsa ,
277- pkcs11_pkey_engine_meths )) {
278- ENGINE_free (pkey_engine_rsa );
279- pkey_engine_rsa = NULL ;
274+ if (pkey_engine_rsa_ex_index < 0 )
275+ pkey_engine_rsa_ex_index = ENGINE_get_ex_new_index (0 ,
276+ "libp11 RSA EVP_PKEY_METHOD" , NULL , NULL , NULL );
277+ engine = ENGINE_new ();
278+ if (pkey_engine_rsa_ex_index < 0 || !engine ||
279+ !ENGINE_set_id (engine , "libp11-rsa-key" ) ||
280+ !ENGINE_set_name (engine , "libp11 RSA key method" ) ||
281+ !ENGINE_set_ex_data (engine , pkey_engine_rsa_ex_index ,
282+ pkey_method_rsa )) {
283+ ENGINE_free (engine );
284+ EVP_PKEY_meth_free (pkey_method_rsa );
285+ return 0 ;
286+ }
287+ if (!ENGINE_set_pkey_meths (engine , pkcs11_pkey_engine_meths )) {
288+ ENGINE_free (engine );
280289 EVP_PKEY_meth_free (pkey_method_rsa );
281- pkey_method_rsa = NULL ;
282290 return 0 ;
283291 }
292+ pkey_engine_rsa = engine ;
284293 return 1 ;
285294}
286295#endif /* OPENSSL_NO_ENGINE */
@@ -301,11 +310,12 @@ void pkcs11_rsa_key_method_free(void)
301310{
302311#ifndef OPENSSL_NO_ENGINE
303312 if (pkey_engine_rsa ) {
313+ /* OpenSSL frees the method returned by the callback when the
314+ * ENGINE's final structural reference is released. Keep the method
315+ * in ENGINE ex_data so it remains available if keys still hold refs. */
304316 ENGINE_free (pkey_engine_rsa );
305317 pkey_engine_rsa = NULL ;
306318 }
307- /* ENGINE_free() releases the methods cached by the ENGINE. */
308- pkey_method_rsa = NULL ;
309319#endif /* OPENSSL_NO_ENGINE */
310320}
311321
0 commit comments