@@ -471,13 +471,14 @@ static const struct pkey_from_data_alias fcc_aliases[] = {
471471};
472472
473473struct pkey_from_data_arg {
474+ VALUE options ;
474475 OSSL_PARAM_BLD * param_bld ;
475476 const OSSL_PARAM * settable_params ;
476477 const struct pkey_from_data_alias * aliases ;
477478};
478479
479480static int
480- add_parameter_to_builder (VALUE key , VALUE value , VALUE arg ) {
481+ add_data_to_builder (VALUE key , VALUE value , VALUE arg ) {
481482 if (NIL_P (value ))
482483 return ST_CONTINUE ;
483484
@@ -500,55 +501,53 @@ add_parameter_to_builder(VALUE key, VALUE value, VALUE arg) {
500501 case OSSL_PARAM_INTEGER :
501502 case OSSL_PARAM_UNSIGNED_INTEGER :
502503 if (!OSSL_PARAM_BLD_push_BN (params -> param_bld , key_ptr , GetBNPtr (value ))) {
503- OSSL_PARAM_BLD_free (params -> param_bld );
504504 ossl_raise (ePKeyError , "OSSL_PARAM_BLD_push_BN" );
505505 }
506506 break ;
507507 case OSSL_PARAM_UTF8_STRING :
508508 StringValue (value );
509509 if (!OSSL_PARAM_BLD_push_utf8_string (params -> param_bld , key_ptr , RSTRING_PTR (value ), RSTRING_LENINT (value ))) {
510- OSSL_PARAM_BLD_free (params -> param_bld );
511510 ossl_raise (ePKeyError , "OSSL_PARAM_BLD_push_utf8_string" );
512511 }
513512 break ;
514513
515514 case OSSL_PARAM_OCTET_STRING :
516515 StringValue (value );
517516 if (!OSSL_PARAM_BLD_push_octet_string (params -> param_bld , key_ptr , RSTRING_PTR (value ), RSTRING_LENINT (value ))) {
518- OSSL_PARAM_BLD_free (params -> param_bld );
519517 ossl_raise (ePKeyError , "OSSL_PARAM_BLD_push_octet_string" );
520518 }
521519 break ;
522520 case OSSL_PARAM_UTF8_PTR :
523521 case OSSL_PARAM_OCTET_PTR :
524- OSSL_PARAM_BLD_free (params -> param_bld );
525522 ossl_raise (ePKeyError , "Unsupported parameter \"%s\", handling of OSSL_PARAM_UTF8_PTR and OSSL_PARAM_OCTET_PTR not implemented" , key_ptr );
526523 break ;
527524 }
528525
529526 return ST_CONTINUE ;
530527 }
531528 }
532- OSSL_PARAM_BLD_free (params -> param_bld );
533529
534- char message_buffer [512 ] = { 0 };
535- char * cur = message_buffer ;
536- char * end = message_buffer + sizeof (message_buffer );
530+ VALUE supported_parameters = rb_ary_new ();
531+
537532 for (const OSSL_PARAM * settable_params = params -> settable_params ; settable_params -> key != NULL ; settable_params ++ ) {
538- const char * fmt = cur == message_buffer ? "%s" : ", %s" ;
539- if (cur > end )
540- break ;
541- cur += snprintf (cur , end - cur , fmt , settable_params -> key );
533+ rb_ary_push (supported_parameters , rb_str_new_cstr (settable_params -> key ));
542534 }
543535
544536 for (int i = 0 ; strlen (params -> aliases [i ].alias ) > 0 ; i ++ ) {
545- const char * fmt = cur == message_buffer ? "%s" : ", %s" ;
546- if (cur > end )
547- break ;
548- cur += snprintf (cur , end - cur , fmt , params -> aliases [i ].alias );
537+ rb_ary_push (supported_parameters , rb_str_new_cstr (params -> aliases [i ].alias ));
549538 }
550539
551- ossl_raise (ePKeyError , "Invalid parameter \"%s\". Supported parameters: \"%s\"" , key_ptr , message_buffer );
540+ ossl_raise (ePKeyError , "Invalid parameter \"%s\". Supported parameters: %" PRIsVALUE , key_ptr , rb_ary_join (supported_parameters , rb_str_new2 (", " )));
541+ }
542+
543+ static VALUE
544+ add_data_to_builder_protected (VALUE value )
545+ {
546+ struct pkey_from_data_arg * args = (void * )value ;
547+
548+ rb_hash_foreach (args -> options , & add_data_to_builder , (VALUE ) args );
549+
550+ return Qnil ;
552551}
553552
554553static VALUE
@@ -567,6 +566,7 @@ pkey_from_data(int argc, VALUE *argv, VALUE self)
567566 struct pkey_from_data_arg from_data_args = { 0 };
568567
569568 from_data_args .param_bld = OSSL_PARAM_BLD_new ();
569+ from_data_args .options = options ;
570570
571571 if (from_data_args .param_bld == NULL ) {
572572 EVP_PKEY_CTX_free (ctx );
@@ -577,6 +577,7 @@ pkey_from_data(int argc, VALUE *argv, VALUE self)
577577
578578 if (from_data_args .settable_params == NULL ) {
579579 EVP_PKEY_CTX_free (ctx );
580+ OSSL_PARAM_BLD_free (from_data_args .param_bld );
580581 ossl_raise (ePKeyError , "EVP_PKEY_fromdata_settable" );
581582 }
582583
@@ -585,7 +586,14 @@ pkey_from_data(int argc, VALUE *argv, VALUE self)
585586 else
586587 from_data_args .aliases = fcc_aliases ;
587588
588- rb_hash_foreach (options , & add_parameter_to_builder , (VALUE ) & from_data_args );
589+ int state ;
590+ rb_protect (add_data_to_builder_protected , (VALUE ) & from_data_args , & state );
591+
592+ if (state ) {
593+ EVP_PKEY_CTX_free (ctx );
594+ OSSL_PARAM_BLD_free (from_data_args .param_bld );
595+ rb_jump_tag (state );
596+ }
589597
590598 OSSL_PARAM * params = OSSL_PARAM_BLD_to_param (from_data_args .param_bld );
591599 OSSL_PARAM_BLD_free (from_data_args .param_bld );
@@ -612,6 +620,7 @@ pkey_from_data(int argc, VALUE *argv, VALUE self)
612620
613621 return ossl_pkey_new (pkey );
614622}
623+
615624#endif
616625
617626/*
@@ -686,11 +695,11 @@ ossl_pkey_s_generate_key(int argc, VALUE *argv, VALUE self)
686695static VALUE
687696ossl_pkey_s_from_data (int argc , VALUE * argv , VALUE self )
688697{
689- #if OSSL_OPENSSL_PREREQ (3 , 0 , 0 )
698+ #if OSSL_OPENSSL_PREREQ (3 , 0 , 0 )
690699 return pkey_from_data (argc , argv , self );
691- #else
700+ #else
692701 rb_raise (ePKeyError , "OpenSSL::PKey.from_data requires OpenSSL 3.0 or later" );
693- #endif
702+ #endif
694703}
695704
696705/*
0 commit comments