@@ -217,6 +217,114 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
217217 return (int )len ;
218218}
219219
220+ #ifdef OSSL_PARAM_INTEGER
221+ #include <openssl/param_build.h>
222+
223+ struct build_params_args {
224+ const OSSL_PARAM * settable ;
225+ VALUE hash ;
226+ OSSL_PARAM_BLD * bld ;
227+ };
228+
229+ static VALUE
230+ build_params_i (RB_BLOCK_CALL_FUNC_ARGLIST (i , memo ))
231+ {
232+ struct build_params_args * args = (struct build_params_args * )memo ;
233+ VALUE keyv = rb_ary_entry (i , 0 ), obj = rb_ary_entry (i , 1 );
234+ OSSL_PARAM_BLD * bld = args -> bld ;
235+
236+ if (SYMBOL_P (keyv ))
237+ keyv = rb_sym2str (keyv );
238+
239+ const OSSL_PARAM * p = args -> settable ;
240+ const char * key = StringValueCStr (keyv );
241+ while (p -> key && strcmp (p -> key , key ))
242+ p ++ ;
243+ if (!p -> key )
244+ rb_raise (rb_eArgError , "unknown OSSL_PARAM key '%" PRIsVALUE "'" , keyv );
245+
246+ switch (p -> data_type ) {
247+ case OSSL_PARAM_INTEGER :
248+ case OSSL_PARAM_UNSIGNED_INTEGER :
249+ obj = ossl_try_convert_to_bn (obj );
250+ if (NIL_P (obj ))
251+ rb_raise (rb_eArgError , "OSSL_PARAM key '%s' requires " \
252+ "integer value" , p -> key );
253+ const BIGNUM * bn = GetBNPtr (obj );
254+ if (p -> data_type == OSSL_PARAM_UNSIGNED_INTEGER && BN_is_negative (bn ))
255+ rb_raise (rb_eArgError , "OSSL_PARAM key '%s' requires " \
256+ "non-negative integer value" , p -> key );
257+ if (!OSSL_PARAM_BLD_push_BN (bld , p -> key , GetBNPtr (obj )))
258+ ossl_raise (eOSSLError , "OSSL_PARAM_BLD_push_BN" );
259+ break ;
260+ case OSSL_PARAM_REAL :
261+ obj = rb_check_to_float (obj );
262+ if (NIL_P (obj ))
263+ rb_raise (rb_eArgError , "OSSL_PARAM key '%s' requires Float value" ,
264+ p -> key );
265+ if (!OSSL_PARAM_BLD_push_double (bld , p -> key , NUM2DBL (obj )))
266+ ossl_raise (eOSSLError , "OSSL_PARAM_BLD_push_double" );
267+ break ;
268+ case OSSL_PARAM_UTF8_STRING :
269+ obj = rb_check_string_type (obj );
270+ if (NIL_P (obj ))
271+ rb_raise (rb_eArgError , "OSSL_PARAM key '%s' requires " \
272+ "NUL-terminated String value" , p -> key );
273+ StringValueCStr (obj );
274+ if (!OSSL_PARAM_BLD_push_utf8_string (bld , p -> key , RSTRING_PTR (obj ),
275+ RSTRING_LEN (obj )))
276+ ossl_raise (eOSSLError , "OSSL_PARAM_BLD_push_utf8_string" );
277+ break ;
278+ case OSSL_PARAM_OCTET_STRING :
279+ obj = rb_check_string_type (obj );
280+ if (NIL_P (obj ))
281+ rb_raise (rb_eArgError , "OSSL_PARAM key '%s' requires String value" ,
282+ p -> key );
283+ if (!OSSL_PARAM_BLD_push_octet_string (bld , p -> key , RSTRING_PTR (obj ),
284+ RSTRING_LEN (obj )))
285+ ossl_raise (eOSSLError , "OSSL_PARAM_BLD_push_octet_string" );
286+ break ;
287+ default :
288+ /*
289+ * Types not used in settable OSSL_PARAMs as of OpenSSL 3.5:
290+ * - OSSL_PARAM_UTF8_PTR
291+ * - OSSL_PARAM_OCTET_PTR
292+ */
293+ rb_raise (eOSSLError , "unsupported type %d for OSSL_PARAM key '%s'" ,
294+ p -> data_type , p -> key );
295+ }
296+ return Qnil ;
297+ }
298+
299+ static VALUE
300+ build_params_internal (VALUE memo )
301+ {
302+ struct build_params_args * args = (struct build_params_args * )memo ;
303+
304+ args -> bld = OSSL_PARAM_BLD_new ();
305+ if (!args -> bld )
306+ ossl_raise (eOSSLError , "OSSL_PARAM_BLD_new" );
307+
308+ if (!NIL_P (args -> hash ))
309+ rb_block_call (args -> hash , rb_intern ("each" ), 0 , NULL , build_params_i ,
310+ (VALUE )args );
311+
312+ OSSL_PARAM * ret = OSSL_PARAM_BLD_to_param (args -> bld );
313+ if (!ret )
314+ ossl_raise (eOSSLError , "OSSL_PARAM_BLD_to_param" );
315+ return (VALUE )ret ;
316+ }
317+
318+ OSSL_PARAM *
319+ ossl_build_params (const OSSL_PARAM * settable , VALUE hash , int * state )
320+ {
321+ struct build_params_args args = { settable , hash , NULL };
322+ VALUE params = rb_protect (build_params_internal , (VALUE )& args , state );
323+ OSSL_PARAM_BLD_free (args .bld );
324+ return (OSSL_PARAM * )params ;
325+ }
326+ #endif
327+
220328/*
221329 * main module
222330 */
0 commit comments