Ruby  2.7.1p83(2020-03-31revisiona0c7c23c9cec0d0ffcba012279cd652d28ad5bf3)
ossl_pkey.c
Go to the documentation of this file.
1 /*
2  * 'OpenSSL for Ruby' project
3  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4  * All rights reserved.
5  */
6 /*
7  * This program is licensed under the same licence as Ruby.
8  * (See the file 'LICENCE'.)
9  */
10 #include "ossl.h"
11 
12 /*
13  * Classes
14  */
18 static ID id_private_q;
19 
20 /*
21  * callback for generating keys
22  */
23 static VALUE
24 call_check_ints0(VALUE arg)
25 {
27  return Qnil;
28 }
29 
30 static void *
31 call_check_ints(void *arg)
32 {
33  int state;
34  rb_protect(call_check_ints0, Qnil, &state);
35  return (void *)(VALUE)state;
36 }
37 
38 int
39 ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
40 {
41  VALUE ary;
42  struct ossl_generate_cb_arg *arg;
43  int state;
44 
46  if (arg->yield) {
47  ary = rb_ary_new2(2);
48  rb_ary_store(ary, 0, INT2NUM(p));
49  rb_ary_store(ary, 1, INT2NUM(n));
50 
51  /*
52  * can be break by raising exception or 'break'
53  */
54  rb_protect(rb_yield, ary, &state);
55  if (state) {
56  arg->state = state;
57  return 0;
58  }
59  }
60  if (arg->interrupted) {
61  arg->interrupted = 0;
62  state = (int)(VALUE)rb_thread_call_with_gvl(call_check_ints, NULL);
63  if (state) {
64  arg->state = state;
65  return 0;
66  }
67  }
68  return 1;
69 }
70 
71 void
73 {
75  arg->interrupted = 1;
76 }
77 
78 static void
79 ossl_evp_pkey_free(void *ptr)
80 {
81  EVP_PKEY_free(ptr);
82 }
83 
84 /*
85  * Public
86  */
88  "OpenSSL/EVP_PKEY",
89  {
90  0, ossl_evp_pkey_free,
91  },
93 };
94 
95 static VALUE
96 pkey_new0(EVP_PKEY *pkey)
97 {
98  VALUE obj;
99  int type;
100 
101  if (!pkey || (type = EVP_PKEY_base_id(pkey)) == EVP_PKEY_NONE)
102  ossl_raise(rb_eRuntimeError, "pkey is empty");
103 
104  switch (type) {
105 #if !defined(OPENSSL_NO_RSA)
106  case EVP_PKEY_RSA:
107  return ossl_rsa_new(pkey);
108 #endif
109 #if !defined(OPENSSL_NO_DSA)
110  case EVP_PKEY_DSA:
111  return ossl_dsa_new(pkey);
112 #endif
113 #if !defined(OPENSSL_NO_DH)
114  case EVP_PKEY_DH:
115  return ossl_dh_new(pkey);
116 #endif
117 #if !defined(OPENSSL_NO_EC)
118  case EVP_PKEY_EC:
119  return ossl_ec_new(pkey);
120 #endif
121  default:
122  obj = NewPKey(cPKey);
123  SetPKey(obj, pkey);
124  return obj;
125  }
126 }
127 
128 VALUE
129 ossl_pkey_new(EVP_PKEY *pkey)
130 {
131  VALUE obj;
132  int status;
133 
134  obj = rb_protect((VALUE (*)(VALUE))pkey_new0, (VALUE)pkey, &status);
135  if (status) {
136  EVP_PKEY_free(pkey);
137  rb_jump_tag(status);
138  }
139 
140  return obj;
141 }
142 
143 /*
144  * call-seq:
145  * OpenSSL::PKey.read(string [, pwd ]) -> PKey
146  * OpenSSL::PKey.read(io [, pwd ]) -> PKey
147  *
148  * Reads a DER or PEM encoded string from _string_ or _io_ and returns an
149  * instance of the appropriate PKey class.
150  *
151  * === Parameters
152  * * _string+ is a DER- or PEM-encoded string containing an arbitrary private
153  * or public key.
154  * * _io_ is an instance of IO containing a DER- or PEM-encoded
155  * arbitrary private or public key.
156  * * _pwd_ is an optional password in case _string_ or _io_ is an encrypted
157  * PEM resource.
158  */
159 static VALUE
160 ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
161 {
162  EVP_PKEY *pkey;
163  BIO *bio;
164  VALUE data, pass;
165 
166  rb_scan_args(argc, argv, "11", &data, &pass);
167  pass = ossl_pem_passwd_value(pass);
168 
169  bio = ossl_obj2bio(&data);
170  if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
171  OSSL_BIO_reset(bio);
172  if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, (void *)pass))) {
173  OSSL_BIO_reset(bio);
174  if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
175  OSSL_BIO_reset(bio);
176  pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, (void *)pass);
177  }
178  }
179  }
180 
181  BIO_free(bio);
182  if (!pkey)
183  ossl_raise(ePKeyError, "Could not parse PKey");
184 
185  return ossl_pkey_new(pkey);
186 }
187 
188 void
189 ossl_pkey_check_public_key(const EVP_PKEY *pkey)
190 {
191  void *ptr;
192  const BIGNUM *n, *e, *pubkey;
193 
194  if (EVP_PKEY_missing_parameters(pkey))
195  ossl_raise(ePKeyError, "parameters missing");
196 
197  /* OpenSSL < 1.1.0 takes non-const pointer */
198  ptr = EVP_PKEY_get0((EVP_PKEY *)pkey);
199  switch (EVP_PKEY_base_id(pkey)) {
200  case EVP_PKEY_RSA:
201  RSA_get0_key(ptr, &n, &e, NULL);
202  if (n && e)
203  return;
204  break;
205  case EVP_PKEY_DSA:
206  DSA_get0_key(ptr, &pubkey, NULL);
207  if (pubkey)
208  return;
209  break;
210  case EVP_PKEY_DH:
211  DH_get0_key(ptr, &pubkey, NULL);
212  if (pubkey)
213  return;
214  break;
215 #if !defined(OPENSSL_NO_EC)
216  case EVP_PKEY_EC:
217  if (EC_KEY_get0_public_key(ptr))
218  return;
219  break;
220 #endif
221  default:
222  /* unsupported type; assuming ok */
223  return;
224  }
225  ossl_raise(ePKeyError, "public key missing");
226 }
227 
228 EVP_PKEY *
230 {
231  EVP_PKEY *pkey;
232 
233  GetPKey(obj, pkey);
234 
235  return pkey;
236 }
237 
238 EVP_PKEY *
240 {
241  EVP_PKEY *pkey;
242 
243  if (rb_funcallv(obj, id_private_q, 0, NULL) != Qtrue) {
244  ossl_raise(rb_eArgError, "Private key is needed.");
245  }
246  GetPKey(obj, pkey);
247 
248  return pkey;
249 }
250 
251 EVP_PKEY *
253 {
254  EVP_PKEY *pkey;
255 
256  GetPKey(obj, pkey);
257  EVP_PKEY_up_ref(pkey);
258 
259  return pkey;
260 }
261 
262 /*
263  * Private
264  */
265 static VALUE
266 ossl_pkey_alloc(VALUE klass)
267 {
268  EVP_PKEY *pkey;
269  VALUE obj;
270 
271  obj = NewPKey(klass);
272  if (!(pkey = EVP_PKEY_new())) {
274  }
275  SetPKey(obj, pkey);
276 
277  return obj;
278 }
279 
280 /*
281  * call-seq:
282  * PKeyClass.new -> self
283  *
284  * Because PKey is an abstract class, actually calling this method explicitly
285  * will raise a NotImplementedError.
286  */
287 static VALUE
288 ossl_pkey_initialize(VALUE self)
289 {
290  if (rb_obj_is_instance_of(self, cPKey)) {
291  ossl_raise(rb_eTypeError, "OpenSSL::PKey::PKey can't be instantiated directly");
292  }
293  return self;
294 }
295 
296 /*
297  * call-seq:
298  * pkey.sign(digest, data) -> String
299  *
300  * To sign the String _data_, _digest_, an instance of OpenSSL::Digest, must
301  * be provided. The return value is again a String containing the signature.
302  * A PKeyError is raised should errors occur.
303  * Any previous state of the Digest instance is irrelevant to the signature
304  * outcome, the digest instance is reset to its initial state during the
305  * operation.
306  *
307  * == Example
308  * data = 'Sign me!'
309  * digest = OpenSSL::Digest::SHA256.new
310  * pkey = OpenSSL::PKey::RSA.new(2048)
311  * signature = pkey.sign(digest, data)
312  */
313 static VALUE
314 ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
315 {
316  EVP_PKEY *pkey;
317  const EVP_MD *md;
318  EVP_MD_CTX *ctx;
319  unsigned int buf_len;
320  VALUE str;
321  int result;
322 
323  pkey = GetPrivPKeyPtr(self);
324  md = ossl_evp_get_digestbyname(digest);
325  StringValue(data);
326  str = rb_str_new(0, EVP_PKEY_size(pkey));
327 
328  ctx = EVP_MD_CTX_new();
329  if (!ctx)
330  ossl_raise(ePKeyError, "EVP_MD_CTX_new");
331  if (!EVP_SignInit_ex(ctx, md, NULL)) {
332  EVP_MD_CTX_free(ctx);
333  ossl_raise(ePKeyError, "EVP_SignInit_ex");
334  }
335  if (!EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
336  EVP_MD_CTX_free(ctx);
337  ossl_raise(ePKeyError, "EVP_SignUpdate");
338  }
339  result = EVP_SignFinal(ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey);
340  EVP_MD_CTX_free(ctx);
341  if (!result)
342  ossl_raise(ePKeyError, "EVP_SignFinal");
343  rb_str_set_len(str, buf_len);
344 
345  return str;
346 }
347 
348 /*
349  * call-seq:
350  * pkey.verify(digest, signature, data) -> String
351  *
352  * To verify the String _signature_, _digest_, an instance of
353  * OpenSSL::Digest, must be provided to re-compute the message digest of the
354  * original _data_, also a String. The return value is +true+ if the
355  * signature is valid, +false+ otherwise. A PKeyError is raised should errors
356  * occur.
357  * Any previous state of the Digest instance is irrelevant to the validation
358  * outcome, the digest instance is reset to its initial state during the
359  * operation.
360  *
361  * == Example
362  * data = 'Sign me!'
363  * digest = OpenSSL::Digest::SHA256.new
364  * pkey = OpenSSL::PKey::RSA.new(2048)
365  * signature = pkey.sign(digest, data)
366  * pub_key = pkey.public_key
367  * puts pub_key.verify(digest, signature, data) # => true
368  */
369 static VALUE
370 ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
371 {
372  EVP_PKEY *pkey;
373  const EVP_MD *md;
374  EVP_MD_CTX *ctx;
375  int siglen, result;
376 
377  GetPKey(self, pkey);
379  md = ossl_evp_get_digestbyname(digest);
380  StringValue(sig);
381  siglen = RSTRING_LENINT(sig);
382  StringValue(data);
383 
384  ctx = EVP_MD_CTX_new();
385  if (!ctx)
386  ossl_raise(ePKeyError, "EVP_MD_CTX_new");
387  if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
388  EVP_MD_CTX_free(ctx);
389  ossl_raise(ePKeyError, "EVP_VerifyInit_ex");
390  }
391  if (!EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
392  EVP_MD_CTX_free(ctx);
393  ossl_raise(ePKeyError, "EVP_VerifyUpdate");
394  }
395  result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), siglen, pkey);
396  EVP_MD_CTX_free(ctx);
397  switch (result) {
398  case 0:
400  return Qfalse;
401  case 1:
402  return Qtrue;
403  default:
404  ossl_raise(ePKeyError, "EVP_VerifyFinal");
405  }
406 }
407 
408 /*
409  * INIT
410  */
411 void
413 {
414 #undef rb_intern
415 #if 0
416  mOSSL = rb_define_module("OpenSSL");
418 #endif
419 
420  /* Document-module: OpenSSL::PKey
421  *
422  * == Asymmetric Public Key Algorithms
423  *
424  * Asymmetric public key algorithms solve the problem of establishing and
425  * sharing secret keys to en-/decrypt messages. The key in such an
426  * algorithm consists of two parts: a public key that may be distributed
427  * to others and a private key that needs to remain secret.
428  *
429  * Messages encrypted with a public key can only be decrypted by
430  * recipients that are in possession of the associated private key.
431  * Since public key algorithms are considerably slower than symmetric
432  * key algorithms (cf. OpenSSL::Cipher) they are often used to establish
433  * a symmetric key shared between two parties that are in possession of
434  * each other's public key.
435  *
436  * Asymmetric algorithms offer a lot of nice features that are used in a
437  * lot of different areas. A very common application is the creation and
438  * validation of digital signatures. To sign a document, the signatory
439  * generally uses a message digest algorithm (cf. OpenSSL::Digest) to
440  * compute a digest of the document that is then encrypted (i.e. signed)
441  * using the private key. Anyone in possession of the public key may then
442  * verify the signature by computing the message digest of the original
443  * document on their own, decrypting the signature using the signatory's
444  * public key and comparing the result to the message digest they
445  * previously computed. The signature is valid if and only if the
446  * decrypted signature is equal to this message digest.
447  *
448  * The PKey module offers support for three popular public/private key
449  * algorithms:
450  * * RSA (OpenSSL::PKey::RSA)
451  * * DSA (OpenSSL::PKey::DSA)
452  * * Elliptic Curve Cryptography (OpenSSL::PKey::EC)
453  * Each of these implementations is in fact a sub-class of the abstract
454  * PKey class which offers the interface for supporting digital signatures
455  * in the form of PKey#sign and PKey#verify.
456  *
457  * == Diffie-Hellman Key Exchange
458  *
459  * Finally PKey also features OpenSSL::PKey::DH, an implementation of
460  * the Diffie-Hellman key exchange protocol based on discrete logarithms
461  * in finite fields, the same basis that DSA is built on.
462  * The Diffie-Hellman protocol can be used to exchange (symmetric) keys
463  * over insecure channels without needing any prior joint knowledge
464  * between the participating parties. As the security of DH demands
465  * relatively long "public keys" (i.e. the part that is overtly
466  * transmitted between participants) DH tends to be quite slow. If
467  * security or speed is your primary concern, OpenSSL::PKey::EC offers
468  * another implementation of the Diffie-Hellman protocol.
469  *
470  */
472 
473  /* Document-class: OpenSSL::PKey::PKeyError
474  *
475  *Raised when errors occur during PKey#sign or PKey#verify.
476  */
478 
479  /* Document-class: OpenSSL::PKey::PKey
480  *
481  * An abstract class that bundles signature creation (PKey#sign) and
482  * validation (PKey#verify) that is common to all implementations except
483  * OpenSSL::PKey::DH
484  * * OpenSSL::PKey::RSA
485  * * OpenSSL::PKey::DSA
486  * * OpenSSL::PKey::EC
487  */
489 
490  rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
491 
492  rb_define_alloc_func(cPKey, ossl_pkey_alloc);
493  rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
494 
495  rb_define_method(cPKey, "sign", ossl_pkey_sign, 2);
496  rb_define_method(cPKey, "verify", ossl_pkey_verify, 3);
497 
498  id_private_q = rb_intern("private?");
499 
500  /*
501  * INIT rsa, dsa, dh, ec
502  */
503  Init_ossl_rsa();
504  Init_ossl_dsa();
505  Init_ossl_dh();
506  Init_ossl_ec();
507 }
ID
unsigned long ID
Definition: ruby.h:103
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.1.h:5742
GetPKeyPtr
EVP_PKEY * GetPKeyPtr(VALUE obj)
Definition: ossl_pkey.c:229
rb_thread_check_ints
void rb_thread_check_ints(void)
Definition: thread.c:1362
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.1.h:13259
rb_define_module_under
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:797
Init_ossl_rsa
void Init_ossl_rsa(void)
Definition: ossl_pkey_rsa.c:880
n
const char size_t n
Definition: rb_mjit_min_header-2.7.1.h:5456
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
ePKeyError
VALUE ePKeyError
Definition: ossl_pkey.c:17
VALUE
unsigned long VALUE
Definition: ruby.h:102
ossl_obj2bio
BIO * ossl_obj2bio(volatile VALUE *pobj)
Definition: ossl_bio.c:13
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
rb_intern
#define rb_intern(str)
rb_ary_store
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:1079
OSSL_BIO_reset
#define OSSL_BIO_reset(bio)
Definition: ossl.h:114
RSTRING_LENINT
#define RSTRING_LENINT(str)
Definition: ruby.h:1017
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:772
ossl.h
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.1.h:5601
ossl_clear_error
void ossl_clear_error(void)
Definition: ossl.c:304
cPKey
VALUE cPKey
Definition: ossl_pkey.c:16
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
INT2NUM
#define INT2NUM(x)
Definition: ruby.h:1609
ptr
struct RIMemo * ptr
Definition: debug.c:74
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.1.h:6116
Qfalse
#define Qfalse
Definition: ruby.h:467
ossl_pem_passwd_cb
int ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
Definition: ossl.c:177
Init_ossl_dh
void Init_ossl_dh(void)
Definition: ossl_pkey_dh.c:576
ossl_evp_pkey_type
const rb_data_type_t ossl_evp_pkey_type
Definition: ossl_pkey.c:87
NULL
#define NULL
Definition: _sdbm.c:101
rb_protect
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
Definition: eval.c:1072
Init_ossl_pkey
void Init_ossl_pkey(void)
Definition: ossl_pkey.c:412
ossl_pkey_check_public_key
void ossl_pkey_check_public_key(const EVP_PKEY *pkey)
Definition: ossl_pkey.c:189
ossl_dh_new
VALUE ossl_dh_new(EVP_PKEY *)
Definition: ossl_pkey_dh.c:58
sig
int sig
Definition: rb_mjit_min_header-2.7.1.h:10427
ossl_ec_new
VALUE ossl_ec_new(EVP_PKEY *)
Definition: ossl_pkey_ec.c:87
mOSSL
VALUE mOSSL
Definition: ossl.c:231
rb_obj_is_instance_of
VALUE rb_obj_is_instance_of(VALUE, VALUE)
Determines if obj is an instance of c.
Definition: object.c:675
ossl_generate_cb_stop
void ossl_generate_cb_stop(void *ptr)
Definition: ossl_pkey.c:72
rb_jump_tag
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:884
ossl_pem_passwd_value
VALUE ossl_pem_passwd_value(VALUE pass)
Definition: ossl.c:151
GetPKey
#define GetPKey(obj, pkey)
Definition: ossl_pkey.h:31
ossl_dsa_new
VALUE ossl_dsa_new(EVP_PKEY *)
Definition: ossl_pkey_dsa.c:72
Init_ossl_dsa
void Init_ossl_dsa(void)
Definition: ossl_pkey_dsa.c:609
ossl_raise
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:293
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
DupPKeyPtr
EVP_PKEY * DupPKeyPtr(VALUE obj)
Definition: ossl_pkey.c:252
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:920
rb_str_set_len
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
BN_GENCB_get_arg
#define BN_GENCB_get_arg(cb)
Definition: openssl_missing.h:46
ossl_generate_cb_arg
Definition: ossl_pkey.h:38
rb_define_module_function
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1771
rb_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.1.h:6372
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
EVP_MD_CTX_free
#define EVP_MD_CTX_free
Definition: openssl_missing.h:54
mPKey
VALUE mPKey
Definition: ossl_pkey.c:15
rb_ary_new2
#define rb_ary_new2
Definition: intern.h:103
Init_ossl_ec
void Init_ossl_ec(void)
Definition: ossl_pkey_ec.c:1650
StringValue
use StringValue() instead")))
argv
char ** argv
Definition: ruby.c:223
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1207
ossl_generate_cb_arg::state
int state
Definition: ossl_pkey.h:41
int
__inline__ int
Definition: rb_mjit_min_header-2.7.1.h:2839
argc
int argc
Definition: ruby.c:222
EVP_PKEY_up_ref
#define EVP_PKEY_up_ref(x)
Definition: openssl_missing.h:143
rb_data_type_struct
Definition: ruby.h:1148
SetPKey
#define SetPKey(obj, pkey)
Definition: ossl_pkey.h:24
NewPKey
#define NewPKey(klass)
Definition: ossl_pkey.h:22
Qtrue
#define Qtrue
Definition: ruby.h:468
eOSSLError
VALUE eOSSLError
Definition: ossl.c:236
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:698
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1237
Qnil
#define Qnil
Definition: ruby.h:469
GetPrivPKeyPtr
EVP_PKEY * GetPrivPKeyPtr(VALUE obj)
Definition: ossl_pkey.c:239
ossl_evp_get_digestbyname
const EVP_MD * ossl_evp_get_digestbyname(VALUE obj)
Definition: ossl_digest.c:45
rb_eStandardError
VALUE rb_eStandardError
Definition: error.c:919
EVP_MD_CTX_new
#define EVP_MD_CTX_new
Definition: openssl_missing.h:50
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
rb_thread_call_with_gvl
RUBY_SYMBOL_EXPORT_BEGIN void * rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
Definition: thread.c:1662
ossl_rsa_new
VALUE ossl_rsa_new(EVP_PKEY *)
Definition: ossl_pkey_rsa.c:73
ossl_generate_cb_2
int ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
Definition: ossl_pkey.c:39
ossl_pkey_new
VALUE ossl_pkey_new(EVP_PKEY *pkey)
Definition: ossl_pkey.c:129
rb_funcallv
#define rb_funcallv(recv, mid, argc, argv)
Definition: rb_mjit_min_header-2.7.1.h:7904