openssl 2.2.0 → 3.2.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +33 -45
  3. data/History.md +300 -0
  4. data/README.md +36 -19
  5. data/ext/openssl/extconf.rb +119 -79
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +26 -45
  8. data/ext/openssl/ossl.c +131 -233
  9. data/ext/openssl/ossl.h +31 -12
  10. data/ext/openssl/ossl_asn1.c +26 -13
  11. data/ext/openssl/ossl_bn.c +279 -143
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +13 -14
  14. data/ext/openssl/ossl_config.c +412 -41
  15. data/ext/openssl/ossl_config.h +4 -7
  16. data/ext/openssl/ossl_digest.c +16 -12
  17. data/ext/openssl/ossl_engine.c +17 -16
  18. data/ext/openssl/ossl_hmac.c +57 -136
  19. data/ext/openssl/ossl_kdf.c +12 -4
  20. data/ext/openssl/ossl_ns_spki.c +1 -1
  21. data/ext/openssl/ossl_ocsp.c +11 -59
  22. data/ext/openssl/ossl_pkcs12.c +22 -4
  23. data/ext/openssl/ossl_pkcs7.c +45 -62
  24. data/ext/openssl/ossl_pkey.c +1320 -196
  25. data/ext/openssl/ossl_pkey.h +36 -73
  26. data/ext/openssl/ossl_pkey_dh.c +152 -347
  27. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  28. data/ext/openssl/ossl_pkey_ec.c +227 -343
  29. data/ext/openssl/ossl_pkey_rsa.c +159 -491
  30. data/ext/openssl/ossl_provider.c +211 -0
  31. data/ext/openssl/ossl_provider.h +5 -0
  32. data/ext/openssl/ossl_ssl.c +593 -467
  33. data/ext/openssl/ossl_ssl_session.c +29 -30
  34. data/ext/openssl/ossl_ts.c +67 -42
  35. data/ext/openssl/ossl_x509.c +0 -6
  36. data/ext/openssl/ossl_x509attr.c +1 -1
  37. data/ext/openssl/ossl_x509cert.c +168 -12
  38. data/ext/openssl/ossl_x509crl.c +14 -11
  39. data/ext/openssl/ossl_x509ext.c +14 -9
  40. data/ext/openssl/ossl_x509name.c +10 -3
  41. data/ext/openssl/ossl_x509req.c +14 -11
  42. data/ext/openssl/ossl_x509revoked.c +4 -4
  43. data/ext/openssl/ossl_x509store.c +204 -94
  44. data/lib/openssl/buffering.rb +10 -4
  45. data/lib/openssl/digest.rb +1 -5
  46. data/lib/openssl/hmac.rb +65 -0
  47. data/lib/openssl/pkey.rb +429 -0
  48. data/lib/openssl/ssl.rb +23 -18
  49. data/lib/openssl/version.rb +1 -1
  50. data/lib/openssl/x509.rb +22 -0
  51. data/lib/openssl.rb +0 -1
  52. metadata +13 -68
  53. data/ext/openssl/ruby_missing.h +0 -24
  54. 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.
188
42
  *
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.
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).
193
46
  *
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
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)
64
+ *
65
+ * # Generating a parameters and a key pair
66
+ * dh = OpenSSL::PKey::DH.new(2048) # An alias of OpenSSL::PKey::DH.generate(2048)
67
+ *
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:
@@ -283,7 +178,7 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
283
178
  static VALUE
284
179
  ossl_dh_is_public(VALUE self)
285
180
  {
286
- DH *dh;
181
+ OSSL_3_const DH *dh;
287
182
  const BIGNUM *bn;
288
183
 
289
184
  GetDH(self, dh);
@@ -302,14 +197,14 @@ ossl_dh_is_public(VALUE self)
302
197
  static VALUE
303
198
  ossl_dh_is_private(VALUE self)
304
199
  {
305
- DH *dh;
200
+ OSSL_3_const DH *dh;
306
201
  const BIGNUM *bn;
307
202
 
308
203
  GetDH(self, dh);
309
204
  DH_get0_key(dh, NULL, &bn);
310
205
 
311
206
  #if !defined(OPENSSL_NO_ENGINE)
312
- return (bn || DH_get0_engine(dh)) ? Qtrue : Qfalse;
207
+ return (bn || DH_get0_engine((DH *)dh)) ? Qtrue : Qfalse;
313
208
  #else
314
209
  return bn ? Qtrue : Qfalse;
315
210
  #endif
@@ -321,14 +216,25 @@ ossl_dh_is_private(VALUE self)
321
216
  * dh.to_pem -> aString
322
217
  * dh.to_s -> aString
323
218
  *
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.
219
+ * Serializes the DH parameters to a PEM-encoding.
220
+ *
221
+ * Note that any existing per-session public/private keys will *not* get
222
+ * encoded, just the Diffie-Hellman parameters will be encoded.
223
+ *
224
+ * PEM-encoded parameters will look like:
225
+ *
226
+ * -----BEGIN DH PARAMETERS-----
227
+ * [...]
228
+ * -----END DH PARAMETERS-----
229
+ *
230
+ * See also #public_to_pem (X.509 SubjectPublicKeyInfo) and
231
+ * #private_to_pem (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for
232
+ * serialization with the private or public key components.
327
233
  */
328
234
  static VALUE
329
235
  ossl_dh_export(VALUE self)
330
236
  {
331
- DH *dh;
237
+ OSSL_3_const DH *dh;
332
238
  BIO *out;
333
239
  VALUE str;
334
240
 
@@ -349,15 +255,19 @@ ossl_dh_export(VALUE self)
349
255
  * call-seq:
350
256
  * dh.to_der -> aString
351
257
  *
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
-
258
+ * Serializes the DH parameters to a DER-encoding
259
+ *
260
+ * Note that any existing per-session public/private keys will *not* get
261
+ * encoded, just the Diffie-Hellman parameters will be encoded.
262
+ *
263
+ * See also #public_to_der (X.509 SubjectPublicKeyInfo) and
264
+ * #private_to_der (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for
265
+ * serialization with the private or public key components.
356
266
  */
357
267
  static VALUE
358
268
  ossl_dh_to_der(VALUE self)
359
269
  {
360
- DH *dh;
270
+ OSSL_3_const DH *dh;
361
271
  unsigned char *p;
362
272
  long len;
363
273
  VALUE str;
@@ -385,7 +295,7 @@ ossl_dh_to_der(VALUE self)
385
295
  static VALUE
386
296
  ossl_dh_get_params(VALUE self)
387
297
  {
388
- DH *dh;
298
+ OSSL_3_const DH *dh;
389
299
  VALUE hash;
390
300
  const BIGNUM *p, *q, *g, *pub_key, *priv_key;
391
301
 
@@ -403,72 +313,6 @@ ossl_dh_get_params(VALUE self)
403
313
  return hash;
404
314
  }
405
315
 
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
316
  /*
473
317
  * call-seq:
474
318
  * dh.params_ok? -> true | false
@@ -476,80 +320,38 @@ ossl_dh_to_public_key(VALUE self)
476
320
  * Validates the Diffie-Hellman parameters associated with this instance.
477
321
  * It checks whether a safe prime and a suitable generator are used. If this
478
322
  * is not the case, +false+ is returned.
323
+ *
324
+ * See also the man page EVP_PKEY_param_check(3).
479
325
  */
480
326
  static VALUE
481
327
  ossl_dh_check_params(VALUE self)
482
328
  {
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
- }
329
+ int ret;
330
+ #ifdef HAVE_EVP_PKEY_CHECK
331
+ EVP_PKEY *pkey;
332
+ EVP_PKEY_CTX *pctx;
493
333
 
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
- {
334
+ GetPKey(self, pkey);
335
+ pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
336
+ if (!pctx)
337
+ ossl_raise(eDHError, "EVP_PKEY_CTX_new");
338
+ ret = EVP_PKEY_param_check(pctx);
339
+ EVP_PKEY_CTX_free(pctx);
340
+ #else
513
341
  DH *dh;
342
+ int codes;
514
343
 
515
344
  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;
345
+ ret = DH_check(dh, &codes) == 1 && codes == 0;
346
+ #endif
539
347
 
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);
348
+ if (ret == 1)
349
+ return Qtrue;
350
+ else {
351
+ /* DH_check_ex() will put error entry on failure */
352
+ ossl_clear_error();
353
+ return Qfalse;
549
354
  }
550
- rb_str_set_len(str, len);
551
-
552
- return str;
553
355
  }
554
356
 
555
357
  /*
@@ -606,30 +408,33 @@ Init_ossl_dh(void)
606
408
  * The per-session private key, an OpenSSL::BN.
607
409
  *
608
410
  * === 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)
411
+ * # you may send the parameters (der) and own public key (pub1) publicly
412
+ * # to the participating party
413
+ * dh1 = OpenSSL::PKey::DH.new(2048)
414
+ * der = dh1.to_der
415
+ * pub1 = dh1.pub_key
615
416
  *
616
- * puts symm_key1 == symm_key2 # => true
417
+ * # the other party generates its per-session key pair
418
+ * dhparams = OpenSSL::PKey::DH.new(der)
419
+ * dh2 = OpenSSL::PKey.generate_key(dhparams)
420
+ * pub2 = dh2.pub_key
421
+ *
422
+ * symm_key1 = dh1.compute_key(pub2)
423
+ * symm_key2 = dh2.compute_key(pub1)
424
+ * puts symm_key1 == symm_key2 # => true
617
425
  */
618
426
  cDH = rb_define_class_under(mPKey, "DH", cPKey);
619
- rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1);
620
427
  rb_define_method(cDH, "initialize", ossl_dh_initialize, -1);
428
+ #ifndef HAVE_EVP_PKEY_DUP
621
429
  rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1);
430
+ #endif
622
431
  rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
623
432
  rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
624
- rb_define_method(cDH, "to_text", ossl_dh_to_text, 0);
625
433
  rb_define_method(cDH, "export", ossl_dh_export, 0);
626
434
  rb_define_alias(cDH, "to_pem", "export");
627
435
  rb_define_alias(cDH, "to_s", "export");
628
436
  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
437
  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
438
 
634
439
  DEF_OSSL_PKEY_BN(cDH, dh, p);
635
440
  DEF_OSSL_PKEY_BN(cDH, dh, q);