openssl 2.2.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +32 -44
  3. data/History.md +103 -1
  4. data/ext/openssl/extconf.rb +24 -26
  5. data/ext/openssl/openssl_missing.c +0 -66
  6. data/ext/openssl/openssl_missing.h +26 -45
  7. data/ext/openssl/ossl.c +59 -46
  8. data/ext/openssl/ossl.h +20 -6
  9. data/ext/openssl/ossl_asn1.c +16 -4
  10. data/ext/openssl/ossl_bn.c +188 -126
  11. data/ext/openssl/ossl_cipher.c +11 -11
  12. data/ext/openssl/ossl_config.c +412 -41
  13. data/ext/openssl/ossl_config.h +4 -7
  14. data/ext/openssl/ossl_digest.c +9 -9
  15. data/ext/openssl/ossl_engine.c +16 -15
  16. data/ext/openssl/ossl_hmac.c +48 -135
  17. data/ext/openssl/ossl_kdf.c +8 -0
  18. data/ext/openssl/ossl_ocsp.c +3 -51
  19. data/ext/openssl/ossl_pkcs12.c +21 -3
  20. data/ext/openssl/ossl_pkcs7.c +42 -59
  21. data/ext/openssl/ossl_pkey.c +1102 -191
  22. data/ext/openssl/ossl_pkey.h +35 -72
  23. data/ext/openssl/ossl_pkey_dh.c +124 -334
  24. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  25. data/ext/openssl/ossl_pkey_ec.c +126 -318
  26. data/ext/openssl/ossl_pkey_rsa.c +100 -487
  27. data/ext/openssl/ossl_ssl.c +256 -355
  28. data/ext/openssl/ossl_ssl_session.c +24 -29
  29. data/ext/openssl/ossl_ts.c +35 -20
  30. data/ext/openssl/ossl_x509.c +0 -6
  31. data/ext/openssl/ossl_x509cert.c +164 -8
  32. data/ext/openssl/ossl_x509crl.c +10 -7
  33. data/ext/openssl/ossl_x509ext.c +1 -2
  34. data/ext/openssl/ossl_x509name.c +9 -2
  35. data/ext/openssl/ossl_x509req.c +10 -7
  36. data/ext/openssl/ossl_x509store.c +154 -70
  37. data/lib/openssl/buffering.rb +9 -0
  38. data/lib/openssl/hmac.rb +65 -0
  39. data/lib/openssl/pkey.rb +417 -0
  40. data/lib/openssl/ssl.rb +7 -7
  41. data/lib/openssl/version.rb +1 -1
  42. data/lib/openssl/x509.rb +22 -0
  43. data/lib/openssl.rb +0 -1
  44. metadata +4 -76
  45. data/ext/openssl/ruby_missing.h +0 -24
  46. data/lib/openssl/config.rb +0 -501
@@ -29,217 +29,105 @@
29
29
  VALUE cDH;
30
30
  VALUE eDHError;
31
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) {
72
- ossl_raise(eDHError, NULL);
73
- }
74
-
75
- return obj;
76
- }
77
-
78
32
  /*
79
33
  * Private
80
34
  */
81
- struct dh_blocking_gen_arg {
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. */
131
- ossl_clear_error();
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);
171
- ossl_raise(eDHError, NULL);
172
- }
173
-
174
- return obj;
175
- }
176
-
177
35
  /*
178
36
  * call-seq:
179
37
  * DH.new -> dh
180
38
  * DH.new(string) -> dh
181
39
  * DH.new(size [, generator]) -> dh
182
40
  *
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.
41
+ * Creates a new instance of OpenSSL::PKey::DH.
42
+ *
43
+ * If called without arguments, an empty instance without any parameter or key
44
+ * components is created. Use #set_pqg to manually set the parameters afterwards
45
+ * (and optionally #set_key to set private and public key components).
46
+ *
47
+ * If a String is given, tries to parse it as a DER- or PEM- encoded parameters.
48
+ * See also OpenSSL::PKey.read which can parse keys of any kinds.
49
+ *
50
+ * The DH.new(size [, generator]) form is an alias of DH.generate.
51
+ *
52
+ * +string+::
53
+ * A String that contains the DER or PEM encoded key.
54
+ * +size+::
55
+ * See DH.generate.
56
+ * +generator+::
57
+ * See DH.generate.
58
+ *
59
+ * Examples:
60
+ * # Creating an instance from scratch
61
+ * # Note that this is deprecated and will not work on OpenSSL 3.0 or later.
62
+ * dh = OpenSSL::PKey::DH.new
63
+ * dh.set_pqg(bn_p, nil, bn_g)
188
64
  *
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.
65
+ * # Generating a parameters and a key pair
66
+ * dh = OpenSSL::PKey::DH.new(2048) # An alias of OpenSSL::PKey::DH.generate(2048)
193
67
  *
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
68
+ * # Reading DH parameters
69
+ * dh_params = OpenSSL::PKey::DH.new(File.read('parameters.pem')) # loads parameters only
70
+ * dh = OpenSSL::PKey.generate_key(dh_params) # generates a key pair
201
71
  */
202
72
  static VALUE
203
73
  ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
204
74
  {
205
75
  EVP_PKEY *pkey;
76
+ int type;
206
77
  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))) {
220
- ossl_raise(eDHError, NULL);
221
- }
78
+ BIO *in = NULL;
79
+ VALUE arg;
80
+
81
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
82
+ if (pkey)
83
+ rb_raise(rb_eTypeError, "pkey already initialized");
84
+
85
+ /* The DH.new(size, generator) form is handled by lib/openssl/pkey.rb */
86
+ if (rb_scan_args(argc, argv, "01", &arg) == 0) {
87
+ dh = DH_new();
88
+ if (!dh)
89
+ ossl_raise(eDHError, "DH_new");
90
+ goto legacy;
222
91
  }
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) {
233
- ossl_raise(eDHError, NULL);
234
- }
92
+
93
+ arg = ossl_to_der_if_possible(arg);
94
+ in = ossl_obj2bio(&arg);
95
+
96
+ /*
97
+ * On OpenSSL <= 1.1.1 and current versions of LibreSSL, the generic
98
+ * routine does not support DER-encoded parameters
99
+ */
100
+ dh = d2i_DHparams_bio(in, NULL);
101
+ if (dh)
102
+ goto legacy;
103
+ OSSL_BIO_reset(in);
104
+
105
+ pkey = ossl_pkey_read_generic(in, Qnil);
106
+ BIO_free(in);
107
+ if (!pkey)
108
+ ossl_raise(eDHError, "could not parse pkey");
109
+
110
+ type = EVP_PKEY_base_id(pkey);
111
+ if (type != EVP_PKEY_DH) {
112
+ EVP_PKEY_free(pkey);
113
+ rb_raise(eDHError, "incorrect pkey type: %s", OBJ_nid2sn(type));
235
114
  }
236
- if (!EVP_PKEY_assign_DH(pkey, dh)) {
237
- DH_free(dh);
238
- ossl_raise(eDHError, NULL);
115
+ RTYPEDDATA_DATA(self) = pkey;
116
+ return self;
117
+
118
+ legacy:
119
+ BIO_free(in);
120
+ pkey = EVP_PKEY_new();
121
+ if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) {
122
+ EVP_PKEY_free(pkey);
123
+ DH_free(dh);
124
+ ossl_raise(eDHError, "EVP_PKEY_assign_DH");
239
125
  }
126
+ RTYPEDDATA_DATA(self) = pkey;
240
127
  return self;
241
128
  }
242
129
 
130
+ #ifndef HAVE_EVP_PKEY_DUP
243
131
  static VALUE
244
132
  ossl_dh_initialize_copy(VALUE self, VALUE other)
245
133
  {
@@ -247,15 +135,14 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
247
135
  DH *dh, *dh_other;
248
136
  const BIGNUM *pub, *priv;
249
137
 
250
- GetPKey(self, pkey);
251
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
252
- ossl_raise(eDHError, "DH already initialized");
138
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
139
+ if (pkey)
140
+ rb_raise(rb_eTypeError, "pkey already initialized");
253
141
  GetDH(other, dh_other);
254
142
 
255
143
  dh = DHparams_dup(dh_other);
256
144
  if (!dh)
257
145
  ossl_raise(eDHError, "DHparams_dup");
258
- EVP_PKEY_assign_DH(pkey, dh);
259
146
 
260
147
  DH_get0_key(dh_other, &pub, &priv);
261
148
  if (pub) {
@@ -270,8 +157,16 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
270
157
  DH_set0_key(dh, pub2, priv2);
271
158
  }
272
159
 
160
+ pkey = EVP_PKEY_new();
161
+ if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) {
162
+ EVP_PKEY_free(pkey);
163
+ DH_free(dh);
164
+ ossl_raise(eDHError, "EVP_PKEY_assign_DH");
165
+ }
166
+ RTYPEDDATA_DATA(self) = pkey;
273
167
  return self;
274
168
  }
169
+ #endif
275
170
 
276
171
  /*
277
172
  * call-seq:
@@ -403,72 +298,6 @@ ossl_dh_get_params(VALUE self)
403
298
  return hash;
404
299
  }
405
300
 
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()))) {
423
- ossl_raise(eDHError, NULL);
424
- }
425
- if (!DHparams_print(out, dh)) {
426
- BIO_free(out);
427
- ossl_raise(eDHError, NULL);
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);
466
- ossl_raise(eDHError, NULL);
467
- }
468
-
469
- return obj;
470
- }
471
-
472
301
  /*
473
302
  * call-seq:
474
303
  * dh.params_ok? -> true | false
@@ -476,80 +305,38 @@ ossl_dh_to_public_key(VALUE self)
476
305
  * Validates the Diffie-Hellman parameters associated with this instance.
477
306
  * It checks whether a safe prime and a suitable generator are used. If this
478
307
  * is not the case, +false+ is returned.
308
+ *
309
+ * See also the man page EVP_PKEY_param_check(3).
479
310
  */
480
311
  static VALUE
481
312
  ossl_dh_check_params(VALUE self)
482
313
  {
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
- }
314
+ int ret;
315
+ #ifdef HAVE_EVP_PKEY_CHECK
316
+ EVP_PKEY *pkey;
317
+ EVP_PKEY_CTX *pctx;
493
318
 
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
- {
319
+ GetPKey(self, pkey);
320
+ pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
321
+ if (!pctx)
322
+ ossl_raise(eDHError, "EVP_PKEY_CTX_new");
323
+ ret = EVP_PKEY_param_check(pctx);
324
+ EVP_PKEY_CTX_free(pctx);
325
+ #else
513
326
  DH *dh;
327
+ int codes;
514
328
 
515
329
  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;
330
+ ret = DH_check(dh, &codes) == 1 && codes == 0;
331
+ #endif
539
332
 
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) {
548
- ossl_raise(eDHError, NULL);
333
+ if (ret == 1)
334
+ return Qtrue;
335
+ else {
336
+ /* DH_check_ex() will put error entry on failure */
337
+ ossl_clear_error();
338
+ return Qfalse;
549
339
  }
550
- rb_str_set_len(str, len);
551
-
552
- return str;
553
340
  }
554
341
 
555
342
  /*
@@ -606,30 +393,33 @@ Init_ossl_dh(void)
606
393
  * The per-session private key, an OpenSSL::BN.
607
394
  *
608
395
  * === 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)
396
+ * # you may send the parameters (der) and own public key (pub1) publicly
397
+ * # to the participating party
398
+ * dh1 = OpenSSL::PKey::DH.new(2048)
399
+ * der = dh1.to_der
400
+ * pub1 = dh1.pub_key
615
401
  *
616
- * puts symm_key1 == symm_key2 # => true
402
+ * # the other party generates its per-session key pair
403
+ * dhparams = OpenSSL::PKey::DH.new(der)
404
+ * dh2 = OpenSSL::PKey.generate_key(dhparams)
405
+ * pub2 = dh2.pub_key
406
+ *
407
+ * symm_key1 = dh1.compute_key(pub2)
408
+ * symm_key2 = dh2.compute_key(pub1)
409
+ * puts symm_key1 == symm_key2 # => true
617
410
  */
618
411
  cDH = rb_define_class_under(mPKey, "DH", cPKey);
619
- rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1);
620
412
  rb_define_method(cDH, "initialize", ossl_dh_initialize, -1);
413
+ #ifndef HAVE_EVP_PKEY_DUP
621
414
  rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1);
415
+ #endif
622
416
  rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
623
417
  rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
624
- rb_define_method(cDH, "to_text", ossl_dh_to_text, 0);
625
418
  rb_define_method(cDH, "export", ossl_dh_export, 0);
626
419
  rb_define_alias(cDH, "to_pem", "export");
627
420
  rb_define_alias(cDH, "to_s", "export");
628
421
  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
422
  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
423
 
634
424
  DEF_OSSL_PKEY_BN(cDH, dh, p);
635
425
  DEF_OSSL_PKEY_BN(cDH, dh, q);