Ruby  2.5.0dev(2017-10-22revision60238)
ossl_pkey_dh.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 #if !defined(OPENSSL_NO_DH)
13 
14 #define GetPKeyDH(obj, pkey) do { \
15  GetPKey((obj), (pkey)); \
16  if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { /* PARANOIA? */ \
17  ossl_raise(rb_eRuntimeError, "THIS IS NOT A DH!") ; \
18  } \
19 } while (0)
20 #define GetDH(obj, dh) do { \
21  EVP_PKEY *_pkey; \
22  GetPKeyDH((obj), _pkey); \
23  (dh) = EVP_PKEY_get0_DH(_pkey); \
24 } while (0)
25 
26 /*
27  * Classes
28  */
31 
32 /*
33  * Public
34  */
35 static VALUE
36 dh_instance(VALUE klass, DH *dh)
37 {
38  EVP_PKEY *pkey;
39  VALUE obj;
40 
41  if (!dh) {
42  return Qfalse;
43  }
44  obj = NewPKey(klass);
45  if (!(pkey = EVP_PKEY_new())) {
46  return Qfalse;
47  }
48  if (!EVP_PKEY_assign_DH(pkey, dh)) {
49  EVP_PKEY_free(pkey);
50  return Qfalse;
51  }
52  SetPKey(obj, pkey);
53 
54  return obj;
55 }
56 
57 VALUE
58 ossl_dh_new(EVP_PKEY *pkey)
59 {
60  VALUE obj;
61 
62  if (!pkey) {
63  obj = dh_instance(cDH, DH_new());
64  } else {
65  obj = NewPKey(cDH);
66  if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) {
67  ossl_raise(rb_eTypeError, "Not a DH key!");
68  }
69  SetPKey(obj, pkey);
70  }
71  if (obj == Qfalse) {
73  }
74 
75  return obj;
76 }
77 
78 /*
79  * Private
80  */
82  DH *dh;
83  int size;
84  int gen;
85  BN_GENCB *cb;
86  int result;
87 };
88 
89 static void *
90 dh_blocking_gen(void *arg)
91 {
92  struct dh_blocking_gen_arg *gen = (struct dh_blocking_gen_arg *)arg;
93  gen->result = DH_generate_parameters_ex(gen->dh, gen->size, gen->gen, gen->cb);
94  return 0;
95 }
96 
97 static DH *
98 dh_generate(int size, int gen)
99 {
100  struct ossl_generate_cb_arg cb_arg = { 0 };
101  struct dh_blocking_gen_arg gen_arg;
102  DH *dh = DH_new();
103  BN_GENCB *cb = BN_GENCB_new();
104 
105  if (!dh || !cb) {
106  DH_free(dh);
107  BN_GENCB_free(cb);
108  return NULL;
109  }
110 
111  if (rb_block_given_p())
112  cb_arg.yield = 1;
113  BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg);
114  gen_arg.dh = dh;
115  gen_arg.size = size;
116  gen_arg.gen = gen;
117  gen_arg.cb = cb;
118  if (cb_arg.yield == 1) {
119  /* we cannot release GVL when callback proc is supplied */
120  dh_blocking_gen(&gen_arg);
121  } else {
122  /* there's a chance to unblock */
123  rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
124  }
125 
126  BN_GENCB_free(cb);
127  if (!gen_arg.result) {
128  DH_free(dh);
129  if (cb_arg.state) {
130  /* Clear OpenSSL error queue before re-raising. */
132  rb_jump_tag(cb_arg.state);
133  }
134  return NULL;
135  }
136 
137  if (!DH_generate_key(dh)) {
138  DH_free(dh);
139  return NULL;
140  }
141 
142  return dh;
143 }
144 
145 /*
146  * call-seq:
147  * DH.generate(size [, generator]) -> dh
148  *
149  * Creates a new DH instance from scratch by generating the private and public
150  * components alike.
151  *
152  * === Parameters
153  * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.
154  * * _generator_ is a small number > 1, typically 2 or 5.
155  *
156  */
157 static VALUE
158 ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass)
159 {
160  DH *dh ;
161  int g = 2;
162  VALUE size, gen, obj;
163 
164  if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) {
165  g = NUM2INT(gen);
166  }
167  dh = dh_generate(NUM2INT(size), g);
168  obj = dh_instance(klass, dh);
169  if (obj == Qfalse) {
170  DH_free(dh);
172  }
173 
174  return obj;
175 }
176 
177 /*
178  * call-seq:
179  * DH.new -> dh
180  * DH.new(string) -> dh
181  * DH.new(size [, generator]) -> dh
182  *
183  * Either generates a DH instance from scratch or by reading already existing
184  * DH parameters from _string_. Note that when reading a DH instance from
185  * data that was encoded from a DH instance by using DH#to_pem or DH#to_der
186  * the result will *not* contain a public/private key pair yet. This needs to
187  * be generated using DH#generate_key! first.
188  *
189  * === Parameters
190  * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.
191  * * _generator_ is a small number > 1, typically 2 or 5.
192  * * _string_ contains the DER or PEM encoded key.
193  *
194  * === Examples
195  * DH.new # -> dh
196  * DH.new(1024) # -> dh
197  * DH.new(1024, 5) # -> dh
198  * #Reading DH parameters
199  * dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet
200  * dh.generate_key! # -> dh with public and private key
201  */
202 static VALUE
203 ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
204 {
205  EVP_PKEY *pkey;
206  DH *dh;
207  int g = 2;
208  BIO *in;
209  VALUE arg, gen;
210 
211  GetPKey(self, pkey);
212  if(rb_scan_args(argc, argv, "02", &arg, &gen) == 0) {
213  dh = DH_new();
214  }
215  else if (RB_INTEGER_TYPE_P(arg)) {
216  if (!NIL_P(gen)) {
217  g = NUM2INT(gen);
218  }
219  if (!(dh = dh_generate(NUM2INT(arg), g))) {
221  }
222  }
223  else {
224  arg = ossl_to_der_if_possible(arg);
225  in = ossl_obj2bio(&arg);
226  dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
227  if (!dh){
228  OSSL_BIO_reset(in);
229  dh = d2i_DHparams_bio(in, NULL);
230  }
231  BIO_free(in);
232  if (!dh) {
234  }
235  }
236  if (!EVP_PKEY_assign_DH(pkey, dh)) {
237  DH_free(dh);
239  }
240  return self;
241 }
242 
243 static VALUE
244 ossl_dh_initialize_copy(VALUE self, VALUE other)
245 {
246  EVP_PKEY *pkey;
247  DH *dh, *dh_other;
248  const BIGNUM *pub, *priv;
249 
250  GetPKey(self, pkey);
251  if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
252  ossl_raise(eDHError, "DH already initialized");
253  GetDH(other, dh_other);
254 
255  dh = DHparams_dup(dh_other);
256  if (!dh)
257  ossl_raise(eDHError, "DHparams_dup");
258  EVP_PKEY_assign_DH(pkey, dh);
259 
260  DH_get0_key(dh_other, &pub, &priv);
261  if (pub) {
262  BIGNUM *pub2 = BN_dup(pub);
263  BIGNUM *priv2 = BN_dup(priv);
264 
265  if (!pub2 || priv && !priv2) {
266  BN_clear_free(pub2);
267  BN_clear_free(priv2);
268  ossl_raise(eDHError, "BN_dup");
269  }
270  DH_set0_key(dh, pub2, priv2);
271  }
272 
273  return self;
274 }
275 
276 /*
277  * call-seq:
278  * dh.public? -> true | false
279  *
280  * Indicates whether this DH instance has a public key associated with it or
281  * not. The public key may be retrieved with DH#pub_key.
282  */
283 static VALUE
284 ossl_dh_is_public(VALUE self)
285 {
286  DH *dh;
287  const BIGNUM *bn;
288 
289  GetDH(self, dh);
290  DH_get0_key(dh, &bn, NULL);
291 
292  return bn ? Qtrue : Qfalse;
293 }
294 
295 /*
296  * call-seq:
297  * dh.private? -> true | false
298  *
299  * Indicates whether this DH instance has a private key associated with it or
300  * not. The private key may be retrieved with DH#priv_key.
301  */
302 static VALUE
303 ossl_dh_is_private(VALUE self)
304 {
305  DH *dh;
306  const BIGNUM *bn;
307 
308  GetDH(self, dh);
309  DH_get0_key(dh, NULL, &bn);
310 
311 #if !defined(OPENSSL_NO_ENGINE)
312  return (bn || DH_get0_engine(dh)) ? Qtrue : Qfalse;
313 #else
314  return bn ? Qtrue : Qfalse;
315 #endif
316 }
317 
318 /*
319  * call-seq:
320  * dh.export -> aString
321  * dh.to_pem -> aString
322  * dh.to_s -> aString
323  *
324  * Encodes this DH to its PEM encoding. Note that any existing per-session
325  * public/private keys will *not* get encoded, just the Diffie-Hellman
326  * parameters will be encoded.
327  */
328 static VALUE
329 ossl_dh_export(VALUE self)
330 {
331  DH *dh;
332  BIO *out;
333  VALUE str;
334 
335  GetDH(self, dh);
336  if (!(out = BIO_new(BIO_s_mem()))) {
338  }
339  if (!PEM_write_bio_DHparams(out, dh)) {
340  BIO_free(out);
342  }
343  str = ossl_membio2str(out);
344 
345  return str;
346 }
347 
348 /*
349  * call-seq:
350  * dh.to_der -> aString
351  *
352  * Encodes this DH to its DER encoding. Note that any existing per-session
353  * public/private keys will *not* get encoded, just the Diffie-Hellman
354  * parameters will be encoded.
355 
356  */
357 static VALUE
358 ossl_dh_to_der(VALUE self)
359 {
360  DH *dh;
361  unsigned char *p;
362  long len;
363  VALUE str;
364 
365  GetDH(self, dh);
366  if((len = i2d_DHparams(dh, NULL)) <= 0)
368  str = rb_str_new(0, len);
369  p = (unsigned char *)RSTRING_PTR(str);
370  if(i2d_DHparams(dh, &p) < 0)
372  ossl_str_adjust(str, p);
373 
374  return str;
375 }
376 
377 /*
378  * call-seq:
379  * dh.params -> hash
380  *
381  * Stores all parameters of key to the hash
382  * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
383  * Don't use :-)) (I's up to you)
384  */
385 static VALUE
386 ossl_dh_get_params(VALUE self)
387 {
388  DH *dh;
389  VALUE hash;
390  const BIGNUM *p, *q, *g, *pub_key, *priv_key;
391 
392  GetDH(self, dh);
393  DH_get0_pqg(dh, &p, &q, &g);
394  DH_get0_key(dh, &pub_key, &priv_key);
395 
396  hash = rb_hash_new();
397  rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
398  rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
399  rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g));
400  rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key));
401  rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key));
402 
403  return hash;
404 }
405 
406 /*
407  * call-seq:
408  * dh.to_text -> aString
409  *
410  * Prints all parameters of key to buffer
411  * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
412  * Don't use :-)) (I's up to you)
413  */
414 static VALUE
415 ossl_dh_to_text(VALUE self)
416 {
417  DH *dh;
418  BIO *out;
419  VALUE str;
420 
421  GetDH(self, dh);
422  if (!(out = BIO_new(BIO_s_mem()))) {
424  }
425  if (!DHparams_print(out, dh)) {
426  BIO_free(out);
428  }
429  str = ossl_membio2str(out);
430 
431  return str;
432 }
433 
434 /*
435  * call-seq:
436  * dh.public_key -> aDH
437  *
438  * Returns a new DH instance that carries just the public information, i.e.
439  * the prime _p_ and the generator _g_, but no public/private key yet. Such
440  * a pair may be generated using DH#generate_key!. The "public key" needed
441  * for a key exchange with DH#compute_key is considered as per-session
442  * information and may be retrieved with DH#pub_key once a key pair has
443  * been generated.
444  * If the current instance already contains private information (and thus a
445  * valid public/private key pair), this information will no longer be present
446  * in the new instance generated by DH#public_key. This feature is helpful for
447  * publishing the Diffie-Hellman parameters without leaking any of the private
448  * per-session information.
449  *
450  * === Example
451  * dh = OpenSSL::PKey::DH.new(2048) # has public and private key set
452  * public_key = dh.public_key # contains only prime and generator
453  * parameters = public_key.to_der # it's safe to publish this
454  */
455 static VALUE
456 ossl_dh_to_public_key(VALUE self)
457 {
458  DH *orig_dh, *dh;
459  VALUE obj;
460 
461  GetDH(self, orig_dh);
462  dh = DHparams_dup(orig_dh); /* err check perfomed by dh_instance */
463  obj = dh_instance(rb_obj_class(self), dh);
464  if (obj == Qfalse) {
465  DH_free(dh);
467  }
468 
469  return obj;
470 }
471 
472 /*
473  * call-seq:
474  * dh.params_ok? -> true | false
475  *
476  * Validates the Diffie-Hellman parameters associated with this instance.
477  * It checks whether a safe prime and a suitable generator are used. If this
478  * is not the case, +false+ is returned.
479  */
480 static VALUE
481 ossl_dh_check_params(VALUE self)
482 {
483  DH *dh;
484  int codes;
485 
486  GetDH(self, dh);
487  if (!DH_check(dh, &codes)) {
488  return Qfalse;
489  }
490 
491  return codes == 0 ? Qtrue : Qfalse;
492 }
493 
494 /*
495  * call-seq:
496  * dh.generate_key! -> self
497  *
498  * Generates a private and public key unless a private key already exists.
499  * If this DH instance was generated from public DH parameters (e.g. by
500  * encoding the result of DH#public_key), then this method needs to be
501  * called first in order to generate the per-session keys before performing
502  * the actual key exchange.
503  *
504  * === Example
505  * dh = OpenSSL::PKey::DH.new(2048)
506  * public_key = dh.public_key #contains no private/public key yet
507  * public_key.generate_key!
508  * puts public_key.private? # => true
509  */
510 static VALUE
511 ossl_dh_generate_key(VALUE self)
512 {
513  DH *dh;
514 
515  GetDH(self, dh);
516  if (!DH_generate_key(dh))
517  ossl_raise(eDHError, "Failed to generate key");
518  return self;
519 }
520 
521 /*
522  * call-seq:
523  * dh.compute_key(pub_bn) -> aString
524  *
525  * Returns a String containing a shared secret computed from the other party's public value.
526  * See DH_compute_key() for further information.
527  *
528  * === Parameters
529  * * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by
530  * DH#public_key as that contains the DH parameters only.
531  */
532 static VALUE
533 ossl_dh_compute_key(VALUE self, VALUE pub)
534 {
535  DH *dh;
536  const BIGNUM *pub_key, *dh_p;
537  VALUE str;
538  int len;
539 
540  GetDH(self, dh);
541  DH_get0_pqg(dh, &dh_p, NULL, NULL);
542  if (!dh_p)
543  ossl_raise(eDHError, "incomplete DH");
544  pub_key = GetBNPtr(pub);
545  len = DH_size(dh);
546  str = rb_str_new(0, len);
547  if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) {
549  }
550  rb_str_set_len(str, len);
551 
552  return str;
553 }
554 
555 /*
556  * Document-method: OpenSSL::PKey::DH#set_pqg
557  * call-seq:
558  * dh.set_pqg(p, q, g) -> self
559  *
560  * Sets _p_, _q_, _g_ to the DH instance.
561  */
562 OSSL_PKEY_BN_DEF3(dh, DH, pqg, p, q, g)
563 /*
564  * Document-method: OpenSSL::PKey::DH#set_key
565  * call-seq:
566  * dh.set_key(pub_key, priv_key) -> self
567  *
568  * Sets _pub_key_ and _priv_key_ for the DH instance. _priv_key_ may be +nil+.
569  */
571 
572 /*
573  * INIT
574  */
575 void
577 {
578 #if 0
582 #endif
583 
584  /* Document-class: OpenSSL::PKey::DHError
585  *
586  * Generic exception that is raised if an operation on a DH PKey
587  * fails unexpectedly or in case an instantiation of an instance of DH
588  * fails due to non-conformant input data.
589  */
591  /* Document-class: OpenSSL::PKey::DH
592  *
593  * An implementation of the Diffie-Hellman key exchange protocol based on
594  * discrete logarithms in finite fields, the same basis that DSA is built
595  * on.
596  *
597  * === Accessor methods for the Diffie-Hellman parameters
598  * DH#p::
599  * The prime (an OpenSSL::BN) of the Diffie-Hellman parameters.
600  * DH#g::
601  * The generator (an OpenSSL::BN) g of the Diffie-Hellman parameters.
602  * DH#pub_key::
603  * The per-session public key (an OpenSSL::BN) matching the private key.
604  * This needs to be passed to DH#compute_key.
605  * DH#priv_key::
606  * The per-session private key, an OpenSSL::BN.
607  *
608  * === Example of a key exchange
609  * dh1 = OpenSSL::PKey::DH.new(2048)
610  * der = dh1.public_key.to_der #you may send this publicly to the participating party
611  * dh2 = OpenSSL::PKey::DH.new(der)
612  * dh2.generate_key! #generate the per-session key pair
613  * symm_key1 = dh1.compute_key(dh2.pub_key)
614  * symm_key2 = dh2.compute_key(dh1.pub_key)
615  *
616  * puts symm_key1 == symm_key2 # => true
617  */
619  rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1);
620  rb_define_method(cDH, "initialize", ossl_dh_initialize, -1);
621  rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1);
622  rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
623  rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
624  rb_define_method(cDH, "to_text", ossl_dh_to_text, 0);
625  rb_define_method(cDH, "export", ossl_dh_export, 0);
626  rb_define_alias(cDH, "to_pem", "export");
627  rb_define_alias(cDH, "to_s", "export");
628  rb_define_method(cDH, "to_der", ossl_dh_to_der, 0);
629  rb_define_method(cDH, "public_key", ossl_dh_to_public_key, 0);
630  rb_define_method(cDH, "params_ok?", ossl_dh_check_params, 0);
631  rb_define_method(cDH, "generate_key!", ossl_dh_generate_key, 0);
632  rb_define_method(cDH, "compute_key", ossl_dh_compute_key, 1);
633 
634  DEF_OSSL_PKEY_BN(cDH, dh, p);
635  DEF_OSSL_PKEY_BN(cDH, dh, q);
636  DEF_OSSL_PKEY_BN(cDH, dh, g);
639  rb_define_method(cDH, "set_pqg", ossl_dh_set_pqg, 3);
640  rb_define_method(cDH, "set_key", ossl_dh_set_key, 2);
641 
642  rb_define_method(cDH, "params", ossl_dh_get_params, 0);
643 }
644 
645 #else /* defined NO_DH */
646 void
647 Init_ossl_dh(void)
648 {
649 }
650 #endif /* NO_DH */
VALUE mOSSL
Definition: ossl.c:231
#define NewPKey(klass)
Definition: ossl_pkey.h:22
#define NUM2INT(x)
Definition: ruby.h:684
priv_key
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1716
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:835
VALUE mPKey
Definition: ossl_pkey.c:15
#define GetDH(obj, dh)
Definition: ossl_pkey_dh.c:20
VALUE ePKeyError
Definition: ossl_pkey.c:17
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
Definition: eval.c:821
#define SetPKey(obj, pkey)
Definition: ossl_pkey.h:24
#define Qtrue
Definition: ruby.h:437
#define ossl_str_adjust(str, p)
Definition: ossl.h:82
pub_key
BIO * ossl_obj2bio(volatile VALUE *pobj)
Definition: ossl_bio.c:13
void rb_str_set_len(VALUE, long)
Definition: string.c:2627
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:693
#define GetPKey(obj, pkey)
Definition: ossl_pkey.h:31
#define BN_GENCB_new()
VALUE ossl_membio2str(BIO *bio)
Definition: ossl_bio.c:29
VALUE eDHError
Definition: ossl_pkey_dh.c:30
VALUE ossl_dh_new(EVP_PKEY *pkey)
Definition: ossl_pkey_dh.c:58
#define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2)
Definition: ossl_pkey.h:228
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class
Definition: object.c:277
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:255
void ossl_generate_cb_stop(void *ptr)
Definition: ossl_pkey.c:50
void ossl_clear_error(void)
Definition: ossl.c:304
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:1616
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
#define OSSL_BIO_reset(bio)
Definition: ossl.h:110
#define GetBNPtr(obj)
Definition: ossl_bn.h:18
#define NIL_P(v)
Definition: ruby.h:451
#define DEF_OSSL_PKEY_BN(class, keytype, name)
Definition: ossl_pkey.h:234
VALUE eOSSLError
Definition: ossl.c:236
int argc
Definition: ruby.c:187
#define Qfalse
Definition: ruby.h:436
#define rb_str_new2
Definition: intern.h:835
void Init_ossl_dh(void)
Definition: ossl_pkey_dh.c:576
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1758
int ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
Definition: ossl_pkey.c:24
#define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3)
Definition: ossl_pkey.h:221
VALUE rb_hash_new(void)
Definition: hash.c:424
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1908
unsigned long VALUE
Definition: ruby.h:85
VALUE rb_eTypeError
Definition: error.c:801
register unsigned int len
Definition: zonetab.h:51
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:790
#define RSTRING_PTR(str)
Definition: ruby.h:975
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:293
#define BN_GENCB_free(cb)
VALUE ossl_bn_new(const BIGNUM *bn)
Definition: ossl_bn.c:58
VALUE cPKey
Definition: ossl_pkey.c:16
#define RB_INTEGER_TYPE_P(obj)
Definition: ruby_missing.h:15
#define NULL
Definition: _sdbm.c:102
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
VALUE cDH
Definition: ossl_pkey_dh.c:29
char ** argv
Definition: ruby.c:188
VALUE rb_str_new(const char *, long)
Definition: string.c:737