openssl 2.1.0.beta2 → 2.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +105 -2
- data/ext/openssl/deprecation.rb +5 -1
- data/ext/openssl/extconf.rb +34 -16
- data/ext/openssl/openssl_missing.h +3 -3
- data/ext/openssl/ossl.c +3 -2
- data/ext/openssl/ossl.h +1 -1
- data/ext/openssl/ossl_asn1.c +4 -3
- data/ext/openssl/ossl_bn.c +27 -14
- data/ext/openssl/ossl_cipher.c +2 -0
- data/ext/openssl/ossl_digest.c +6 -2
- data/ext/openssl/ossl_pkcs12.c +1 -0
- data/ext/openssl/ossl_pkcs7.c +1 -0
- data/ext/openssl/ossl_pkey.c +26 -3
- data/ext/openssl/ossl_pkey.h +6 -6
- data/ext/openssl/ossl_pkey_dh.c +1 -1
- data/ext/openssl/ossl_pkey_ec.c +72 -86
- data/ext/openssl/ossl_rand.c +0 -8
- data/ext/openssl/ossl_ssl.c +111 -38
- data/ext/openssl/ossl_version.h +1 -1
- data/ext/openssl/ossl_x509.c +91 -0
- data/ext/openssl/ossl_x509ext.c +1 -0
- data/ext/openssl/ossl_x509name.c +8 -7
- data/ext/openssl/ossl_x509store.c +40 -22
- data/lib/openssl/buffering.rb +5 -12
- data/lib/openssl/config.rb +36 -18
- data/lib/openssl/pkey.rb +23 -1
- data/lib/openssl/ssl.rb +6 -5
- metadata +22 -9
data/ext/openssl/ossl_pkey_ec.c
CHANGED
@@ -653,15 +653,15 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
|
|
653
653
|
StringValue(data);
|
654
654
|
StringValue(sig);
|
655
655
|
|
656
|
-
switch (ECDSA_verify(0, (unsigned char *)
|
657
|
-
|
658
|
-
|
659
|
-
|
656
|
+
switch (ECDSA_verify(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
|
657
|
+
(unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), ec)) {
|
658
|
+
case 1:
|
659
|
+
return Qtrue;
|
660
|
+
case 0:
|
661
|
+
return Qfalse;
|
662
|
+
default:
|
663
|
+
ossl_raise(eECError, "ECDSA_verify");
|
660
664
|
}
|
661
|
-
|
662
|
-
ossl_raise(eECError, "ECDSA_verify");
|
663
|
-
|
664
|
-
UNREACHABLE;
|
665
665
|
}
|
666
666
|
|
667
667
|
/*
|
@@ -1319,76 +1319,61 @@ ec_point_new(const EC_POINT *point, const EC_GROUP *group)
|
|
1319
1319
|
return obj;
|
1320
1320
|
}
|
1321
1321
|
|
1322
|
+
static VALUE ossl_ec_point_initialize_copy(VALUE, VALUE);
|
1322
1323
|
/*
|
1323
1324
|
* call-seq:
|
1324
1325
|
* OpenSSL::PKey::EC::Point.new(point)
|
1325
|
-
* OpenSSL::PKey::EC::Point.new(group)
|
1326
|
-
*
|
1326
|
+
* OpenSSL::PKey::EC::Point.new(group [, encoded_point])
|
1327
|
+
*
|
1328
|
+
* Creates a new instance of OpenSSL::PKey::EC::Point. If the only argument is
|
1329
|
+
* an instance of EC::Point, a copy is returned. Otherwise, creates a point
|
1330
|
+
* that belongs to _group_.
|
1327
1331
|
*
|
1328
|
-
*
|
1332
|
+
* _encoded_point_ is the octet string representation of the point. This
|
1333
|
+
* must be either a String or an OpenSSL::BN.
|
1329
1334
|
*/
|
1330
1335
|
static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
|
1331
1336
|
{
|
1332
1337
|
EC_POINT *point;
|
1333
|
-
VALUE
|
1334
|
-
|
1335
|
-
const EC_GROUP *group = NULL;
|
1338
|
+
VALUE group_v, arg2;
|
1339
|
+
const EC_GROUP *group;
|
1336
1340
|
|
1337
1341
|
TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point);
|
1338
1342
|
if (point)
|
1339
|
-
|
1340
|
-
|
1341
|
-
switch (rb_scan_args(argc, argv, "11", &arg1, &arg2)) {
|
1342
|
-
case 1:
|
1343
|
-
if (rb_obj_is_kind_of(arg1, cEC_POINT)) {
|
1344
|
-
const EC_POINT *arg_point;
|
1345
|
-
|
1346
|
-
group_v = rb_attr_get(arg1, id_i_group);
|
1347
|
-
GetECGroup(group_v, group);
|
1348
|
-
GetECPoint(arg1, arg_point);
|
1349
|
-
|
1350
|
-
point = EC_POINT_dup(arg_point, group);
|
1351
|
-
} else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
|
1352
|
-
group_v = arg1;
|
1353
|
-
GetECGroup(group_v, group);
|
1354
|
-
|
1355
|
-
point = EC_POINT_new(group);
|
1356
|
-
} else {
|
1357
|
-
ossl_raise(eEC_POINT, "wrong argument type: must be OpenSSL::PKey::EC::Point or OpenSSL::Pkey::EC::Group");
|
1358
|
-
}
|
1359
|
-
|
1360
|
-
break;
|
1361
|
-
case 2:
|
1362
|
-
if (!rb_obj_is_kind_of(arg1, cEC_GROUP))
|
1363
|
-
ossl_raise(rb_eArgError, "1st argument must be OpenSSL::PKey::EC::Group");
|
1364
|
-
group_v = arg1;
|
1365
|
-
GetECGroup(group_v, group);
|
1366
|
-
|
1367
|
-
if (rb_obj_is_kind_of(arg2, cBN)) {
|
1368
|
-
const BIGNUM *bn = GetBNPtr(arg2);
|
1369
|
-
|
1370
|
-
point = EC_POINT_bn2point(group, bn, NULL, ossl_bn_ctx);
|
1371
|
-
} else {
|
1372
|
-
BIO *in = ossl_obj2bio(&arg1);
|
1373
|
-
|
1374
|
-
/* BUG: finish me */
|
1375
|
-
|
1376
|
-
BIO_free(in);
|
1343
|
+
rb_raise(eEC_POINT, "EC_POINT already initialized");
|
1377
1344
|
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
default:
|
1384
|
-
ossl_raise(rb_eArgError, "wrong number of arguments");
|
1345
|
+
rb_scan_args(argc, argv, "11", &group_v, &arg2);
|
1346
|
+
if (rb_obj_is_kind_of(group_v, cEC_POINT)) {
|
1347
|
+
if (argc != 1)
|
1348
|
+
rb_raise(rb_eArgError, "invalid second argument");
|
1349
|
+
return ossl_ec_point_initialize_copy(self, group_v);
|
1385
1350
|
}
|
1386
1351
|
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1352
|
+
GetECGroup(group_v, group);
|
1353
|
+
if (argc == 1) {
|
1354
|
+
point = EC_POINT_new(group);
|
1355
|
+
if (!point)
|
1356
|
+
ossl_raise(eEC_POINT, "EC_POINT_new");
|
1357
|
+
}
|
1358
|
+
else {
|
1359
|
+
if (rb_obj_is_kind_of(arg2, cBN)) {
|
1360
|
+
point = EC_POINT_bn2point(group, GetBNPtr(arg2), NULL, ossl_bn_ctx);
|
1361
|
+
if (!point)
|
1362
|
+
ossl_raise(eEC_POINT, "EC_POINT_bn2point");
|
1363
|
+
}
|
1364
|
+
else {
|
1365
|
+
StringValue(arg2);
|
1366
|
+
point = EC_POINT_new(group);
|
1367
|
+
if (!point)
|
1368
|
+
ossl_raise(eEC_POINT, "EC_POINT_new");
|
1369
|
+
if (!EC_POINT_oct2point(group, point,
|
1370
|
+
(unsigned char *)RSTRING_PTR(arg2),
|
1371
|
+
RSTRING_LEN(arg2), ossl_bn_ctx)) {
|
1372
|
+
EC_POINT_free(point);
|
1373
|
+
ossl_raise(eEC_POINT, "EC_POINT_oct2point");
|
1374
|
+
}
|
1375
|
+
}
|
1376
|
+
}
|
1392
1377
|
|
1393
1378
|
RTYPEDDATA_DATA(self) = point;
|
1394
1379
|
rb_ivar_set(self, id_i_group, group_v);
|
@@ -1543,38 +1528,38 @@ static VALUE ossl_ec_point_set_to_infinity(VALUE self)
|
|
1543
1528
|
|
1544
1529
|
/*
|
1545
1530
|
* call-seq:
|
1546
|
-
*
|
1531
|
+
* point.to_octet_string(conversion_form) -> String
|
1532
|
+
*
|
1533
|
+
* Returns the octet string representation of the elliptic curve point.
|
1547
1534
|
*
|
1548
|
-
*
|
1549
|
-
* _conversion_form_ is given, the point data is converted using the specified
|
1550
|
-
* form. If not given, the default form set in the EC::Group object is used.
|
1535
|
+
* _conversion_form_ specifies how the point is converted. Possible values are:
|
1551
1536
|
*
|
1552
|
-
*
|
1537
|
+
* - +:compressed+
|
1538
|
+
* - +:uncompressed+
|
1539
|
+
* - +:hybrid+
|
1553
1540
|
*/
|
1554
1541
|
static VALUE
|
1555
|
-
|
1542
|
+
ossl_ec_point_to_octet_string(VALUE self, VALUE conversion_form)
|
1556
1543
|
{
|
1557
1544
|
EC_POINT *point;
|
1558
|
-
VALUE form_obj, bn_obj;
|
1559
1545
|
const EC_GROUP *group;
|
1560
1546
|
point_conversion_form_t form;
|
1561
|
-
|
1547
|
+
VALUE str;
|
1548
|
+
size_t len;
|
1562
1549
|
|
1563
1550
|
GetECPoint(self, point);
|
1564
1551
|
GetECPointGroup(self, group);
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
return bn_obj;
|
1552
|
+
form = parse_point_conversion_form_symbol(conversion_form);
|
1553
|
+
|
1554
|
+
len = EC_POINT_point2oct(group, point, form, NULL, 0, ossl_bn_ctx);
|
1555
|
+
if (!len)
|
1556
|
+
ossl_raise(eEC_POINT, "EC_POINT_point2oct");
|
1557
|
+
str = rb_str_new(NULL, (long)len);
|
1558
|
+
if (!EC_POINT_point2oct(group, point, form,
|
1559
|
+
(unsigned char *)RSTRING_PTR(str), len,
|
1560
|
+
ossl_bn_ctx))
|
1561
|
+
ossl_raise(eEC_POINT, "EC_POINT_point2oct");
|
1562
|
+
return str;
|
1578
1563
|
}
|
1579
1564
|
|
1580
1565
|
/*
|
@@ -1664,6 +1649,7 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
|
|
1664
1649
|
|
1665
1650
|
void Init_ossl_ec(void)
|
1666
1651
|
{
|
1652
|
+
#undef rb_intern
|
1667
1653
|
#if 0
|
1668
1654
|
mPKey = rb_define_module_under(mOSSL, "PKey");
|
1669
1655
|
cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
|
@@ -1799,7 +1785,7 @@ void Init_ossl_ec(void)
|
|
1799
1785
|
rb_define_method(cEC_POINT, "set_to_infinity!", ossl_ec_point_set_to_infinity, 0);
|
1800
1786
|
/* all the other methods */
|
1801
1787
|
|
1802
|
-
rb_define_method(cEC_POINT, "
|
1788
|
+
rb_define_method(cEC_POINT, "to_octet_string", ossl_ec_point_to_octet_string, 1);
|
1803
1789
|
rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1);
|
1804
1790
|
|
1805
1791
|
id_i_group = rb_intern("@group");
|
data/ext/openssl/ossl_rand.c
CHANGED
@@ -67,8 +67,6 @@ ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
|
|
67
67
|
static VALUE
|
68
68
|
ossl_rand_load_file(VALUE self, VALUE filename)
|
69
69
|
{
|
70
|
-
rb_check_safe_obj(filename);
|
71
|
-
|
72
70
|
if(!RAND_load_file(StringValueCStr(filename), -1)) {
|
73
71
|
ossl_raise(eRandomError, NULL);
|
74
72
|
}
|
@@ -86,8 +84,6 @@ ossl_rand_load_file(VALUE self, VALUE filename)
|
|
86
84
|
static VALUE
|
87
85
|
ossl_rand_write_file(VALUE self, VALUE filename)
|
88
86
|
{
|
89
|
-
rb_check_safe_obj(filename);
|
90
|
-
|
91
87
|
if (RAND_write_file(StringValueCStr(filename)) == -1) {
|
92
88
|
ossl_raise(eRandomError, NULL);
|
93
89
|
}
|
@@ -164,8 +160,6 @@ ossl_rand_pseudo_bytes(VALUE self, VALUE len)
|
|
164
160
|
static VALUE
|
165
161
|
ossl_rand_egd(VALUE self, VALUE filename)
|
166
162
|
{
|
167
|
-
rb_check_safe_obj(filename);
|
168
|
-
|
169
163
|
if (RAND_egd(StringValueCStr(filename)) == -1) {
|
170
164
|
ossl_raise(eRandomError, NULL);
|
171
165
|
}
|
@@ -186,8 +180,6 @@ ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
|
|
186
180
|
{
|
187
181
|
int n = NUM2INT(len);
|
188
182
|
|
189
|
-
rb_check_safe_obj(filename);
|
190
|
-
|
191
183
|
if (RAND_egd_bytes(StringValueCStr(filename), n) == -1) {
|
192
184
|
ossl_raise(eRandomError, NULL);
|
193
185
|
}
|
data/ext/openssl/ossl_ssl.c
CHANGED
@@ -13,6 +13,12 @@
|
|
13
13
|
|
14
14
|
#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
|
15
15
|
|
16
|
+
#if !defined(TLS1_3_VERSION) && \
|
17
|
+
defined(LIBRESSL_VERSION_NUMBER) && \
|
18
|
+
LIBRESSL_VERSION_NUMBER >= 0x3020000fL
|
19
|
+
# define TLS1_3_VERSION 0x0304
|
20
|
+
#endif
|
21
|
+
|
16
22
|
#ifdef _WIN32
|
17
23
|
# define TO_SOCKET(s) _get_osfhandle(s)
|
18
24
|
#else
|
@@ -33,7 +39,7 @@ static VALUE eSSLErrorWaitReadable;
|
|
33
39
|
static VALUE eSSLErrorWaitWritable;
|
34
40
|
|
35
41
|
static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
|
36
|
-
id_npn_protocols_encoded;
|
42
|
+
id_npn_protocols_encoded, id_each;
|
37
43
|
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
|
38
44
|
|
39
45
|
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
|
@@ -53,6 +59,13 @@ static int ossl_sslctx_ex_ptr_idx;
|
|
53
59
|
static int ossl_sslctx_ex_store_p;
|
54
60
|
#endif
|
55
61
|
|
62
|
+
static void
|
63
|
+
ossl_sslctx_mark(void *ptr)
|
64
|
+
{
|
65
|
+
SSL_CTX *ctx = ptr;
|
66
|
+
rb_gc_mark((VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx));
|
67
|
+
}
|
68
|
+
|
56
69
|
static void
|
57
70
|
ossl_sslctx_free(void *ptr)
|
58
71
|
{
|
@@ -67,7 +80,7 @@ ossl_sslctx_free(void *ptr)
|
|
67
80
|
static const rb_data_type_t ossl_sslctx_type = {
|
68
81
|
"OpenSSL/SSL/CTX",
|
69
82
|
{
|
70
|
-
|
83
|
+
ossl_sslctx_mark, ossl_sslctx_free,
|
71
84
|
},
|
72
85
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
73
86
|
};
|
@@ -184,8 +197,10 @@ ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
|
|
184
197
|
|
185
198
|
for (i = 0; i < numberof(options_map); i++) {
|
186
199
|
sum |= options_map[i].opts;
|
187
|
-
|
200
|
+
if ((min && min > options_map[i].ver) ||
|
201
|
+
(max && max < options_map[i].ver)) {
|
188
202
|
opts |= options_map[i].opts;
|
203
|
+
}
|
189
204
|
}
|
190
205
|
SSL_CTX_clear_options(ctx, sum);
|
191
206
|
SSL_CTX_set_options(ctx, opts);
|
@@ -357,7 +372,14 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|
357
372
|
rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
|
358
373
|
return 0;
|
359
374
|
}
|
360
|
-
|
375
|
+
if (ret != Qtrue) {
|
376
|
+
preverify_ok = 0;
|
377
|
+
#if defined(X509_V_ERR_HOSTNAME_MISMATCH)
|
378
|
+
X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
|
379
|
+
#else
|
380
|
+
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
|
381
|
+
#endif
|
382
|
+
}
|
361
383
|
}
|
362
384
|
|
363
385
|
return ossl_verify_cb_call(cb, preverify_ok, ctx);
|
@@ -377,9 +399,8 @@ ossl_call_session_get_cb(VALUE ary)
|
|
377
399
|
return rb_funcallv(cb, id_call, 1, &ary);
|
378
400
|
}
|
379
401
|
|
380
|
-
/* this method is currently only called for servers (in OpenSSL <= 0.9.8e) */
|
381
402
|
static SSL_SESSION *
|
382
|
-
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
403
|
+
#if (!defined(LIBRESSL_VERSION_NUMBER) ? OPENSSL_VERSION_NUMBER >= 0x10100000 : LIBRESSL_VERSION_NUMBER >= 0x2080000f)
|
383
404
|
ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
|
384
405
|
#else
|
385
406
|
ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
|
@@ -591,7 +612,7 @@ ssl_renegotiation_cb(const SSL *ssl)
|
|
591
612
|
#if !defined(OPENSSL_NO_NEXTPROTONEG) || \
|
592
613
|
defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
|
593
614
|
static VALUE
|
594
|
-
ssl_npn_encode_protocol_i(
|
615
|
+
ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
|
595
616
|
{
|
596
617
|
int len = RSTRING_LENINT(cur);
|
597
618
|
char len_byte;
|
@@ -608,7 +629,7 @@ static VALUE
|
|
608
629
|
ssl_encode_npn_protocols(VALUE protocols)
|
609
630
|
{
|
610
631
|
VALUE encoded = rb_str_new(NULL, 0);
|
611
|
-
|
632
|
+
rb_block_call(protocols, id_each, 0, 0, ssl_npn_encode_protocol_i, encoded);
|
612
633
|
return encoded;
|
613
634
|
}
|
614
635
|
|
@@ -678,7 +699,7 @@ static int
|
|
678
699
|
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
|
679
700
|
void *arg)
|
680
701
|
{
|
681
|
-
VALUE protocols = (VALUE)arg;
|
702
|
+
VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded);
|
682
703
|
|
683
704
|
*out = (const unsigned char *) RSTRING_PTR(protocols);
|
684
705
|
*outlen = RSTRING_LENINT(protocols);
|
@@ -896,7 +917,7 @@ ossl_sslctx_setup(VALUE self)
|
|
896
917
|
if (!NIL_P(val)) {
|
897
918
|
VALUE encoded = ssl_encode_npn_protocols(val);
|
898
919
|
rb_ivar_set(self, id_npn_protocols_encoded, encoded);
|
899
|
-
SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)
|
920
|
+
SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
|
900
921
|
OSSL_Debug("SSL NPN advertise callback added");
|
901
922
|
}
|
902
923
|
if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
|
@@ -1035,10 +1056,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
|
1035
1056
|
}
|
1036
1057
|
|
1037
1058
|
GetSSLCTX(self, ctx);
|
1038
|
-
if(!ctx){
|
1039
|
-
ossl_raise(eSSLError, "SSL_CTX is not initialized.");
|
1040
|
-
return Qnil;
|
1041
|
-
}
|
1042
1059
|
if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) {
|
1043
1060
|
ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
|
1044
1061
|
}
|
@@ -1518,6 +1535,14 @@ ssl_started(SSL *ssl)
|
|
1518
1535
|
return SSL_get_fd(ssl) >= 0;
|
1519
1536
|
}
|
1520
1537
|
|
1538
|
+
static void
|
1539
|
+
ossl_ssl_mark(void *ptr)
|
1540
|
+
{
|
1541
|
+
SSL *ssl = ptr;
|
1542
|
+
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
|
1543
|
+
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
|
1544
|
+
}
|
1545
|
+
|
1521
1546
|
static void
|
1522
1547
|
ossl_ssl_free(void *ssl)
|
1523
1548
|
{
|
@@ -1527,7 +1552,7 @@ ossl_ssl_free(void *ssl)
|
|
1527
1552
|
const rb_data_type_t ossl_ssl_type = {
|
1528
1553
|
"OpenSSL/SSL",
|
1529
1554
|
{
|
1530
|
-
|
1555
|
+
ossl_ssl_mark, ossl_ssl_free,
|
1531
1556
|
},
|
1532
1557
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
1533
1558
|
};
|
@@ -1683,6 +1708,11 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|
1683
1708
|
rb_io_wait_readable(fptr->fd);
|
1684
1709
|
continue;
|
1685
1710
|
case SSL_ERROR_SYSCALL:
|
1711
|
+
#ifdef __APPLE__
|
1712
|
+
/* See ossl_ssl_write_internal() */
|
1713
|
+
if (errno == EPROTOTYPE)
|
1714
|
+
continue;
|
1715
|
+
#endif
|
1686
1716
|
if (errno) rb_sys_fail(funcname);
|
1687
1717
|
ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
|
1688
1718
|
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
@@ -1831,7 +1861,6 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1831
1861
|
else
|
1832
1862
|
rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
|
1833
1863
|
}
|
1834
|
-
OBJ_TAINT(str);
|
1835
1864
|
rb_str_set_len(str, 0);
|
1836
1865
|
if (ilen == 0)
|
1837
1866
|
return str;
|
@@ -1840,26 +1869,36 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1840
1869
|
io = rb_attr_get(self, id_i_io);
|
1841
1870
|
GetOpenFile(io, fptr);
|
1842
1871
|
if (ssl_started(ssl)) {
|
1843
|
-
|
1872
|
+
rb_str_locktmp(str);
|
1873
|
+
for (;;) {
|
1844
1874
|
nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
|
1845
1875
|
switch(ssl_get_error(ssl, nread)){
|
1846
1876
|
case SSL_ERROR_NONE:
|
1877
|
+
rb_str_unlocktmp(str);
|
1847
1878
|
goto end;
|
1848
1879
|
case SSL_ERROR_ZERO_RETURN:
|
1880
|
+
rb_str_unlocktmp(str);
|
1849
1881
|
if (no_exception_p(opts)) { return Qnil; }
|
1850
1882
|
rb_eof_error();
|
1851
1883
|
case SSL_ERROR_WANT_WRITE:
|
1852
|
-
|
1853
|
-
|
1884
|
+
if (nonblock) {
|
1885
|
+
rb_str_unlocktmp(str);
|
1886
|
+
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1887
|
+
write_would_block(nonblock);
|
1888
|
+
}
|
1854
1889
|
rb_io_wait_writable(fptr->fd);
|
1855
1890
|
continue;
|
1856
1891
|
case SSL_ERROR_WANT_READ:
|
1857
|
-
|
1858
|
-
|
1892
|
+
if (nonblock) {
|
1893
|
+
rb_str_unlocktmp(str);
|
1894
|
+
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1895
|
+
read_would_block(nonblock);
|
1896
|
+
}
|
1859
1897
|
rb_io_wait_readable(fptr->fd);
|
1860
1898
|
continue;
|
1861
1899
|
case SSL_ERROR_SYSCALL:
|
1862
1900
|
if (!ERR_peek_error()) {
|
1901
|
+
rb_str_unlocktmp(str);
|
1863
1902
|
if (errno)
|
1864
1903
|
rb_sys_fail(0);
|
1865
1904
|
else {
|
@@ -1874,19 +1913,32 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1874
1913
|
rb_eof_error();
|
1875
1914
|
}
|
1876
1915
|
}
|
1916
|
+
/* fall through */
|
1877
1917
|
default:
|
1918
|
+
rb_str_unlocktmp(str);
|
1878
1919
|
ossl_raise(eSSLError, "SSL_read");
|
1879
1920
|
}
|
1880
1921
|
}
|
1881
1922
|
}
|
1882
1923
|
else {
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1924
|
+
ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
|
1925
|
+
|
1926
|
+
rb_warning("SSL session is not started yet.");
|
1927
|
+
#if defined(RB_PASS_KEYWORDS)
|
1928
|
+
if (nonblock) {
|
1929
|
+
VALUE argv[3];
|
1930
|
+
argv[0] = len;
|
1931
|
+
argv[1] = str;
|
1932
|
+
argv[2] = opts;
|
1933
|
+
return rb_funcallv_kw(io, meth, 3, argv, RB_PASS_KEYWORDS);
|
1934
|
+
}
|
1935
|
+
#else
|
1936
|
+
if (nonblock) {
|
1937
|
+
return rb_funcall(io, meth, 3, len, str, opts);
|
1938
|
+
}
|
1939
|
+
#endif
|
1940
|
+
else
|
1941
|
+
return rb_funcall(io, meth, 2, len, str);
|
1890
1942
|
}
|
1891
1943
|
|
1892
1944
|
end:
|
@@ -1934,21 +1986,21 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|
1934
1986
|
int nwrite = 0;
|
1935
1987
|
rb_io_t *fptr;
|
1936
1988
|
int nonblock = opts != Qfalse;
|
1937
|
-
VALUE io;
|
1989
|
+
VALUE tmp, io;
|
1938
1990
|
|
1939
|
-
StringValue(str);
|
1991
|
+
tmp = rb_str_new_frozen(StringValue(str));
|
1940
1992
|
GetSSL(self, ssl);
|
1941
1993
|
io = rb_attr_get(self, id_i_io);
|
1942
1994
|
GetOpenFile(io, fptr);
|
1943
1995
|
if (ssl_started(ssl)) {
|
1944
|
-
for (;;){
|
1945
|
-
int num = RSTRING_LENINT(
|
1996
|
+
for (;;) {
|
1997
|
+
int num = RSTRING_LENINT(tmp);
|
1946
1998
|
|
1947
1999
|
/* SSL_write(3ssl) manpage states num == 0 is undefined */
|
1948
2000
|
if (num == 0)
|
1949
2001
|
goto end;
|
1950
2002
|
|
1951
|
-
nwrite = SSL_write(ssl, RSTRING_PTR(
|
2003
|
+
nwrite = SSL_write(ssl, RSTRING_PTR(tmp), num);
|
1952
2004
|
switch(ssl_get_error(ssl, nwrite)){
|
1953
2005
|
case SSL_ERROR_NONE:
|
1954
2006
|
goto end;
|
@@ -1963,6 +2015,16 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|
1963
2015
|
rb_io_wait_readable(fptr->fd);
|
1964
2016
|
continue;
|
1965
2017
|
case SSL_ERROR_SYSCALL:
|
2018
|
+
#ifdef __APPLE__
|
2019
|
+
/*
|
2020
|
+
* It appears that send syscall can return EPROTOTYPE if the
|
2021
|
+
* socket is being torn down. Retry to get a proper errno to
|
2022
|
+
* make the error handling in line with the socket library.
|
2023
|
+
* [Bug #14713] https://bugs.ruby-lang.org/issues/14713
|
2024
|
+
*/
|
2025
|
+
if (errno == EPROTOTYPE)
|
2026
|
+
continue;
|
2027
|
+
#endif
|
1966
2028
|
if (errno) rb_sys_fail(0);
|
1967
2029
|
default:
|
1968
2030
|
ossl_raise(eSSLError, "SSL_write");
|
@@ -1973,11 +2035,21 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|
1973
2035
|
ID meth = nonblock ?
|
1974
2036
|
rb_intern("write_nonblock") : rb_intern("syswrite");
|
1975
2037
|
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
2038
|
+
rb_warning("SSL session is not started yet.");
|
2039
|
+
#if defined(RB_PASS_KEYWORDS)
|
2040
|
+
if (nonblock) {
|
2041
|
+
VALUE argv[2];
|
2042
|
+
argv[0] = str;
|
2043
|
+
argv[1] = opts;
|
2044
|
+
return rb_funcallv_kw(io, meth, 2, argv, RB_PASS_KEYWORDS);
|
2045
|
+
}
|
2046
|
+
#else
|
2047
|
+
if (nonblock) {
|
2048
|
+
return rb_funcall(io, meth, 2, str, opts);
|
2049
|
+
}
|
2050
|
+
#endif
|
2051
|
+
else
|
2052
|
+
return rb_funcall(io, meth, 1, str);
|
1981
2053
|
}
|
1982
2054
|
|
1983
2055
|
end:
|
@@ -2920,6 +2992,7 @@ Init_ossl_ssl(void)
|
|
2920
2992
|
id_tmp_dh_callback = rb_intern("tmp_dh_callback");
|
2921
2993
|
id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
|
2922
2994
|
id_npn_protocols_encoded = rb_intern("npn_protocols_encoded");
|
2995
|
+
id_each = rb_intern_const("each");
|
2923
2996
|
|
2924
2997
|
#define DefIVarID(name) do \
|
2925
2998
|
id_i_##name = rb_intern("@"#name); while (0)
|