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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +33 -45
- data/History.md +300 -0
- data/README.md +36 -19
- data/ext/openssl/extconf.rb +119 -79
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +26 -45
- data/ext/openssl/ossl.c +131 -233
- data/ext/openssl/ossl.h +31 -12
- data/ext/openssl/ossl_asn1.c +26 -13
- data/ext/openssl/ossl_bn.c +279 -143
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +13 -14
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +16 -12
- data/ext/openssl/ossl_engine.c +17 -16
- data/ext/openssl/ossl_hmac.c +57 -136
- data/ext/openssl/ossl_kdf.c +12 -4
- data/ext/openssl/ossl_ns_spki.c +1 -1
- data/ext/openssl/ossl_ocsp.c +11 -59
- data/ext/openssl/ossl_pkcs12.c +22 -4
- data/ext/openssl/ossl_pkcs7.c +45 -62
- data/ext/openssl/ossl_pkey.c +1320 -196
- data/ext/openssl/ossl_pkey.h +36 -73
- data/ext/openssl/ossl_pkey_dh.c +152 -347
- data/ext/openssl/ossl_pkey_dsa.c +157 -413
- data/ext/openssl/ossl_pkey_ec.c +227 -343
- data/ext/openssl/ossl_pkey_rsa.c +159 -491
- data/ext/openssl/ossl_provider.c +211 -0
- data/ext/openssl/ossl_provider.h +5 -0
- data/ext/openssl/ossl_ssl.c +593 -467
- data/ext/openssl/ossl_ssl_session.c +29 -30
- data/ext/openssl/ossl_ts.c +67 -42
- data/ext/openssl/ossl_x509.c +0 -6
- data/ext/openssl/ossl_x509attr.c +1 -1
- data/ext/openssl/ossl_x509cert.c +168 -12
- data/ext/openssl/ossl_x509crl.c +14 -11
- data/ext/openssl/ossl_x509ext.c +14 -9
- data/ext/openssl/ossl_x509name.c +10 -3
- data/ext/openssl/ossl_x509req.c +14 -11
- data/ext/openssl/ossl_x509revoked.c +4 -4
- data/ext/openssl/ossl_x509store.c +204 -94
- data/lib/openssl/buffering.rb +10 -4
- data/lib/openssl/digest.rb +1 -5
- data/lib/openssl/hmac.rb +65 -0
- data/lib/openssl/pkey.rb +429 -0
- data/lib/openssl/ssl.rb +23 -18
- data/lib/openssl/version.rb +1 -1
- data/lib/openssl/x509.rb +22 -0
- data/lib/openssl.rb +0 -1
- metadata +13 -68
- data/ext/openssl/ruby_missing.h +0 -24
- data/lib/openssl/config.rb +0 -501
data/ext/openssl/ossl_pkey_dh.c
CHANGED
@@ -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
|
-
*
|
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
|
-
*
|
190
|
-
*
|
191
|
-
*
|
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
|
-
*
|
195
|
-
*
|
196
|
-
*
|
197
|
-
*
|
198
|
-
*
|
199
|
-
*
|
200
|
-
*
|
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
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
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
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
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
|
-
|
237
|
-
|
238
|
-
|
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
|
-
|
251
|
-
if (
|
252
|
-
|
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
|
-
*
|
325
|
-
*
|
326
|
-
*
|
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
|
-
*
|
353
|
-
*
|
354
|
-
*
|
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
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
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
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
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
|
-
|
517
|
-
|
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
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
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
|
-
*
|
610
|
-
*
|
611
|
-
*
|
612
|
-
*
|
613
|
-
*
|
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
|
-
*
|
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);
|