openssl 3.0.2 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +1 -1
- data/History.md +76 -0
- data/README.md +36 -19
- data/ext/openssl/extconf.rb +89 -55
- data/ext/openssl/ossl.c +73 -195
- data/ext/openssl/ossl.h +11 -6
- data/ext/openssl/ossl_asn1.c +11 -10
- data/ext/openssl/ossl_bn.c +25 -13
- data/ext/openssl/ossl_cipher.c +2 -3
- data/ext/openssl/ossl_config.c +1 -1
- data/ext/openssl/ossl_digest.c +1 -1
- data/ext/openssl/ossl_engine.c +1 -1
- data/ext/openssl/ossl_hmac.c +1 -1
- data/ext/openssl/ossl_kdf.c +4 -4
- data/ext/openssl/ossl_ns_spki.c +1 -1
- data/ext/openssl/ossl_ocsp.c +8 -8
- data/ext/openssl/ossl_pkcs12.c +1 -1
- data/ext/openssl/ossl_pkcs7.c +3 -3
- data/ext/openssl/ossl_pkey.c +219 -46
- data/ext/openssl/ossl_pkey.h +1 -1
- data/ext/openssl/ossl_pkey_dh.c +28 -13
- data/ext/openssl/ossl_pkey_dsa.c +64 -15
- data/ext/openssl/ossl_pkey_ec.c +73 -17
- data/ext/openssl/ossl_pkey_rsa.c +74 -19
- data/ext/openssl/ossl_provider.c +211 -0
- data/ext/openssl/ossl_provider.h +5 -0
- data/ext/openssl/ossl_ssl.c +292 -113
- data/ext/openssl/ossl_ssl_session.c +5 -1
- data/ext/openssl/ossl_ts.c +3 -3
- data/ext/openssl/ossl_x509attr.c +1 -1
- data/ext/openssl/ossl_x509cert.c +1 -1
- data/ext/openssl/ossl_x509crl.c +1 -1
- data/ext/openssl/ossl_x509ext.c +13 -7
- data/ext/openssl/ossl_x509name.c +1 -1
- data/ext/openssl/ossl_x509req.c +1 -1
- data/ext/openssl/ossl_x509revoked.c +1 -1
- data/ext/openssl/ossl_x509store.c +12 -5
- data/lib/openssl/buffering.rb +2 -5
- data/lib/openssl/digest.rb +1 -5
- data/lib/openssl/pkey.rb +8 -4
- data/lib/openssl/ssl.rb +15 -10
- data/lib/openssl/version.rb +1 -1
- metadata +9 -6
data/ext/openssl/ossl_ssl.c
CHANGED
@@ -11,11 +11,15 @@
|
|
11
11
|
*/
|
12
12
|
#include "ossl.h"
|
13
13
|
|
14
|
+
#ifndef OPENSSL_NO_SOCK
|
14
15
|
#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
|
15
16
|
|
17
|
+
#if !defined(OPENSSL_NO_NEXTPROTONEG) && !OSSL_IS_LIBRESSL
|
18
|
+
# define OSSL_USE_NEXTPROTONEG
|
19
|
+
#endif
|
20
|
+
|
16
21
|
#if !defined(TLS1_3_VERSION) && \
|
17
|
-
|
18
|
-
LIBRESSL_VERSION_NUMBER >= 0x3020000fL
|
22
|
+
OSSL_LIBRESSL_PREREQ(3, 2, 0) && !OSSL_LIBRESSL_PREREQ(3, 4, 0)
|
19
23
|
# define TLS1_3_VERSION 0x0304
|
20
24
|
#endif
|
21
25
|
|
@@ -30,7 +34,6 @@
|
|
30
34
|
} while (0)
|
31
35
|
|
32
36
|
VALUE mSSL;
|
33
|
-
static VALUE mSSLExtConfig;
|
34
37
|
static VALUE eSSLError;
|
35
38
|
VALUE cSSLContext;
|
36
39
|
VALUE cSSLSocket;
|
@@ -49,7 +52,7 @@ static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
|
|
49
52
|
id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
|
50
53
|
id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
|
51
54
|
id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
|
52
|
-
id_i_verify_hostname;
|
55
|
+
id_i_verify_hostname, id_i_keylog_cb;
|
53
56
|
static ID id_i_io, id_i_context, id_i_hostname;
|
54
57
|
|
55
58
|
static int ossl_ssl_ex_vcb_idx;
|
@@ -74,7 +77,7 @@ static const rb_data_type_t ossl_sslctx_type = {
|
|
74
77
|
{
|
75
78
|
ossl_sslctx_mark, ossl_sslctx_free,
|
76
79
|
},
|
77
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
80
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
78
81
|
};
|
79
82
|
|
80
83
|
static VALUE
|
@@ -291,7 +294,7 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
|
291
294
|
if (!pkey)
|
292
295
|
return NULL;
|
293
296
|
|
294
|
-
return EVP_PKEY_get0_DH(pkey);
|
297
|
+
return (DH *)EVP_PKEY_get0_DH(pkey);
|
295
298
|
}
|
296
299
|
#endif /* OPENSSL_NO_DH */
|
297
300
|
|
@@ -441,6 +444,54 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
|
|
441
444
|
return 0;
|
442
445
|
}
|
443
446
|
|
447
|
+
#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
|
448
|
+
/*
|
449
|
+
* It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
|
450
|
+
* SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
|
451
|
+
* https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
|
452
|
+
*/
|
453
|
+
|
454
|
+
struct ossl_call_keylog_cb_args {
|
455
|
+
VALUE ssl_obj;
|
456
|
+
const char * line;
|
457
|
+
};
|
458
|
+
|
459
|
+
static VALUE
|
460
|
+
ossl_call_keylog_cb(VALUE args_v)
|
461
|
+
{
|
462
|
+
VALUE sslctx_obj, cb, line_v;
|
463
|
+
struct ossl_call_keylog_cb_args *args = (struct ossl_call_keylog_cb_args *) args_v;
|
464
|
+
|
465
|
+
sslctx_obj = rb_attr_get(args->ssl_obj, id_i_context);
|
466
|
+
|
467
|
+
cb = rb_attr_get(sslctx_obj, id_i_keylog_cb);
|
468
|
+
if (NIL_P(cb)) return Qnil;
|
469
|
+
|
470
|
+
line_v = rb_str_new_cstr(args->line);
|
471
|
+
|
472
|
+
return rb_funcall(cb, id_call, 2, args->ssl_obj, line_v);
|
473
|
+
}
|
474
|
+
|
475
|
+
static void
|
476
|
+
ossl_sslctx_keylog_cb(const SSL *ssl, const char *line)
|
477
|
+
{
|
478
|
+
VALUE ssl_obj;
|
479
|
+
struct ossl_call_keylog_cb_args args;
|
480
|
+
int state = 0;
|
481
|
+
|
482
|
+
OSSL_Debug("SSL keylog callback entered");
|
483
|
+
|
484
|
+
ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
485
|
+
args.ssl_obj = ssl_obj;
|
486
|
+
args.line = line;
|
487
|
+
|
488
|
+
rb_protect(ossl_call_keylog_cb, (VALUE)&args, &state);
|
489
|
+
if (state) {
|
490
|
+
rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
|
491
|
+
}
|
492
|
+
}
|
493
|
+
#endif
|
494
|
+
|
444
495
|
static VALUE
|
445
496
|
ossl_call_session_remove_cb(VALUE ary)
|
446
497
|
{
|
@@ -655,7 +706,7 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
|
|
655
706
|
return SSL_TLSEXT_ERR_OK;
|
656
707
|
}
|
657
708
|
|
658
|
-
#
|
709
|
+
#ifdef OSSL_USE_NEXTPROTONEG
|
659
710
|
static int
|
660
711
|
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
|
661
712
|
void *arg)
|
@@ -834,9 +885,9 @@ ossl_sslctx_setup(VALUE self)
|
|
834
885
|
if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path))
|
835
886
|
ossl_raise(eSSLError, "SSL_CTX_load_verify_dir");
|
836
887
|
#else
|
837
|
-
if(ca_file || ca_path){
|
838
|
-
|
839
|
-
|
888
|
+
if (ca_file || ca_path) {
|
889
|
+
if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
|
890
|
+
ossl_raise(eSSLError, "SSL_CTX_load_verify_locations");
|
840
891
|
}
|
841
892
|
#endif
|
842
893
|
|
@@ -852,7 +903,7 @@ ossl_sslctx_setup(VALUE self)
|
|
852
903
|
val = rb_attr_get(self, id_i_verify_depth);
|
853
904
|
if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
|
854
905
|
|
855
|
-
#
|
906
|
+
#ifdef OSSL_USE_NEXTPROTONEG
|
856
907
|
val = rb_attr_get(self, id_i_npn_protocols);
|
857
908
|
if (!NIL_P(val)) {
|
858
909
|
VALUE encoded = ssl_encode_npn_protocols(val);
|
@@ -911,6 +962,18 @@ ossl_sslctx_setup(VALUE self)
|
|
911
962
|
OSSL_Debug("SSL TLSEXT servername callback added");
|
912
963
|
}
|
913
964
|
|
965
|
+
#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
|
966
|
+
/*
|
967
|
+
* It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
|
968
|
+
* SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
|
969
|
+
* https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
|
970
|
+
*/
|
971
|
+
if (RTEST(rb_attr_get(self, id_i_keylog_cb))) {
|
972
|
+
SSL_CTX_set_keylog_callback(ctx, ossl_sslctx_keylog_cb);
|
973
|
+
OSSL_Debug("SSL keylog callback added");
|
974
|
+
}
|
975
|
+
#endif
|
976
|
+
|
914
977
|
return Qtrue;
|
915
978
|
}
|
916
979
|
|
@@ -959,27 +1022,13 @@ ossl_sslctx_get_ciphers(VALUE self)
|
|
959
1022
|
return ary;
|
960
1023
|
}
|
961
1024
|
|
962
|
-
/*
|
963
|
-
* call-seq:
|
964
|
-
* ctx.ciphers = "cipher1:cipher2:..."
|
965
|
-
* ctx.ciphers = [name, ...]
|
966
|
-
* ctx.ciphers = [[name, version, bits, alg_bits], ...]
|
967
|
-
*
|
968
|
-
* Sets the list of available cipher suites for this context. Note in a server
|
969
|
-
* context some ciphers require the appropriate certificates. For example, an
|
970
|
-
* RSA cipher suite can only be chosen when an RSA certificate is available.
|
971
|
-
*/
|
972
1025
|
static VALUE
|
973
|
-
|
1026
|
+
build_cipher_string(VALUE v)
|
974
1027
|
{
|
975
|
-
SSL_CTX *ctx;
|
976
1028
|
VALUE str, elem;
|
977
1029
|
int i;
|
978
1030
|
|
979
|
-
|
980
|
-
if (NIL_P(v))
|
981
|
-
return v;
|
982
|
-
else if (RB_TYPE_P(v, T_ARRAY)) {
|
1031
|
+
if (RB_TYPE_P(v, T_ARRAY)) {
|
983
1032
|
str = rb_str_new(0, 0);
|
984
1033
|
for (i = 0; i < RARRAY_LEN(v); i++) {
|
985
1034
|
elem = rb_ary_entry(v, i);
|
@@ -993,14 +1042,67 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
|
993
1042
|
StringValue(str);
|
994
1043
|
}
|
995
1044
|
|
1045
|
+
return str;
|
1046
|
+
}
|
1047
|
+
|
1048
|
+
/*
|
1049
|
+
* call-seq:
|
1050
|
+
* ctx.ciphers = "cipher1:cipher2:..."
|
1051
|
+
* ctx.ciphers = [name, ...]
|
1052
|
+
* ctx.ciphers = [[name, version, bits, alg_bits], ...]
|
1053
|
+
*
|
1054
|
+
* Sets the list of available cipher suites for this context. Note in a server
|
1055
|
+
* context some ciphers require the appropriate certificates. For example, an
|
1056
|
+
* RSA cipher suite can only be chosen when an RSA certificate is available.
|
1057
|
+
*/
|
1058
|
+
static VALUE
|
1059
|
+
ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
1060
|
+
{
|
1061
|
+
SSL_CTX *ctx;
|
1062
|
+
VALUE str;
|
1063
|
+
|
1064
|
+
rb_check_frozen(self);
|
1065
|
+
if (NIL_P(v))
|
1066
|
+
return v;
|
1067
|
+
|
1068
|
+
str = build_cipher_string(v);
|
1069
|
+
|
996
1070
|
GetSSLCTX(self, ctx);
|
997
|
-
if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
|
1071
|
+
if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
|
998
1072
|
ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
|
999
|
-
}
|
1000
1073
|
|
1001
1074
|
return v;
|
1002
1075
|
}
|
1003
1076
|
|
1077
|
+
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
|
1078
|
+
/*
|
1079
|
+
* call-seq:
|
1080
|
+
* ctx.ciphersuites = "cipher1:cipher2:..."
|
1081
|
+
* ctx.ciphersuites = [name, ...]
|
1082
|
+
* ctx.ciphersuites = [[name, version, bits, alg_bits], ...]
|
1083
|
+
*
|
1084
|
+
* Sets the list of available TLSv1.3 cipher suites for this context.
|
1085
|
+
*/
|
1086
|
+
static VALUE
|
1087
|
+
ossl_sslctx_set_ciphersuites(VALUE self, VALUE v)
|
1088
|
+
{
|
1089
|
+
SSL_CTX *ctx;
|
1090
|
+
VALUE str;
|
1091
|
+
|
1092
|
+
rb_check_frozen(self);
|
1093
|
+
if (NIL_P(v))
|
1094
|
+
return v;
|
1095
|
+
|
1096
|
+
str = build_cipher_string(v);
|
1097
|
+
|
1098
|
+
GetSSLCTX(self, ctx);
|
1099
|
+
if (!SSL_CTX_set_ciphersuites(ctx, StringValueCStr(str)))
|
1100
|
+
ossl_raise(eSSLError, "SSL_CTX_set_ciphersuites");
|
1101
|
+
|
1102
|
+
return v;
|
1103
|
+
}
|
1104
|
+
#endif
|
1105
|
+
|
1004
1106
|
#ifndef OPENSSL_NO_DH
|
1005
1107
|
/*
|
1006
1108
|
* call-seq:
|
@@ -1439,7 +1541,6 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
|
|
1439
1541
|
/*
|
1440
1542
|
* SSLSocket class
|
1441
1543
|
*/
|
1442
|
-
#ifndef OPENSSL_NO_SOCK
|
1443
1544
|
static inline int
|
1444
1545
|
ssl_started(SSL *ssl)
|
1445
1546
|
{
|
@@ -1452,6 +1553,10 @@ ossl_ssl_mark(void *ptr)
|
|
1452
1553
|
{
|
1453
1554
|
SSL *ssl = ptr;
|
1454
1555
|
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
|
1556
|
+
|
1557
|
+
// Note: this reference is stored as @verify_callback so we don't need to mark it.
|
1558
|
+
// However we do need to ensure GC compaction won't move it, hence why
|
1559
|
+
// we call rb_gc_mark here.
|
1455
1560
|
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
|
1456
1561
|
}
|
1457
1562
|
|
@@ -1466,7 +1571,7 @@ const rb_data_type_t ossl_ssl_type = {
|
|
1466
1571
|
{
|
1467
1572
|
ossl_ssl_mark, ossl_ssl_free,
|
1468
1573
|
},
|
1469
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
1574
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
1470
1575
|
};
|
1471
1576
|
|
1472
1577
|
static VALUE
|
@@ -1545,6 +1650,8 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
|
1545
1650
|
SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
|
1546
1651
|
SSL_set_info_callback(ssl, ssl_info_cb);
|
1547
1652
|
verify_cb = rb_attr_get(v_ctx, id_i_verify_callback);
|
1653
|
+
// We don't need to trigger a write barrier because it's already
|
1654
|
+
// an instance variable of this object.
|
1548
1655
|
SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
|
1549
1656
|
|
1550
1657
|
rb_call_super(0, NULL);
|
@@ -1552,6 +1659,17 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
|
1552
1659
|
return self;
|
1553
1660
|
}
|
1554
1661
|
|
1662
|
+
#ifndef HAVE_RB_IO_DESCRIPTOR
|
1663
|
+
static int
|
1664
|
+
io_descriptor_fallback(VALUE io)
|
1665
|
+
{
|
1666
|
+
rb_io_t *fptr;
|
1667
|
+
GetOpenFile(io, fptr);
|
1668
|
+
return fptr->fd;
|
1669
|
+
}
|
1670
|
+
#define rb_io_descriptor io_descriptor_fallback
|
1671
|
+
#endif
|
1672
|
+
|
1555
1673
|
static VALUE
|
1556
1674
|
ossl_ssl_setup(VALUE self)
|
1557
1675
|
{
|
@@ -1567,8 +1685,8 @@ ossl_ssl_setup(VALUE self)
|
|
1567
1685
|
GetOpenFile(io, fptr);
|
1568
1686
|
rb_io_check_readable(fptr);
|
1569
1687
|
rb_io_check_writable(fptr);
|
1570
|
-
if (!SSL_set_fd(ssl, TO_SOCKET(
|
1571
|
-
|
1688
|
+
if (!SSL_set_fd(ssl, TO_SOCKET(rb_io_descriptor(io))))
|
1689
|
+
ossl_raise(eSSLError, "SSL_set_fd");
|
1572
1690
|
|
1573
1691
|
return Qtrue;
|
1574
1692
|
}
|
@@ -1602,99 +1720,107 @@ no_exception_p(VALUE opts)
|
|
1602
1720
|
return 0;
|
1603
1721
|
}
|
1604
1722
|
|
1723
|
+
// Provided by Ruby 3.2.0 and later in order to support the default IO#timeout.
|
1724
|
+
#ifndef RUBY_IO_TIMEOUT_DEFAULT
|
1725
|
+
#define RUBY_IO_TIMEOUT_DEFAULT Qnil
|
1726
|
+
#endif
|
1727
|
+
|
1605
1728
|
static void
|
1606
|
-
io_wait_writable(
|
1729
|
+
io_wait_writable(VALUE io)
|
1607
1730
|
{
|
1608
1731
|
#ifdef HAVE_RB_IO_MAYBE_WAIT
|
1609
|
-
rb_io_maybe_wait_writable(errno,
|
1732
|
+
rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
|
1610
1733
|
#else
|
1734
|
+
rb_io_t *fptr;
|
1735
|
+
GetOpenFile(io, fptr);
|
1611
1736
|
rb_io_wait_writable(fptr->fd);
|
1612
1737
|
#endif
|
1613
1738
|
}
|
1614
1739
|
|
1615
1740
|
static void
|
1616
|
-
io_wait_readable(
|
1741
|
+
io_wait_readable(VALUE io)
|
1617
1742
|
{
|
1618
1743
|
#ifdef HAVE_RB_IO_MAYBE_WAIT
|
1619
|
-
rb_io_maybe_wait_readable(errno,
|
1744
|
+
rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
|
1620
1745
|
#else
|
1746
|
+
rb_io_t *fptr;
|
1747
|
+
GetOpenFile(io, fptr);
|
1621
1748
|
rb_io_wait_readable(fptr->fd);
|
1622
1749
|
#endif
|
1623
1750
|
}
|
1624
1751
|
|
1625
1752
|
static VALUE
|
1626
|
-
ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
1753
|
+
ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
|
1627
1754
|
{
|
1628
1755
|
SSL *ssl;
|
1629
|
-
rb_io_t *fptr;
|
1630
1756
|
int ret, ret2;
|
1631
1757
|
VALUE cb_state;
|
1632
1758
|
int nonblock = opts != Qfalse;
|
1633
|
-
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
1634
|
-
unsigned long err;
|
1635
|
-
#endif
|
1636
1759
|
|
1637
1760
|
rb_ivar_set(self, ID_callback_state, Qnil);
|
1638
1761
|
|
1639
1762
|
GetSSL(self, ssl);
|
1640
1763
|
|
1641
|
-
|
1642
|
-
for(;;){
|
1643
|
-
|
1764
|
+
VALUE io = rb_attr_get(self, id_i_io);
|
1765
|
+
for (;;) {
|
1766
|
+
ret = func(ssl);
|
1644
1767
|
|
1645
|
-
|
1768
|
+
cb_state = rb_attr_get(self, ID_callback_state);
|
1646
1769
|
if (!NIL_P(cb_state)) {
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1770
|
+
/* must cleanup OpenSSL error stack before re-raising */
|
1771
|
+
ossl_clear_error();
|
1772
|
+
rb_jump_tag(NUM2INT(cb_state));
|
1773
|
+
}
|
1651
1774
|
|
1652
|
-
|
1653
|
-
|
1775
|
+
if (ret > 0)
|
1776
|
+
break;
|
1654
1777
|
|
1655
|
-
|
1656
|
-
|
1778
|
+
switch ((ret2 = ssl_get_error(ssl, ret))) {
|
1779
|
+
case SSL_ERROR_WANT_WRITE:
|
1657
1780
|
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1658
1781
|
write_would_block(nonblock);
|
1659
|
-
io_wait_writable(
|
1782
|
+
io_wait_writable(io);
|
1660
1783
|
continue;
|
1661
|
-
|
1784
|
+
case SSL_ERROR_WANT_READ:
|
1662
1785
|
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1663
1786
|
read_would_block(nonblock);
|
1664
|
-
io_wait_readable(
|
1787
|
+
io_wait_readable(io);
|
1665
1788
|
continue;
|
1666
|
-
|
1789
|
+
case SSL_ERROR_SYSCALL:
|
1667
1790
|
#ifdef __APPLE__
|
1668
1791
|
/* See ossl_ssl_write_internal() */
|
1669
1792
|
if (errno == EPROTOTYPE)
|
1670
1793
|
continue;
|
1671
1794
|
#endif
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1795
|
+
if (errno) rb_sys_fail(funcname);
|
1796
|
+
/* fallthrough */
|
1797
|
+
default: {
|
1798
|
+
VALUE error_append = Qnil;
|
1676
1799
|
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl),
|
1690
|
-
err_msg, verify_msg);
|
1691
|
-
}
|
1800
|
+
unsigned long err = ERR_peek_last_error();
|
1801
|
+
if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
|
1802
|
+
ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
|
1803
|
+
const char *err_msg = ERR_reason_error_string(err),
|
1804
|
+
*verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
|
1805
|
+
if (!err_msg)
|
1806
|
+
err_msg = "(null)";
|
1807
|
+
if (!verify_msg)
|
1808
|
+
verify_msg = "(null)";
|
1809
|
+
ossl_clear_error(); /* let ossl_raise() not append message */
|
1810
|
+
error_append = rb_sprintf(": %s (%s)", err_msg, verify_msg);
|
1811
|
+
}
|
1692
1812
|
#endif
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1813
|
+
ossl_raise(eSSLError,
|
1814
|
+
"%s%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s%"PRIsVALUE,
|
1815
|
+
funcname,
|
1816
|
+
ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "",
|
1817
|
+
ret2,
|
1818
|
+
errno,
|
1819
|
+
peeraddr_ip_str(self),
|
1820
|
+
SSL_state_string_long(ssl),
|
1821
|
+
error_append);
|
1822
|
+
}
|
1823
|
+
}
|
1698
1824
|
}
|
1699
1825
|
|
1700
1826
|
return self;
|
@@ -1800,8 +1926,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1800
1926
|
SSL *ssl;
|
1801
1927
|
int ilen;
|
1802
1928
|
VALUE len, str;
|
1803
|
-
|
1804
|
-
VALUE io, opts = Qnil;
|
1929
|
+
VALUE opts = Qnil;
|
1805
1930
|
|
1806
1931
|
if (nonblock) {
|
1807
1932
|
rb_scan_args(argc, argv, "11:", &len, &str, &opts);
|
@@ -1826,8 +1951,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1826
1951
|
if (ilen == 0)
|
1827
1952
|
return str;
|
1828
1953
|
|
1829
|
-
io = rb_attr_get(self, id_i_io);
|
1830
|
-
GetOpenFile(io, fptr);
|
1954
|
+
VALUE io = rb_attr_get(self, id_i_io);
|
1831
1955
|
|
1832
1956
|
rb_str_locktmp(str);
|
1833
1957
|
for (;;) {
|
@@ -1847,7 +1971,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1847
1971
|
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1848
1972
|
write_would_block(nonblock);
|
1849
1973
|
}
|
1850
|
-
io_wait_writable(
|
1974
|
+
io_wait_writable(io);
|
1851
1975
|
continue;
|
1852
1976
|
case SSL_ERROR_WANT_READ:
|
1853
1977
|
if (nonblock) {
|
@@ -1855,7 +1979,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1855
1979
|
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1856
1980
|
read_would_block(nonblock);
|
1857
1981
|
}
|
1858
|
-
io_wait_readable(
|
1982
|
+
io_wait_readable(io);
|
1859
1983
|
continue;
|
1860
1984
|
case SSL_ERROR_SYSCALL:
|
1861
1985
|
if (!ERR_peek_error()) {
|
@@ -1921,14 +2045,14 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|
1921
2045
|
SSL *ssl;
|
1922
2046
|
rb_io_t *fptr;
|
1923
2047
|
int num, nonblock = opts != Qfalse;
|
1924
|
-
VALUE tmp
|
2048
|
+
VALUE tmp;
|
1925
2049
|
|
1926
2050
|
GetSSL(self, ssl);
|
1927
2051
|
if (!ssl_started(ssl))
|
1928
2052
|
rb_raise(eSSLError, "SSL session is not started yet");
|
1929
2053
|
|
1930
2054
|
tmp = rb_str_new_frozen(StringValue(str));
|
1931
|
-
io = rb_attr_get(self, id_i_io);
|
2055
|
+
VALUE io = rb_attr_get(self, id_i_io);
|
1932
2056
|
GetOpenFile(io, fptr);
|
1933
2057
|
|
1934
2058
|
/* SSL_write(3ssl) manpage states num == 0 is undefined */
|
@@ -1944,12 +2068,12 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|
1944
2068
|
case SSL_ERROR_WANT_WRITE:
|
1945
2069
|
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1946
2070
|
write_would_block(nonblock);
|
1947
|
-
io_wait_writable(
|
2071
|
+
io_wait_writable(io);
|
1948
2072
|
continue;
|
1949
2073
|
case SSL_ERROR_WANT_READ:
|
1950
2074
|
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1951
2075
|
read_would_block(nonblock);
|
1952
|
-
io_wait_readable(
|
2076
|
+
io_wait_readable(io);
|
1953
2077
|
continue;
|
1954
2078
|
case SSL_ERROR_SYSCALL:
|
1955
2079
|
#ifdef __APPLE__
|
@@ -2342,7 +2466,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
|
|
2342
2466
|
return ossl_x509name_sk2ary(ca);
|
2343
2467
|
}
|
2344
2468
|
|
2345
|
-
#
|
2469
|
+
# ifdef OSSL_USE_NEXTPROTONEG
|
2346
2470
|
/*
|
2347
2471
|
* call-seq:
|
2348
2472
|
* ssl.npn_protocol => String | nil
|
@@ -2390,6 +2514,49 @@ ossl_ssl_alpn_protocol(VALUE self)
|
|
2390
2514
|
return rb_str_new((const char *) out, outlen);
|
2391
2515
|
}
|
2392
2516
|
|
2517
|
+
/*
|
2518
|
+
* call-seq:
|
2519
|
+
* session.export_keying_material(label, length) -> String
|
2520
|
+
*
|
2521
|
+
* Enables use of shared session key material in accordance with RFC 5705.
|
2522
|
+
*/
|
2523
|
+
static VALUE
|
2524
|
+
ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self)
|
2525
|
+
{
|
2526
|
+
SSL *ssl;
|
2527
|
+
VALUE str;
|
2528
|
+
VALUE label;
|
2529
|
+
VALUE length;
|
2530
|
+
VALUE context;
|
2531
|
+
unsigned char *p;
|
2532
|
+
size_t len;
|
2533
|
+
int use_ctx = 0;
|
2534
|
+
unsigned char *ctx = NULL;
|
2535
|
+
size_t ctx_len = 0;
|
2536
|
+
int ret;
|
2537
|
+
|
2538
|
+
rb_scan_args(argc, argv, "21", &label, &length, &context);
|
2539
|
+
StringValue(label);
|
2540
|
+
|
2541
|
+
GetSSL(self, ssl);
|
2542
|
+
|
2543
|
+
len = (size_t)NUM2LONG(length);
|
2544
|
+
str = rb_str_new(0, len);
|
2545
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
2546
|
+
if (!NIL_P(context)) {
|
2547
|
+
use_ctx = 1;
|
2548
|
+
StringValue(context);
|
2549
|
+
ctx = (unsigned char *)RSTRING_PTR(context);
|
2550
|
+
ctx_len = RSTRING_LEN(context);
|
2551
|
+
}
|
2552
|
+
ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label),
|
2553
|
+
RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
|
2554
|
+
if (ret == 0 || ret == -1) {
|
2555
|
+
ossl_raise(eSSLError, "SSL_export_keying_material");
|
2556
|
+
}
|
2557
|
+
return str;
|
2558
|
+
}
|
2559
|
+
|
2393
2560
|
/*
|
2394
2561
|
* call-seq:
|
2395
2562
|
* ssl.tmp_key => PKey or nil
|
@@ -2419,6 +2586,7 @@ Init_ossl_ssl(void)
|
|
2419
2586
|
rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
|
2420
2587
|
#endif
|
2421
2588
|
|
2589
|
+
#ifndef OPENSSL_NO_SOCK
|
2422
2590
|
id_call = rb_intern_const("call");
|
2423
2591
|
ID_callback_state = rb_intern_const("callback_state");
|
2424
2592
|
|
@@ -2441,16 +2609,6 @@ Init_ossl_ssl(void)
|
|
2441
2609
|
*/
|
2442
2610
|
mSSL = rb_define_module_under(mOSSL, "SSL");
|
2443
2611
|
|
2444
|
-
/* Document-module: OpenSSL::ExtConfig
|
2445
|
-
*
|
2446
|
-
* This module contains configuration information about the SSL extension,
|
2447
|
-
* for example if socket support is enabled, or the host name TLS extension
|
2448
|
-
* is enabled. Constants in this module will always be defined, but contain
|
2449
|
-
* +true+ or +false+ values depending on the configuration of your OpenSSL
|
2450
|
-
* installation.
|
2451
|
-
*/
|
2452
|
-
mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig");
|
2453
|
-
|
2454
2612
|
/* Document-class: OpenSSL::SSL::SSLError
|
2455
2613
|
*
|
2456
2614
|
* Generic error class raised by SSLSocket and SSLContext.
|
@@ -2613,8 +2771,6 @@ Init_ossl_ssl(void)
|
|
2613
2771
|
*/
|
2614
2772
|
rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
|
2615
2773
|
|
2616
|
-
rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
|
2617
|
-
|
2618
2774
|
/*
|
2619
2775
|
* A callback invoked whenever a new handshake is initiated on an
|
2620
2776
|
* established connection. May be used to disable renegotiation entirely.
|
@@ -2635,7 +2791,7 @@ Init_ossl_ssl(void)
|
|
2635
2791
|
* end
|
2636
2792
|
*/
|
2637
2793
|
rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
|
2638
|
-
#
|
2794
|
+
#ifdef OSSL_USE_NEXTPROTONEG
|
2639
2795
|
/*
|
2640
2796
|
* An Enumerable of Strings. Each String represents a protocol to be
|
2641
2797
|
* advertised as the list of supported protocols for Next Protocol
|
@@ -2697,12 +2853,38 @@ Init_ossl_ssl(void)
|
|
2697
2853
|
*/
|
2698
2854
|
rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
|
2699
2855
|
|
2856
|
+
/*
|
2857
|
+
* A callback invoked when TLS key material is generated or received, in
|
2858
|
+
* order to allow applications to store this keying material for debugging
|
2859
|
+
* purposes.
|
2860
|
+
*
|
2861
|
+
* The callback is invoked with an SSLSocket and a string containing the
|
2862
|
+
* key material in the format used by NSS for its SSLKEYLOGFILE debugging
|
2863
|
+
* output.
|
2864
|
+
*
|
2865
|
+
* It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
|
2866
|
+
* SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
|
2867
|
+
* https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
|
2868
|
+
*
|
2869
|
+
* === Example
|
2870
|
+
*
|
2871
|
+
* context.keylog_cb = proc do |_sock, line|
|
2872
|
+
* File.open('ssl_keylog_file', "a") do |f|
|
2873
|
+
* f.write("#{line}\n")
|
2874
|
+
* end
|
2875
|
+
* end
|
2876
|
+
*/
|
2877
|
+
rb_attr(cSSLContext, rb_intern_const("keylog_cb"), 1, 1, Qfalse);
|
2878
|
+
|
2700
2879
|
rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
|
2701
2880
|
rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
|
2702
2881
|
rb_define_private_method(cSSLContext, "set_minmax_proto_version",
|
2703
2882
|
ossl_sslctx_set_minmax_proto_version, 2);
|
2704
2883
|
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
|
2705
2884
|
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
|
2885
|
+
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
|
2886
|
+
rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1);
|
2887
|
+
#endif
|
2706
2888
|
#ifndef OPENSSL_NO_DH
|
2707
2889
|
rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
|
2708
2890
|
#endif
|
@@ -2779,11 +2961,6 @@ Init_ossl_ssl(void)
|
|
2779
2961
|
* Document-class: OpenSSL::SSL::SSLSocket
|
2780
2962
|
*/
|
2781
2963
|
cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
|
2782
|
-
#ifdef OPENSSL_NO_SOCK
|
2783
|
-
rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue);
|
2784
|
-
rb_define_method(cSSLSocket, "initialize", rb_f_notimplement, -1);
|
2785
|
-
#else
|
2786
|
-
rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse);
|
2787
2964
|
rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
|
2788
2965
|
rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
|
2789
2966
|
rb_undef_method(cSSLSocket, "initialize_copy");
|
@@ -2814,10 +2991,10 @@ Init_ossl_ssl(void)
|
|
2814
2991
|
rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
|
2815
2992
|
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
|
2816
2993
|
rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
|
2817
|
-
|
2994
|
+
rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1);
|
2995
|
+
# ifdef OSSL_USE_NEXTPROTONEG
|
2818
2996
|
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
|
2819
2997
|
# endif
|
2820
|
-
#endif
|
2821
2998
|
|
2822
2999
|
rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
|
2823
3000
|
rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
|
@@ -2974,8 +3151,10 @@ Init_ossl_ssl(void)
|
|
2974
3151
|
DefIVarID(alpn_select_cb);
|
2975
3152
|
DefIVarID(servername_cb);
|
2976
3153
|
DefIVarID(verify_hostname);
|
3154
|
+
DefIVarID(keylog_cb);
|
2977
3155
|
|
2978
3156
|
DefIVarID(io);
|
2979
3157
|
DefIVarID(context);
|
2980
3158
|
DefIVarID(hostname);
|
3159
|
+
#endif /* !defined(OPENSSL_NO_SOCK) */
|
2981
3160
|
}
|