openssl 2.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +426 -0
  4. data/README.md +38 -21
  5. data/ext/openssl/extconf.rb +132 -72
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +62 -46
  8. data/ext/openssl/ossl.c +177 -252
  9. data/ext/openssl/ossl.h +39 -17
  10. data/ext/openssl/ossl_asn1.c +53 -14
  11. data/ext/openssl/ossl_bn.c +288 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +42 -32
  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 +32 -63
  17. data/ext/openssl/ossl_engine.c +19 -28
  18. data/ext/openssl/ossl_hmac.c +61 -146
  19. data/ext/openssl/ossl_kdf.c +15 -23
  20. data/ext/openssl/ossl_ns_spki.c +2 -2
  21. data/ext/openssl/ossl_ocsp.c +17 -70
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +23 -4
  24. data/ext/openssl/ossl_pkcs7.c +49 -81
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1508 -195
  27. data/ext/openssl/ossl_pkey.h +41 -78
  28. data/ext/openssl/ossl_pkey_dh.c +153 -348
  29. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  30. data/ext/openssl/ossl_pkey_ec.c +257 -343
  31. data/ext/openssl/ossl_pkey_rsa.c +166 -490
  32. data/ext/openssl/ossl_provider.c +211 -0
  33. data/ext/openssl/ossl_provider.h +5 -0
  34. data/ext/openssl/ossl_rand.c +2 -40
  35. data/ext/openssl/ossl_ssl.c +666 -456
  36. data/ext/openssl/ossl_ssl_session.c +29 -30
  37. data/ext/openssl/ossl_ts.c +1539 -0
  38. data/ext/openssl/ossl_ts.h +16 -0
  39. data/ext/openssl/ossl_x509.c +86 -1
  40. data/ext/openssl/ossl_x509attr.c +1 -1
  41. data/ext/openssl/ossl_x509cert.c +170 -14
  42. data/ext/openssl/ossl_x509crl.c +14 -11
  43. data/ext/openssl/ossl_x509ext.c +29 -9
  44. data/ext/openssl/ossl_x509name.c +24 -12
  45. data/ext/openssl/ossl_x509req.c +14 -11
  46. data/ext/openssl/ossl_x509revoked.c +4 -4
  47. data/ext/openssl/ossl_x509store.c +205 -96
  48. data/lib/openssl/bn.rb +1 -1
  49. data/lib/openssl/buffering.rb +42 -20
  50. data/lib/openssl/cipher.rb +1 -1
  51. data/lib/openssl/digest.rb +10 -16
  52. data/lib/openssl/hmac.rb +78 -0
  53. data/lib/openssl/marshal.rb +30 -0
  54. data/lib/openssl/pkcs5.rb +1 -1
  55. data/lib/openssl/pkey.rb +447 -1
  56. data/lib/openssl/ssl.rb +68 -24
  57. data/lib/openssl/version.rb +5 -0
  58. data/lib/openssl/x509.rb +177 -1
  59. data/lib/openssl.rb +24 -9
  60. metadata +18 -71
  61. data/ext/openssl/deprecation.rb +0 -23
  62. data/ext/openssl/ossl_version.h +0 -15
  63. data/ext/openssl/ruby_missing.h +0 -24
  64. data/lib/openssl/config.rb +0 -474
@@ -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,22 +135,21 @@ 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) {
262
149
  BIGNUM *pub2 = BN_dup(pub);
263
150
  BIGNUM *priv2 = BN_dup(priv);
264
151
 
265
- if (!pub2 || priv && !priv2) {
152
+ if (!pub2 || (priv && !priv2)) {
266
153
  BN_clear_free(pub2);
267
154
  BN_clear_free(priv2);
268
155
  ossl_raise(eDHError, "BN_dup");
@@ -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);