openssl 2.0.0.beta.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of openssl might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +1 -1
- data/History.md +4 -1
- data/README.md +4 -8
- data/ext/openssl/extconf.rb +0 -6
- data/ext/openssl/ossl.c +27 -88
- data/ext/openssl/ossl.h +3 -39
- data/ext/openssl/ossl_asn1.c +69 -129
- data/ext/openssl/ossl_bio.c +0 -3
- data/ext/openssl/ossl_bn.c +9 -8
- data/ext/openssl/ossl_cipher.c +39 -40
- data/ext/openssl/ossl_digest.c +22 -15
- data/ext/openssl/ossl_engine.c +1 -18
- data/ext/openssl/ossl_ns_spki.c +1 -6
- data/ext/openssl/ossl_pkcs7.c +1 -1
- data/ext/openssl/ossl_pkey.c +75 -32
- data/ext/openssl/ossl_pkey.h +0 -1
- data/ext/openssl/ossl_pkey_dh.c +1 -1
- data/ext/openssl/ossl_pkey_dsa.c +2 -4
- data/ext/openssl/ossl_pkey_ec.c +39 -25
- data/ext/openssl/ossl_pkey_rsa.c +5 -7
- data/ext/openssl/ossl_ssl.c +105 -79
- data/ext/openssl/ossl_ssl_session.c +19 -36
- data/ext/openssl/ossl_x509.h +6 -3
- data/ext/openssl/ossl_x509cert.c +1 -1
- data/ext/openssl/ossl_x509crl.c +5 -24
- data/ext/openssl/ossl_x509name.c +3 -5
- data/ext/openssl/ossl_x509req.c +4 -18
- data/ext/openssl/ossl_x509store.c +83 -25
- data/ext/openssl/ruby_missing.h +0 -9
- data/lib/openssl/buffering.rb +9 -1
- data/lib/openssl/ssl.rb +8 -12
- metadata +17 -17
data/ext/openssl/ossl_pkey.h
CHANGED
@@ -48,7 +48,6 @@ int ossl_generate_cb_2(int p, int n, BN_GENCB *cb);
|
|
48
48
|
void ossl_generate_cb_stop(void *ptr);
|
49
49
|
|
50
50
|
VALUE ossl_pkey_new(EVP_PKEY *);
|
51
|
-
VALUE ossl_pkey_new_from_file(VALUE);
|
52
51
|
EVP_PKEY *GetPKeyPtr(VALUE);
|
53
52
|
EVP_PKEY *DupPKeyPtr(VALUE);
|
54
53
|
EVP_PKEY *GetPrivPKeyPtr(VALUE);
|
data/ext/openssl/ossl_pkey_dh.c
CHANGED
@@ -460,7 +460,7 @@ ossl_dh_to_public_key(VALUE self)
|
|
460
460
|
|
461
461
|
GetDH(self, orig_dh);
|
462
462
|
dh = DHparams_dup(orig_dh); /* err check perfomed by dh_instance */
|
463
|
-
obj = dh_instance(
|
463
|
+
obj = dh_instance(rb_obj_class(self), dh);
|
464
464
|
if (obj == Qfalse) {
|
465
465
|
DH_free(dh);
|
466
466
|
ossl_raise(eDHError, NULL);
|
data/ext/openssl/ossl_pkey_dsa.c
CHANGED
@@ -491,7 +491,7 @@ ossl_dsa_to_public_key(VALUE self)
|
|
491
491
|
(i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa))
|
492
492
|
dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey));
|
493
493
|
#undef DSAPublicKey_dup
|
494
|
-
obj = dsa_instance(
|
494
|
+
obj = dsa_instance(rb_obj_class(self), dsa);
|
495
495
|
if (obj == Qfalse) {
|
496
496
|
DSA_free(dsa);
|
497
497
|
ossl_raise(eDSAError, NULL);
|
@@ -499,8 +499,6 @@ ossl_dsa_to_public_key(VALUE self)
|
|
499
499
|
return obj;
|
500
500
|
}
|
501
501
|
|
502
|
-
#define ossl_dsa_buf_size(dsa) (DSA_size(dsa) + 16)
|
503
|
-
|
504
502
|
/*
|
505
503
|
* call-seq:
|
506
504
|
* dsa.syssign(string) -> aString
|
@@ -535,7 +533,7 @@ ossl_dsa_sign(VALUE self, VALUE data)
|
|
535
533
|
if (!DSA_PRIVATE(self, dsa))
|
536
534
|
ossl_raise(eDSAError, "Private DSA key needed!");
|
537
535
|
StringValue(data);
|
538
|
-
str = rb_str_new(0,
|
536
|
+
str = rb_str_new(0, DSA_size(dsa));
|
539
537
|
if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
|
540
538
|
(unsigned char *)RSTRING_PTR(str),
|
541
539
|
&buf_len, dsa)) { /* type is ignored (0) */
|
data/ext/openssl/ossl_pkey_ec.c
CHANGED
@@ -643,11 +643,10 @@ static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data)
|
|
643
643
|
if (EC_KEY_get0_private_key(ec) == NULL)
|
644
644
|
ossl_raise(eECError, "Private EC key needed!");
|
645
645
|
|
646
|
-
str = rb_str_new(0, ECDSA_size(ec)
|
646
|
+
str = rb_str_new(0, ECDSA_size(ec));
|
647
647
|
if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1)
|
648
|
-
|
649
|
-
|
650
|
-
rb_str_resize(str, buf_len);
|
648
|
+
ossl_raise(eECError, "ECDSA_sign");
|
649
|
+
rb_str_set_len(str, buf_len);
|
651
650
|
|
652
651
|
return str;
|
653
652
|
}
|
@@ -1106,6 +1105,22 @@ static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
|
|
1106
1105
|
return ID2SYM(ret);
|
1107
1106
|
}
|
1108
1107
|
|
1108
|
+
static point_conversion_form_t
|
1109
|
+
parse_point_conversion_form_symbol(VALUE sym)
|
1110
|
+
{
|
1111
|
+
ID id = SYM2ID(sym);
|
1112
|
+
|
1113
|
+
if (id == ID_uncompressed)
|
1114
|
+
return POINT_CONVERSION_UNCOMPRESSED;
|
1115
|
+
else if (id == ID_compressed)
|
1116
|
+
return POINT_CONVERSION_COMPRESSED;
|
1117
|
+
else if (id == ID_hybrid)
|
1118
|
+
return POINT_CONVERSION_HYBRID;
|
1119
|
+
else
|
1120
|
+
ossl_raise(rb_eArgError, "unsupported point conversion form %+"PRIsVALUE
|
1121
|
+
" (expected :compressed, :uncompressed, or :hybrid)", sym);
|
1122
|
+
}
|
1123
|
+
|
1109
1124
|
/*
|
1110
1125
|
* call-seq:
|
1111
1126
|
* group.point_conversion_form = form
|
@@ -1125,23 +1140,14 @@ static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
|
|
1125
1140
|
*
|
1126
1141
|
* See the OpenSSL documentation for EC_GROUP_set_point_conversion_form()
|
1127
1142
|
*/
|
1128
|
-
static VALUE
|
1143
|
+
static VALUE
|
1144
|
+
ossl_ec_group_set_point_conversion_form(VALUE self, VALUE form_v)
|
1129
1145
|
{
|
1130
|
-
EC_GROUP *group
|
1146
|
+
EC_GROUP *group;
|
1131
1147
|
point_conversion_form_t form;
|
1132
|
-
ID form_id = SYM2ID(form_v);
|
1133
1148
|
|
1134
1149
|
GetECGroup(self, group);
|
1135
|
-
|
1136
|
-
if (form_id == ID_uncompressed) {
|
1137
|
-
form = POINT_CONVERSION_UNCOMPRESSED;
|
1138
|
-
} else if (form_id == ID_compressed) {
|
1139
|
-
form = POINT_CONVERSION_COMPRESSED;
|
1140
|
-
} else if (form_id == ID_hybrid) {
|
1141
|
-
form = POINT_CONVERSION_HYBRID;
|
1142
|
-
} else {
|
1143
|
-
ossl_raise(rb_eArgError, "form must be :compressed, :uncompressed, or :hybrid");
|
1144
|
-
}
|
1150
|
+
form = parse_point_conversion_form_symbol(form_v);
|
1145
1151
|
|
1146
1152
|
EC_GROUP_set_point_conversion_form(group, form);
|
1147
1153
|
|
@@ -1191,7 +1197,7 @@ static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed)
|
|
1191
1197
|
|
1192
1198
|
/*
|
1193
1199
|
* call-seq:
|
1194
|
-
* group.degree =>
|
1200
|
+
* group.degree => integer
|
1195
1201
|
*
|
1196
1202
|
* See the OpenSSL documentation for EC_GROUP_get_degree()
|
1197
1203
|
*/
|
@@ -1549,22 +1555,30 @@ static VALUE ossl_ec_point_set_to_infinity(VALUE self)
|
|
1549
1555
|
|
1550
1556
|
/*
|
1551
1557
|
* call-seq:
|
1552
|
-
* point.to_bn
|
1558
|
+
* point.to_bn(conversion_form = nil) => OpenSSL::BN
|
1559
|
+
*
|
1560
|
+
* Convert the EC point into an octet string and store in an OpenSSL::BN. If
|
1561
|
+
* +conversion_form+ is given, the point data is converted using the specified
|
1562
|
+
* form. If not given, the default form set in the EC::Group object is used.
|
1553
1563
|
*
|
1554
|
-
*
|
1564
|
+
* See also EC::Point#point_conversion_form=.
|
1555
1565
|
*/
|
1556
|
-
static VALUE
|
1566
|
+
static VALUE
|
1567
|
+
ossl_ec_point_to_bn(int argc, VALUE *argv, VALUE self)
|
1557
1568
|
{
|
1558
1569
|
EC_POINT *point;
|
1559
|
-
VALUE bn_obj;
|
1570
|
+
VALUE form_obj, bn_obj;
|
1560
1571
|
const EC_GROUP *group;
|
1561
1572
|
point_conversion_form_t form;
|
1562
1573
|
BIGNUM *bn;
|
1563
1574
|
|
1564
1575
|
GetECPoint(self, point);
|
1565
1576
|
GetECPointGroup(self, group);
|
1566
|
-
|
1567
|
-
|
1577
|
+
rb_scan_args(argc, argv, "01", &form_obj);
|
1578
|
+
if (NIL_P(form_obj))
|
1579
|
+
form = EC_GROUP_get_point_conversion_form(group);
|
1580
|
+
else
|
1581
|
+
form = parse_point_conversion_form_symbol(form_obj);
|
1568
1582
|
|
1569
1583
|
bn_obj = rb_obj_alloc(cBN);
|
1570
1584
|
bn = GetBNPtr(bn_obj);
|
@@ -1793,7 +1807,7 @@ void Init_ossl_ec(void)
|
|
1793
1807
|
rb_define_method(cEC_POINT, "set_to_infinity!", ossl_ec_point_set_to_infinity, 0);
|
1794
1808
|
/* all the other methods */
|
1795
1809
|
|
1796
|
-
rb_define_method(cEC_POINT, "to_bn", ossl_ec_point_to_bn,
|
1810
|
+
rb_define_method(cEC_POINT, "to_bn", ossl_ec_point_to_bn, -1);
|
1797
1811
|
rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1);
|
1798
1812
|
|
1799
1813
|
id_i_group = rb_intern("@group");
|
data/ext/openssl/ossl_pkey_rsa.c
CHANGED
@@ -404,8 +404,6 @@ ossl_rsa_to_der(VALUE self)
|
|
404
404
|
return str;
|
405
405
|
}
|
406
406
|
|
407
|
-
#define ossl_rsa_buf_size(rsa) (RSA_size(rsa)+16)
|
408
|
-
|
409
407
|
/*
|
410
408
|
* call-seq:
|
411
409
|
* rsa.public_encrypt(string) => String
|
@@ -429,7 +427,7 @@ ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
|
|
429
427
|
rb_scan_args(argc, argv, "11", &buffer, &padding);
|
430
428
|
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
|
431
429
|
StringValue(buffer);
|
432
|
-
str = rb_str_new(0,
|
430
|
+
str = rb_str_new(0, RSA_size(rsa));
|
433
431
|
buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
|
434
432
|
(unsigned char *)RSTRING_PTR(str), rsa, pad);
|
435
433
|
if (buf_len < 0) ossl_raise(eRSAError, NULL);
|
@@ -461,7 +459,7 @@ ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
|
|
461
459
|
rb_scan_args(argc, argv, "11", &buffer, &padding);
|
462
460
|
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
|
463
461
|
StringValue(buffer);
|
464
|
-
str = rb_str_new(0,
|
462
|
+
str = rb_str_new(0, RSA_size(rsa));
|
465
463
|
buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
|
466
464
|
(unsigned char *)RSTRING_PTR(str), rsa, pad);
|
467
465
|
if (buf_len < 0) ossl_raise(eRSAError, NULL);
|
@@ -495,7 +493,7 @@ ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
|
|
495
493
|
rb_scan_args(argc, argv, "11", &buffer, &padding);
|
496
494
|
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
|
497
495
|
StringValue(buffer);
|
498
|
-
str = rb_str_new(0,
|
496
|
+
str = rb_str_new(0, RSA_size(rsa));
|
499
497
|
buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
|
500
498
|
(unsigned char *)RSTRING_PTR(str), rsa, pad);
|
501
499
|
if (buf_len < 0) ossl_raise(eRSAError, NULL);
|
@@ -529,7 +527,7 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
|
|
529
527
|
rb_scan_args(argc, argv, "11", &buffer, &padding);
|
530
528
|
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
|
531
529
|
StringValue(buffer);
|
532
|
-
str = rb_str_new(0,
|
530
|
+
str = rb_str_new(0, RSA_size(rsa));
|
533
531
|
buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
|
534
532
|
(unsigned char *)RSTRING_PTR(str), rsa, pad);
|
535
533
|
if (buf_len < 0) ossl_raise(eRSAError, NULL);
|
@@ -620,7 +618,7 @@ ossl_rsa_to_public_key(VALUE self)
|
|
620
618
|
GetPKeyRSA(self, pkey);
|
621
619
|
/* err check performed by rsa_instance */
|
622
620
|
rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey));
|
623
|
-
obj = rsa_instance(
|
621
|
+
obj = rsa_instance(rb_obj_class(self), rsa);
|
624
622
|
if (obj == Qfalse) {
|
625
623
|
RSA_free(rsa);
|
626
624
|
ossl_raise(eRSAError, NULL);
|
data/ext/openssl/ossl_ssl.c
CHANGED
@@ -11,10 +11,6 @@
|
|
11
11
|
*/
|
12
12
|
#include "ossl.h"
|
13
13
|
|
14
|
-
#if defined(HAVE_UNISTD_H)
|
15
|
-
# include <unistd.h> /* for read(), and write() */
|
16
|
-
#endif
|
17
|
-
|
18
14
|
#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
|
19
15
|
|
20
16
|
#ifdef _WIN32
|
@@ -36,7 +32,7 @@ VALUE cSSLSocket;
|
|
36
32
|
static VALUE eSSLErrorWaitReadable;
|
37
33
|
static VALUE eSSLErrorWaitWritable;
|
38
34
|
|
39
|
-
static ID ID_callback_state;
|
35
|
+
static ID ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback;
|
40
36
|
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
|
41
37
|
|
42
38
|
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
|
@@ -223,69 +219,90 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
|
223
219
|
return 1;
|
224
220
|
}
|
225
221
|
|
226
|
-
#if !defined(OPENSSL_NO_DH)
|
227
|
-
|
228
|
-
|
222
|
+
#if !defined(OPENSSL_NO_DH) || \
|
223
|
+
!defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
224
|
+
struct tmp_dh_callback_args {
|
225
|
+
VALUE ssl_obj;
|
226
|
+
ID id;
|
227
|
+
int type;
|
228
|
+
int is_export;
|
229
|
+
int keylength;
|
230
|
+
};
|
231
|
+
|
232
|
+
static EVP_PKEY *
|
233
|
+
ossl_call_tmp_dh_callback(struct tmp_dh_callback_args *args)
|
229
234
|
{
|
230
235
|
VALUE cb, dh;
|
231
236
|
EVP_PKEY *pkey;
|
232
237
|
|
233
|
-
cb = rb_funcall(
|
234
|
-
|
235
|
-
|
236
|
-
dh =
|
238
|
+
cb = rb_funcall(args->ssl_obj, args->id, 0);
|
239
|
+
if (NIL_P(cb))
|
240
|
+
return NULL;
|
241
|
+
dh = rb_funcall(cb, rb_intern("call"), 3,
|
242
|
+
args->ssl_obj, INT2NUM(args->is_export), INT2NUM(args->keylength));
|
237
243
|
pkey = GetPKeyPtr(dh);
|
238
|
-
if (EVP_PKEY_base_id(pkey) !=
|
244
|
+
if (EVP_PKEY_base_id(pkey) != args->type)
|
245
|
+
return NULL;
|
239
246
|
|
240
|
-
return
|
247
|
+
return pkey;
|
241
248
|
}
|
249
|
+
#endif
|
242
250
|
|
243
|
-
|
251
|
+
#if !defined(OPENSSL_NO_DH)
|
252
|
+
static DH *
|
244
253
|
ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
245
254
|
{
|
246
|
-
VALUE
|
255
|
+
VALUE rb_ssl;
|
256
|
+
EVP_PKEY *pkey;
|
257
|
+
struct tmp_dh_callback_args args;
|
258
|
+
int state;
|
247
259
|
|
248
260
|
rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
261
|
+
args.ssl_obj = rb_ssl;
|
262
|
+
args.id = id_tmp_dh_callback;
|
263
|
+
args.is_export = is_export;
|
264
|
+
args.keylength = keylength;
|
265
|
+
args.type = EVP_PKEY_DH;
|
266
|
+
|
267
|
+
pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
|
268
|
+
(VALUE)&args, &state);
|
269
|
+
if (state) {
|
270
|
+
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
271
|
+
return NULL;
|
272
|
+
}
|
273
|
+
if (!pkey)
|
274
|
+
return NULL;
|
249
275
|
|
250
|
-
|
251
|
-
|
252
|
-
dh = rb_protect(ossl_call_tmp_dh_callback, args, NULL);
|
253
|
-
if (!RTEST(dh)) return NULL;
|
254
|
-
|
255
|
-
return EVP_PKEY_get0_DH(GetPKeyPtr(dh));
|
276
|
+
return EVP_PKEY_get0_DH(pkey);
|
256
277
|
}
|
257
278
|
#endif /* OPENSSL_NO_DH */
|
258
279
|
|
259
280
|
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
260
|
-
static
|
261
|
-
ossl_call_tmp_ecdh_callback(VALUE args)
|
262
|
-
{
|
263
|
-
VALUE cb, ecdh;
|
264
|
-
EVP_PKEY *pkey;
|
265
|
-
|
266
|
-
cb = rb_funcall(rb_ary_entry(args, 0), rb_intern("tmp_ecdh_callback"), 0);
|
267
|
-
|
268
|
-
if (NIL_P(cb)) return Qfalse;
|
269
|
-
ecdh = rb_apply(cb, rb_intern("call"), args);
|
270
|
-
pkey = GetPKeyPtr(ecdh);
|
271
|
-
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) return Qfalse;
|
272
|
-
|
273
|
-
return ecdh;
|
274
|
-
}
|
275
|
-
|
276
|
-
static EC_KEY*
|
281
|
+
static EC_KEY *
|
277
282
|
ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
|
278
283
|
{
|
279
|
-
VALUE
|
284
|
+
VALUE rb_ssl;
|
285
|
+
EVP_PKEY *pkey;
|
286
|
+
struct tmp_dh_callback_args args;
|
287
|
+
int state;
|
280
288
|
|
281
289
|
rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
290
|
+
args.ssl_obj = rb_ssl;
|
291
|
+
args.id = id_tmp_ecdh_callback;
|
292
|
+
args.is_export = is_export;
|
293
|
+
args.keylength = keylength;
|
294
|
+
args.type = EVP_PKEY_EC;
|
295
|
+
|
296
|
+
pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
|
297
|
+
(VALUE)&args, &state);
|
298
|
+
if (state) {
|
299
|
+
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
300
|
+
return NULL;
|
301
|
+
}
|
302
|
+
if (!pkey)
|
303
|
+
return NULL;
|
282
304
|
|
283
|
-
|
284
|
-
|
285
|
-
ecdh = rb_protect(ossl_call_tmp_ecdh_callback, args, NULL);
|
286
|
-
if (!RTEST(ecdh)) return NULL;
|
287
|
-
|
288
|
-
return EVP_PKEY_get0_EC_KEY(GetPKeyPtr(ecdh));
|
305
|
+
return EVP_PKEY_get0_EC_KEY(pkey);
|
289
306
|
}
|
290
307
|
#endif
|
291
308
|
|
@@ -636,7 +653,11 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
|
|
636
653
|
{
|
637
654
|
VALUE selected;
|
638
655
|
int status;
|
639
|
-
struct npn_select_cb_common_args args
|
656
|
+
struct npn_select_cb_common_args args;
|
657
|
+
|
658
|
+
args.cb = cb;
|
659
|
+
args.in = in;
|
660
|
+
args.inlen = inlen;
|
640
661
|
|
641
662
|
selected = rb_protect(npn_select_cb_common_i, (VALUE)&args, &status);
|
642
663
|
if (status) {
|
@@ -1372,24 +1393,6 @@ ssl_started(SSL *ssl)
|
|
1372
1393
|
return SSL_get_fd(ssl) >= 0;
|
1373
1394
|
}
|
1374
1395
|
|
1375
|
-
static void
|
1376
|
-
ossl_ssl_shutdown(SSL *ssl)
|
1377
|
-
{
|
1378
|
-
int i;
|
1379
|
-
|
1380
|
-
/* 4 is from SSL_smart_shutdown() of mod_ssl.c (v2.2.19) */
|
1381
|
-
/* It says max 2x pending + 2x data = 4 */
|
1382
|
-
for (i = 0; i < 4; ++i) {
|
1383
|
-
/*
|
1384
|
-
* Ignore the case SSL_shutdown returns -1. Empty handshake_func
|
1385
|
-
* must not happen.
|
1386
|
-
*/
|
1387
|
-
if (SSL_shutdown(ssl) != 0)
|
1388
|
-
break;
|
1389
|
-
}
|
1390
|
-
ossl_clear_error();
|
1391
|
-
}
|
1392
|
-
|
1393
1396
|
static void
|
1394
1397
|
ossl_ssl_free(void *ssl)
|
1395
1398
|
{
|
@@ -1492,19 +1495,15 @@ ossl_ssl_setup(VALUE self)
|
|
1492
1495
|
static void
|
1493
1496
|
write_would_block(int nonblock)
|
1494
1497
|
{
|
1495
|
-
if (nonblock)
|
1496
|
-
|
1497
|
-
rb_exc_raise(exc);
|
1498
|
-
}
|
1498
|
+
if (nonblock)
|
1499
|
+
ossl_raise(eSSLErrorWaitWritable, "write would block");
|
1499
1500
|
}
|
1500
1501
|
|
1501
1502
|
static void
|
1502
1503
|
read_would_block(int nonblock)
|
1503
1504
|
{
|
1504
|
-
if (nonblock)
|
1505
|
-
|
1506
|
-
rb_exc_raise(exc);
|
1507
|
-
}
|
1505
|
+
if (nonblock)
|
1506
|
+
ossl_raise(eSSLErrorWaitReadable, "read would block");
|
1508
1507
|
}
|
1509
1508
|
|
1510
1509
|
static int
|
@@ -1710,11 +1709,21 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1710
1709
|
rb_io_wait_readable(FPTR_TO_FD(fptr));
|
1711
1710
|
continue;
|
1712
1711
|
case SSL_ERROR_SYSCALL:
|
1713
|
-
if(ERR_peek_error()
|
1714
|
-
if (
|
1715
|
-
|
1712
|
+
if (!ERR_peek_error()) {
|
1713
|
+
if (errno)
|
1714
|
+
rb_sys_fail(0);
|
1715
|
+
else {
|
1716
|
+
/*
|
1717
|
+
* The underlying BIO returned 0. This is actually a
|
1718
|
+
* protocol error. But unfortunately, not all
|
1719
|
+
* implementations cleanly shutdown the TLS connection
|
1720
|
+
* but just shutdown/close the TCP connection. So report
|
1721
|
+
* EOF for now...
|
1722
|
+
*/
|
1723
|
+
if (no_exception_p(opts)) { return Qnil; }
|
1724
|
+
rb_eof_error();
|
1725
|
+
}
|
1716
1726
|
}
|
1717
|
-
rb_sys_fail(0);
|
1718
1727
|
default:
|
1719
1728
|
ossl_raise(eSSLError, "SSL_read");
|
1720
1729
|
}
|
@@ -1867,11 +1876,24 @@ static VALUE
|
|
1867
1876
|
ossl_ssl_stop(VALUE self)
|
1868
1877
|
{
|
1869
1878
|
SSL *ssl;
|
1879
|
+
int ret;
|
1870
1880
|
|
1871
1881
|
GetSSL(self, ssl);
|
1882
|
+
if (!ssl_started(ssl))
|
1883
|
+
return Qnil;
|
1884
|
+
ret = SSL_shutdown(ssl);
|
1885
|
+
if (ret == 1) /* Have already received close_notify */
|
1886
|
+
return Qnil;
|
1887
|
+
if (ret == 0) /* Sent close_notify, but we don't wait for reply */
|
1888
|
+
return Qnil;
|
1872
1889
|
|
1873
|
-
|
1874
|
-
|
1890
|
+
/*
|
1891
|
+
* XXX: Something happened. Possibly it failed because the underlying socket
|
1892
|
+
* is not writable/readable, since it is in non-blocking mode. We should do
|
1893
|
+
* some proper error handling using SSL_get_error() and maybe retry, but we
|
1894
|
+
* can't block here. Give up for now.
|
1895
|
+
*/
|
1896
|
+
ossl_clear_error();
|
1875
1897
|
return Qnil;
|
1876
1898
|
}
|
1877
1899
|
|
@@ -2521,6 +2543,7 @@ Init_ossl_ssl(void)
|
|
2521
2543
|
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
|
2522
2544
|
|
2523
2545
|
rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
|
2546
|
+
rb_define_alias(cSSLContext, "freeze", "setup");
|
2524
2547
|
|
2525
2548
|
/*
|
2526
2549
|
* No session caching for client or server
|
@@ -2687,6 +2710,9 @@ Init_ossl_ssl(void)
|
|
2687
2710
|
sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
|
2688
2711
|
sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
|
2689
2712
|
|
2713
|
+
id_tmp_dh_callback = rb_intern("tmp_dh_callback");
|
2714
|
+
id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
|
2715
|
+
|
2690
2716
|
#define DefIVarID(name) do \
|
2691
2717
|
id_i_##name = rb_intern("@"#name); while (0)
|
2692
2718
|
|