openssl 2.1.0.beta2 → 2.1.3
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/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)
|