openssl 2.2.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +33 -45
- data/History.md +248 -1
- data/README.md +36 -19
- data/ext/openssl/extconf.rb +101 -68
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +26 -45
- data/ext/openssl/ossl.c +128 -237
- data/ext/openssl/ossl.h +31 -12
- data/ext/openssl/ossl_asn1.c +26 -13
- data/ext/openssl/ossl_bn.c +213 -139
- data/ext/openssl/ossl_cipher.c +13 -14
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +10 -10
- data/ext/openssl/ossl_engine.c +17 -16
- data/ext/openssl/ossl_hmac.c +57 -136
- data/ext/openssl/ossl_kdf.c +12 -4
- data/ext/openssl/ossl_ns_spki.c +1 -1
- data/ext/openssl/ossl_ocsp.c +11 -59
- data/ext/openssl/ossl_pkcs12.c +22 -4
- data/ext/openssl/ossl_pkcs7.c +45 -62
- data/ext/openssl/ossl_pkey.c +1320 -196
- data/ext/openssl/ossl_pkey.h +36 -73
- data/ext/openssl/ossl_pkey_dh.c +152 -347
- data/ext/openssl/ossl_pkey_dsa.c +157 -413
- data/ext/openssl/ossl_pkey_ec.c +227 -343
- data/ext/openssl/ossl_pkey_rsa.c +159 -491
- data/ext/openssl/ossl_provider.c +211 -0
- data/ext/openssl/ossl_provider.h +5 -0
- data/ext/openssl/ossl_ssl.c +530 -450
- data/ext/openssl/ossl_ssl_session.c +29 -30
- data/ext/openssl/ossl_ts.c +38 -23
- data/ext/openssl/ossl_x509.c +0 -6
- data/ext/openssl/ossl_x509attr.c +1 -1
- data/ext/openssl/ossl_x509cert.c +168 -12
- data/ext/openssl/ossl_x509crl.c +14 -11
- data/ext/openssl/ossl_x509ext.c +14 -9
- data/ext/openssl/ossl_x509name.c +10 -3
- data/ext/openssl/ossl_x509req.c +14 -11
- data/ext/openssl/ossl_x509revoked.c +4 -4
- data/ext/openssl/ossl_x509store.c +166 -75
- data/lib/openssl/buffering.rb +9 -3
- data/lib/openssl/digest.rb +1 -5
- data/lib/openssl/hmac.rb +65 -0
- data/lib/openssl/pkey.rb +429 -0
- data/lib/openssl/ssl.rb +22 -17
- data/lib/openssl/version.rb +1 -1
- data/lib/openssl/x509.rb +22 -0
- data/lib/openssl.rb +0 -1
- metadata +10 -79
- data/ext/openssl/ruby_missing.h +0 -24
- data/lib/openssl/config.rb +0 -501
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;
|
@@ -38,26 +41,23 @@ VALUE cSSLSocket;
|
|
38
41
|
static VALUE eSSLErrorWaitReadable;
|
39
42
|
static VALUE eSSLErrorWaitWritable;
|
40
43
|
|
41
|
-
static ID id_call, ID_callback_state, id_tmp_dh_callback,
|
44
|
+
static ID id_call, ID_callback_state, id_tmp_dh_callback,
|
42
45
|
id_npn_protocols_encoded, id_each;
|
43
46
|
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
|
44
47
|
|
45
48
|
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
|
46
49
|
id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
|
47
50
|
id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
|
48
|
-
id_i_client_cert_cb,
|
51
|
+
id_i_client_cert_cb, id_i_timeout,
|
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;
|
56
59
|
static int ossl_ssl_ex_ptr_idx;
|
57
60
|
static int ossl_sslctx_ex_ptr_idx;
|
58
|
-
#if !defined(HAVE_X509_STORE_UP_REF)
|
59
|
-
static int ossl_sslctx_ex_store_p;
|
60
|
-
#endif
|
61
61
|
|
62
62
|
static void
|
63
63
|
ossl_sslctx_mark(void *ptr)
|
@@ -69,12 +69,7 @@ ossl_sslctx_mark(void *ptr)
|
|
69
69
|
static void
|
70
70
|
ossl_sslctx_free(void *ptr)
|
71
71
|
{
|
72
|
-
|
73
|
-
#if !defined(HAVE_X509_STORE_UP_REF)
|
74
|
-
if (ctx && SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_store_p))
|
75
|
-
ctx->cert_store = NULL;
|
76
|
-
#endif
|
77
|
-
SSL_CTX_free(ctx);
|
72
|
+
SSL_CTX_free(ptr);
|
78
73
|
}
|
79
74
|
|
80
75
|
static const rb_data_type_t ossl_sslctx_type = {
|
@@ -82,7 +77,7 @@ static const rb_data_type_t ossl_sslctx_type = {
|
|
82
77
|
{
|
83
78
|
ossl_sslctx_mark, ossl_sslctx_free,
|
84
79
|
},
|
85
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
80
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
86
81
|
};
|
87
82
|
|
88
83
|
static VALUE
|
@@ -96,7 +91,7 @@ ossl_sslctx_s_alloc(VALUE klass)
|
|
96
91
|
VALUE obj;
|
97
92
|
|
98
93
|
obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
|
99
|
-
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
94
|
+
#if OPENSSL_VERSION_NUMBER >= 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
|
100
95
|
ctx = SSL_CTX_new(TLS_method());
|
101
96
|
#else
|
102
97
|
ctx = SSL_CTX_new(SSLv23_method());
|
@@ -108,14 +103,15 @@ ossl_sslctx_s_alloc(VALUE klass)
|
|
108
103
|
RTYPEDDATA_DATA(obj) = ctx;
|
109
104
|
SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj);
|
110
105
|
|
111
|
-
#if !defined(OPENSSL_NO_EC) &&
|
106
|
+
#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER < 0x10100000 && \
|
107
|
+
!defined(LIBRESSL_VERSION_NUMBER)
|
112
108
|
/* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
|
113
109
|
* allows to specify multiple curve names and OpenSSL will select
|
114
110
|
* automatically from them. In OpenSSL 1.0.2, the automatic selection has to
|
115
|
-
* be enabled explicitly.
|
116
|
-
* always enabled. To uniform the behavior, we enable the
|
117
|
-
* selection also in 1.0.2. Users can still disable ECDH by
|
118
|
-
* cipher suites by SSLContext#ciphers=. */
|
111
|
+
* be enabled explicitly. OpenSSL 1.1.0 and LibreSSL 2.6.1 removed the knob
|
112
|
+
* and it is always enabled. To uniform the behavior, we enable the
|
113
|
+
* automatic selection also in 1.0.2. Users can still disable ECDH by
|
114
|
+
* removing ECDH cipher suites by SSLContext#ciphers=. */
|
119
115
|
if (!SSL_CTX_set_ecdh_auto(ctx, 1))
|
120
116
|
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
121
117
|
#endif
|
@@ -244,8 +240,7 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
|
244
240
|
return 1;
|
245
241
|
}
|
246
242
|
|
247
|
-
#if !defined(OPENSSL_NO_DH)
|
248
|
-
!defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
243
|
+
#if !defined(OPENSSL_NO_DH)
|
249
244
|
struct tmp_dh_callback_args {
|
250
245
|
VALUE ssl_obj;
|
251
246
|
ID id;
|
@@ -254,22 +249,23 @@ struct tmp_dh_callback_args {
|
|
254
249
|
int keylength;
|
255
250
|
};
|
256
251
|
|
257
|
-
static
|
258
|
-
ossl_call_tmp_dh_callback(
|
252
|
+
static VALUE
|
253
|
+
ossl_call_tmp_dh_callback(VALUE arg)
|
259
254
|
{
|
255
|
+
struct tmp_dh_callback_args *args = (struct tmp_dh_callback_args *)arg;
|
260
256
|
VALUE cb, dh;
|
261
257
|
EVP_PKEY *pkey;
|
262
258
|
|
263
259
|
cb = rb_funcall(args->ssl_obj, args->id, 0);
|
264
260
|
if (NIL_P(cb))
|
265
|
-
return NULL;
|
261
|
+
return (VALUE)NULL;
|
266
262
|
dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
|
267
263
|
INT2NUM(args->keylength));
|
268
264
|
pkey = GetPKeyPtr(dh);
|
269
265
|
if (EVP_PKEY_base_id(pkey) != args->type)
|
270
|
-
return NULL;
|
266
|
+
return (VALUE)NULL;
|
271
267
|
|
272
|
-
return pkey;
|
268
|
+
return (VALUE)pkey;
|
273
269
|
}
|
274
270
|
#endif
|
275
271
|
|
@@ -289,7 +285,7 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
|
289
285
|
args.keylength = keylength;
|
290
286
|
args.type = EVP_PKEY_DH;
|
291
287
|
|
292
|
-
pkey = (EVP_PKEY *)rb_protect(
|
288
|
+
pkey = (EVP_PKEY *)rb_protect(ossl_call_tmp_dh_callback,
|
293
289
|
(VALUE)&args, &state);
|
294
290
|
if (state) {
|
295
291
|
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
@@ -298,39 +294,10 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
|
298
294
|
if (!pkey)
|
299
295
|
return NULL;
|
300
296
|
|
301
|
-
return EVP_PKEY_get0_DH(pkey);
|
297
|
+
return (DH *)EVP_PKEY_get0_DH(pkey);
|
302
298
|
}
|
303
299
|
#endif /* OPENSSL_NO_DH */
|
304
300
|
|
305
|
-
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
306
|
-
static EC_KEY *
|
307
|
-
ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
|
308
|
-
{
|
309
|
-
VALUE rb_ssl;
|
310
|
-
EVP_PKEY *pkey;
|
311
|
-
struct tmp_dh_callback_args args;
|
312
|
-
int state;
|
313
|
-
|
314
|
-
rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
315
|
-
args.ssl_obj = rb_ssl;
|
316
|
-
args.id = id_tmp_ecdh_callback;
|
317
|
-
args.is_export = is_export;
|
318
|
-
args.keylength = keylength;
|
319
|
-
args.type = EVP_PKEY_EC;
|
320
|
-
|
321
|
-
pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
|
322
|
-
(VALUE)&args, &state);
|
323
|
-
if (state) {
|
324
|
-
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
325
|
-
return NULL;
|
326
|
-
}
|
327
|
-
if (!pkey)
|
328
|
-
return NULL;
|
329
|
-
|
330
|
-
return EVP_PKEY_get0_EC_KEY(pkey);
|
331
|
-
}
|
332
|
-
#endif
|
333
|
-
|
334
301
|
static VALUE
|
335
302
|
call_verify_certificate_identity(VALUE ctx_v)
|
336
303
|
{
|
@@ -400,7 +367,7 @@ ossl_call_session_get_cb(VALUE ary)
|
|
400
367
|
}
|
401
368
|
|
402
369
|
static SSL_SESSION *
|
403
|
-
#if
|
370
|
+
#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
|
404
371
|
ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
|
405
372
|
#else
|
406
373
|
ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
|
@@ -477,6 +444,54 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
|
|
477
444
|
return 0;
|
478
445
|
}
|
479
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
|
+
|
480
495
|
static VALUE
|
481
496
|
ossl_call_session_remove_cb(VALUE ary)
|
482
497
|
{
|
@@ -609,8 +624,6 @@ ssl_renegotiation_cb(const SSL *ssl)
|
|
609
624
|
rb_funcallv(cb, id_call, 1, &ssl_obj);
|
610
625
|
}
|
611
626
|
|
612
|
-
#if !defined(OPENSSL_NO_NEXTPROTONEG) || \
|
613
|
-
defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
|
614
627
|
static VALUE
|
615
628
|
ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
|
616
629
|
{
|
@@ -692,9 +705,8 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
|
|
692
705
|
|
693
706
|
return SSL_TLSEXT_ERR_OK;
|
694
707
|
}
|
695
|
-
#endif
|
696
708
|
|
697
|
-
#
|
709
|
+
#ifdef OSSL_USE_NEXTPROTONEG
|
698
710
|
static int
|
699
711
|
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
|
700
712
|
void *arg)
|
@@ -721,7 +733,6 @@ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
|
|
721
733
|
}
|
722
734
|
#endif
|
723
735
|
|
724
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
725
736
|
static int
|
726
737
|
ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
727
738
|
const unsigned char *in, unsigned int inlen, void *arg)
|
@@ -733,7 +744,6 @@ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
|
733
744
|
|
734
745
|
return ssl_npn_select_cb_common(ssl, cb, out, outlen, in, inlen);
|
735
746
|
}
|
736
|
-
#endif
|
737
747
|
|
738
748
|
/* This function may serve as the entry point to support further callbacks. */
|
739
749
|
static void
|
@@ -810,26 +820,6 @@ ossl_sslctx_setup(VALUE self)
|
|
810
820
|
SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
|
811
821
|
#endif
|
812
822
|
|
813
|
-
#if !defined(OPENSSL_NO_EC)
|
814
|
-
/* We added SSLContext#tmp_ecdh_callback= in Ruby 2.3.0,
|
815
|
-
* but SSL_CTX_set_tmp_ecdh_callback() was removed in OpenSSL 1.1.0. */
|
816
|
-
if (RTEST(rb_attr_get(self, id_i_tmp_ecdh_callback))) {
|
817
|
-
# if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
818
|
-
rb_warn("#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
|
819
|
-
SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
|
820
|
-
# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
|
821
|
-
/* tmp_ecdh_callback and ecdh_auto conflict; OpenSSL ignores
|
822
|
-
* tmp_ecdh_callback. So disable ecdh_auto. */
|
823
|
-
if (!SSL_CTX_set_ecdh_auto(ctx, 0))
|
824
|
-
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
825
|
-
# endif
|
826
|
-
# else
|
827
|
-
ossl_raise(eSSLError, "OpenSSL does not support tmp_ecdh_callback; "
|
828
|
-
"use #ecdh_curves= instead");
|
829
|
-
# endif
|
830
|
-
}
|
831
|
-
#endif /* OPENSSL_NO_EC */
|
832
|
-
|
833
823
|
#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
|
834
824
|
SSL_CTX_set_post_handshake_auth(ctx, 1);
|
835
825
|
#endif
|
@@ -838,17 +828,7 @@ ossl_sslctx_setup(VALUE self)
|
|
838
828
|
if (!NIL_P(val)) {
|
839
829
|
X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
|
840
830
|
SSL_CTX_set_cert_store(ctx, store);
|
841
|
-
#if !defined(HAVE_X509_STORE_UP_REF)
|
842
|
-
/*
|
843
|
-
* WORKAROUND:
|
844
|
-
* X509_STORE can count references, but
|
845
|
-
* X509_STORE_free() doesn't care it.
|
846
|
-
* So we won't increment it but mark it by ex_data.
|
847
|
-
*/
|
848
|
-
SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
|
849
|
-
#else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
|
850
831
|
X509_STORE_up_ref(store);
|
851
|
-
#endif
|
852
832
|
}
|
853
833
|
|
854
834
|
val = rb_attr_get(self, id_i_extra_chain_cert);
|
@@ -899,10 +879,17 @@ ossl_sslctx_setup(VALUE self)
|
|
899
879
|
ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
|
900
880
|
val = rb_attr_get(self, id_i_ca_path);
|
901
881
|
ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
|
902
|
-
|
903
|
-
|
904
|
-
|
882
|
+
#ifdef HAVE_SSL_CTX_LOAD_VERIFY_FILE
|
883
|
+
if (ca_file && !SSL_CTX_load_verify_file(ctx, ca_file))
|
884
|
+
ossl_raise(eSSLError, "SSL_CTX_load_verify_file");
|
885
|
+
if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path))
|
886
|
+
ossl_raise(eSSLError, "SSL_CTX_load_verify_dir");
|
887
|
+
#else
|
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");
|
905
891
|
}
|
892
|
+
#endif
|
906
893
|
|
907
894
|
val = rb_attr_get(self, id_i_verify_mode);
|
908
895
|
verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
|
@@ -916,7 +903,7 @@ ossl_sslctx_setup(VALUE self)
|
|
916
903
|
val = rb_attr_get(self, id_i_verify_depth);
|
917
904
|
if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
|
918
905
|
|
919
|
-
#
|
906
|
+
#ifdef OSSL_USE_NEXTPROTONEG
|
920
907
|
val = rb_attr_get(self, id_i_npn_protocols);
|
921
908
|
if (!NIL_P(val)) {
|
922
909
|
VALUE encoded = ssl_encode_npn_protocols(val);
|
@@ -930,7 +917,6 @@ ossl_sslctx_setup(VALUE self)
|
|
930
917
|
}
|
931
918
|
#endif
|
932
919
|
|
933
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
934
920
|
val = rb_attr_get(self, id_i_alpn_protocols);
|
935
921
|
if (!NIL_P(val)) {
|
936
922
|
VALUE rprotos = ssl_encode_npn_protocols(val);
|
@@ -945,7 +931,6 @@ ossl_sslctx_setup(VALUE self)
|
|
945
931
|
SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
|
946
932
|
OSSL_Debug("SSL ALPN select callback added");
|
947
933
|
}
|
948
|
-
#endif
|
949
934
|
|
950
935
|
rb_obj_freeze(self);
|
951
936
|
|
@@ -977,6 +962,18 @@ ossl_sslctx_setup(VALUE self)
|
|
977
962
|
OSSL_Debug("SSL TLSEXT servername callback added");
|
978
963
|
}
|
979
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
|
+
|
980
977
|
return Qtrue;
|
981
978
|
}
|
982
979
|
|
@@ -1025,27 +1022,13 @@ ossl_sslctx_get_ciphers(VALUE self)
|
|
1025
1022
|
return ary;
|
1026
1023
|
}
|
1027
1024
|
|
1028
|
-
/*
|
1029
|
-
* call-seq:
|
1030
|
-
* ctx.ciphers = "cipher1:cipher2:..."
|
1031
|
-
* ctx.ciphers = [name, ...]
|
1032
|
-
* ctx.ciphers = [[name, version, bits, alg_bits], ...]
|
1033
|
-
*
|
1034
|
-
* Sets the list of available cipher suites for this context. Note in a server
|
1035
|
-
* context some ciphers require the appropriate certificates. For example, an
|
1036
|
-
* RSA cipher suite can only be chosen when an RSA certificate is available.
|
1037
|
-
*/
|
1038
1025
|
static VALUE
|
1039
|
-
|
1026
|
+
build_cipher_string(VALUE v)
|
1040
1027
|
{
|
1041
|
-
SSL_CTX *ctx;
|
1042
1028
|
VALUE str, elem;
|
1043
1029
|
int i;
|
1044
1030
|
|
1045
|
-
|
1046
|
-
if (NIL_P(v))
|
1047
|
-
return v;
|
1048
|
-
else if (RB_TYPE_P(v, T_ARRAY)) {
|
1031
|
+
if (RB_TYPE_P(v, T_ARRAY)) {
|
1049
1032
|
str = rb_str_new(0, 0);
|
1050
1033
|
for (i = 0; i < RARRAY_LEN(v); i++) {
|
1051
1034
|
elem = rb_ary_entry(v, i);
|
@@ -1059,14 +1042,113 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
|
1059
1042
|
StringValue(str);
|
1060
1043
|
}
|
1061
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
|
+
|
1062
1070
|
GetSSLCTX(self, ctx);
|
1063
|
-
if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
|
1071
|
+
if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
|
1064
1072
|
ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
|
1065
|
-
}
|
1066
1073
|
|
1067
1074
|
return v;
|
1068
1075
|
}
|
1069
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
|
+
|
1106
|
+
#ifndef OPENSSL_NO_DH
|
1107
|
+
/*
|
1108
|
+
* call-seq:
|
1109
|
+
* ctx.tmp_dh = pkey
|
1110
|
+
*
|
1111
|
+
* Sets DH parameters used for ephemeral DH key exchange. This is relevant for
|
1112
|
+
* servers only.
|
1113
|
+
*
|
1114
|
+
* +pkey+ is an instance of OpenSSL::PKey::DH. Note that key components
|
1115
|
+
* contained in the key object, if any, are ignored. The server will always
|
1116
|
+
* generate a new key pair for each handshake.
|
1117
|
+
*
|
1118
|
+
* Added in version 3.0. See also the man page SSL_set0_tmp_dh_pkey(3).
|
1119
|
+
*
|
1120
|
+
* Example:
|
1121
|
+
* ctx = OpenSSL::SSL::SSLContext.new
|
1122
|
+
* ctx.tmp_dh = OpenSSL::DH.generate(2048)
|
1123
|
+
* svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx)
|
1124
|
+
* Thread.new { svr.accept }
|
1125
|
+
*/
|
1126
|
+
static VALUE
|
1127
|
+
ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg)
|
1128
|
+
{
|
1129
|
+
SSL_CTX *ctx;
|
1130
|
+
EVP_PKEY *pkey;
|
1131
|
+
|
1132
|
+
rb_check_frozen(self);
|
1133
|
+
GetSSLCTX(self, ctx);
|
1134
|
+
pkey = GetPKeyPtr(arg);
|
1135
|
+
|
1136
|
+
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH)
|
1137
|
+
rb_raise(eSSLError, "invalid pkey type %s (expected DH)",
|
1138
|
+
OBJ_nid2sn(EVP_PKEY_base_id(pkey)));
|
1139
|
+
#ifdef HAVE_SSL_SET0_TMP_DH_PKEY
|
1140
|
+
if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkey))
|
1141
|
+
ossl_raise(eSSLError, "SSL_CTX_set0_tmp_dh_pkey");
|
1142
|
+
EVP_PKEY_up_ref(pkey);
|
1143
|
+
#else
|
1144
|
+
if (!SSL_CTX_set_tmp_dh(ctx, EVP_PKEY_get0_DH(pkey)))
|
1145
|
+
ossl_raise(eSSLError, "SSL_CTX_set_tmp_dh");
|
1146
|
+
#endif
|
1147
|
+
|
1148
|
+
return arg;
|
1149
|
+
}
|
1150
|
+
#endif
|
1151
|
+
|
1070
1152
|
#if !defined(OPENSSL_NO_EC)
|
1071
1153
|
/*
|
1072
1154
|
* call-seq:
|
@@ -1078,9 +1160,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
|
1078
1160
|
* Extension. For a server, the list is used by OpenSSL to determine the set of
|
1079
1161
|
* shared curves. OpenSSL will pick the most appropriate one from it.
|
1080
1162
|
*
|
1081
|
-
* Note that this works differently with old OpenSSL (<= 1.0.1). Only one curve
|
1082
|
-
* can be set, and this has no effect for TLS clients.
|
1083
|
-
*
|
1084
1163
|
* === Example
|
1085
1164
|
* ctx1 = OpenSSL::SSL::SSLContext.new
|
1086
1165
|
* ctx1.ecdh_curves = "X25519:P-256:P-224"
|
@@ -1104,48 +1183,8 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
|
|
1104
1183
|
GetSSLCTX(self, ctx);
|
1105
1184
|
StringValueCStr(arg);
|
1106
1185
|
|
1107
|
-
#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
|
1108
1186
|
if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
|
1109
1187
|
ossl_raise(eSSLError, NULL);
|
1110
|
-
#else
|
1111
|
-
/* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to
|
1112
|
-
* SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */
|
1113
|
-
{
|
1114
|
-
VALUE curve, splitted;
|
1115
|
-
EC_KEY *ec;
|
1116
|
-
int nid;
|
1117
|
-
|
1118
|
-
splitted = rb_str_split(arg, ":");
|
1119
|
-
if (!RARRAY_LEN(splitted))
|
1120
|
-
ossl_raise(eSSLError, "invalid input format");
|
1121
|
-
curve = RARRAY_AREF(splitted, 0);
|
1122
|
-
StringValueCStr(curve);
|
1123
|
-
|
1124
|
-
/* SSL_CTX_set1_curves_list() accepts NIST names */
|
1125
|
-
nid = EC_curve_nist2nid(RSTRING_PTR(curve));
|
1126
|
-
if (nid == NID_undef)
|
1127
|
-
nid = OBJ_txt2nid(RSTRING_PTR(curve));
|
1128
|
-
if (nid == NID_undef)
|
1129
|
-
ossl_raise(eSSLError, "unknown curve name");
|
1130
|
-
|
1131
|
-
ec = EC_KEY_new_by_curve_name(nid);
|
1132
|
-
if (!ec)
|
1133
|
-
ossl_raise(eSSLError, NULL);
|
1134
|
-
EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
|
1135
|
-
if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
|
1136
|
-
EC_KEY_free(ec);
|
1137
|
-
ossl_raise(eSSLError, "SSL_CTX_set_tmp_ecdh");
|
1138
|
-
}
|
1139
|
-
EC_KEY_free(ec);
|
1140
|
-
# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
|
1141
|
-
/* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto
|
1142
|
-
* is enabled. So disable ecdh_auto. */
|
1143
|
-
if (!SSL_CTX_set_ecdh_auto(ctx, 0))
|
1144
|
-
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
1145
|
-
# endif
|
1146
|
-
}
|
1147
|
-
#endif
|
1148
|
-
|
1149
1188
|
return arg;
|
1150
1189
|
}
|
1151
1190
|
#else
|
@@ -1236,7 +1275,7 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
|
|
1236
1275
|
|
1237
1276
|
/*
|
1238
1277
|
* call-seq:
|
1239
|
-
* ctx.add_certificate(
|
1278
|
+
* ctx.add_certificate(certificate, pkey [, extra_certs]) -> self
|
1240
1279
|
*
|
1241
1280
|
* Adds a certificate to the context. _pkey_ must be a corresponding private
|
1242
1281
|
* key with _certificate_.
|
@@ -1268,10 +1307,6 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
|
|
1268
1307
|
* ecdsa_pkey = ...
|
1269
1308
|
* another_ca_cert = ...
|
1270
1309
|
* ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])
|
1271
|
-
*
|
1272
|
-
* === Note
|
1273
|
-
* OpenSSL before the version 1.0.2 could handle only one extra chain across
|
1274
|
-
* all key types. Calling this method discards the chain set previously.
|
1275
1310
|
*/
|
1276
1311
|
static VALUE
|
1277
1312
|
ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
@@ -1296,7 +1331,7 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
|
1296
1331
|
EVP_PKEY_free(pub_pkey);
|
1297
1332
|
if (!pub_pkey)
|
1298
1333
|
rb_raise(rb_eArgError, "certificate does not contain public key");
|
1299
|
-
if (
|
1334
|
+
if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
|
1300
1335
|
rb_raise(rb_eArgError, "public key mismatch");
|
1301
1336
|
|
1302
1337
|
if (argc >= 3)
|
@@ -1310,34 +1345,9 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
|
1310
1345
|
sk_X509_pop_free(extra_chain, X509_free);
|
1311
1346
|
ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
|
1312
1347
|
}
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
|
1317
|
-
sk_X509_pop_free(extra_chain, X509_free);
|
1318
|
-
ossl_raise(eSSLError, "SSL_CTX_set0_chain");
|
1319
|
-
}
|
1320
|
-
#else
|
1321
|
-
STACK_OF(X509) *orig_extra_chain;
|
1322
|
-
X509 *x509_tmp;
|
1323
|
-
|
1324
|
-
/* First, clear the existing chain */
|
1325
|
-
SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
|
1326
|
-
if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
|
1327
|
-
rb_warning("SSL_CTX_set0_chain() is not available; " \
|
1328
|
-
"clearing previously set certificate chain");
|
1329
|
-
SSL_CTX_clear_extra_chain_certs(ctx);
|
1330
|
-
}
|
1331
|
-
while ((x509_tmp = sk_X509_shift(extra_chain))) {
|
1332
|
-
/* Transfers ownership */
|
1333
|
-
if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
|
1334
|
-
X509_free(x509_tmp);
|
1335
|
-
sk_X509_pop_free(extra_chain, X509_free);
|
1336
|
-
ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert");
|
1337
|
-
}
|
1338
|
-
}
|
1339
|
-
sk_X509_free(extra_chain);
|
1340
|
-
#endif
|
1348
|
+
if (extra_chain && !SSL_CTX_set0_chain(ctx, extra_chain)) {
|
1349
|
+
sk_X509_pop_free(extra_chain, X509_free);
|
1350
|
+
ossl_raise(eSSLError, "SSL_CTX_set0_chain");
|
1341
1351
|
}
|
1342
1352
|
return self;
|
1343
1353
|
}
|
@@ -1531,12 +1541,11 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
|
|
1531
1541
|
/*
|
1532
1542
|
* SSLSocket class
|
1533
1543
|
*/
|
1534
|
-
#ifndef OPENSSL_NO_SOCK
|
1535
1544
|
static inline int
|
1536
1545
|
ssl_started(SSL *ssl)
|
1537
1546
|
{
|
1538
|
-
/*
|
1539
|
-
return
|
1547
|
+
/* BIO is created through ossl_ssl_setup(), called by #connect or #accept */
|
1548
|
+
return SSL_get_rbio(ssl) != NULL;
|
1540
1549
|
}
|
1541
1550
|
|
1542
1551
|
static void
|
@@ -1544,6 +1553,10 @@ ossl_ssl_mark(void *ptr)
|
|
1544
1553
|
{
|
1545
1554
|
SSL *ssl = ptr;
|
1546
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.
|
1547
1560
|
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
|
1548
1561
|
}
|
1549
1562
|
|
@@ -1558,7 +1571,7 @@ const rb_data_type_t ossl_ssl_type = {
|
|
1558
1571
|
{
|
1559
1572
|
ossl_ssl_mark, ossl_ssl_free,
|
1560
1573
|
},
|
1561
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
1574
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
1562
1575
|
};
|
1563
1576
|
|
1564
1577
|
static VALUE
|
@@ -1567,6 +1580,29 @@ ossl_ssl_s_alloc(VALUE klass)
|
|
1567
1580
|
return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
|
1568
1581
|
}
|
1569
1582
|
|
1583
|
+
static VALUE
|
1584
|
+
peer_ip_address(VALUE self)
|
1585
|
+
{
|
1586
|
+
VALUE remote_address = rb_funcall(rb_attr_get(self, id_i_io), rb_intern("remote_address"), 0);
|
1587
|
+
|
1588
|
+
return rb_funcall(remote_address, rb_intern("inspect_sockaddr"), 0);
|
1589
|
+
}
|
1590
|
+
|
1591
|
+
static VALUE
|
1592
|
+
fallback_peer_ip_address(VALUE self, VALUE args)
|
1593
|
+
{
|
1594
|
+
return rb_str_new_cstr("(null)");
|
1595
|
+
}
|
1596
|
+
|
1597
|
+
static VALUE
|
1598
|
+
peeraddr_ip_str(VALUE self)
|
1599
|
+
{
|
1600
|
+
VALUE rb_mErrno = rb_const_get(rb_cObject, rb_intern("Errno"));
|
1601
|
+
VALUE rb_eSystemCallError = rb_const_get(rb_mErrno, rb_intern("SystemCallError"));
|
1602
|
+
|
1603
|
+
return rb_rescue2(peer_ip_address, self, fallback_peer_ip_address, (VALUE)0, rb_eSystemCallError, NULL);
|
1604
|
+
}
|
1605
|
+
|
1570
1606
|
/*
|
1571
1607
|
* call-seq:
|
1572
1608
|
* SSLSocket.new(io) => aSSLSocket
|
@@ -1603,6 +1639,7 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
|
1603
1639
|
|
1604
1640
|
if (rb_respond_to(io, rb_intern("nonblock=")))
|
1605
1641
|
rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
|
1642
|
+
Check_Type(io, T_FILE);
|
1606
1643
|
rb_ivar_set(self, id_i_io, io);
|
1607
1644
|
|
1608
1645
|
ssl = SSL_new(ctx);
|
@@ -1613,6 +1650,8 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
|
1613
1650
|
SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
|
1614
1651
|
SSL_set_info_callback(ssl, ssl_info_cb);
|
1615
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.
|
1616
1655
|
SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
|
1617
1656
|
|
1618
1657
|
rb_call_super(0, NULL);
|
@@ -1620,6 +1659,17 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
|
1620
1659
|
return self;
|
1621
1660
|
}
|
1622
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
|
+
|
1623
1673
|
static VALUE
|
1624
1674
|
ossl_ssl_setup(VALUE self)
|
1625
1675
|
{
|
@@ -1635,8 +1685,8 @@ ossl_ssl_setup(VALUE self)
|
|
1635
1685
|
GetOpenFile(io, fptr);
|
1636
1686
|
rb_io_check_readable(fptr);
|
1637
1687
|
rb_io_check_writable(fptr);
|
1638
|
-
if (!SSL_set_fd(ssl, TO_SOCKET(
|
1639
|
-
|
1688
|
+
if (!SSL_set_fd(ssl, TO_SOCKET(rb_io_descriptor(io))))
|
1689
|
+
ossl_raise(eSSLError, "SSL_set_fd");
|
1640
1690
|
|
1641
1691
|
return Qtrue;
|
1642
1692
|
}
|
@@ -1670,75 +1720,107 @@ no_exception_p(VALUE opts)
|
|
1670
1720
|
return 0;
|
1671
1721
|
}
|
1672
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
|
+
|
1728
|
+
static void
|
1729
|
+
io_wait_writable(VALUE io)
|
1730
|
+
{
|
1731
|
+
#ifdef HAVE_RB_IO_MAYBE_WAIT
|
1732
|
+
rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
|
1733
|
+
#else
|
1734
|
+
rb_io_t *fptr;
|
1735
|
+
GetOpenFile(io, fptr);
|
1736
|
+
rb_io_wait_writable(fptr->fd);
|
1737
|
+
#endif
|
1738
|
+
}
|
1739
|
+
|
1740
|
+
static void
|
1741
|
+
io_wait_readable(VALUE io)
|
1742
|
+
{
|
1743
|
+
#ifdef HAVE_RB_IO_MAYBE_WAIT
|
1744
|
+
rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
|
1745
|
+
#else
|
1746
|
+
rb_io_t *fptr;
|
1747
|
+
GetOpenFile(io, fptr);
|
1748
|
+
rb_io_wait_readable(fptr->fd);
|
1749
|
+
#endif
|
1750
|
+
}
|
1751
|
+
|
1673
1752
|
static VALUE
|
1674
|
-
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)
|
1675
1754
|
{
|
1676
1755
|
SSL *ssl;
|
1677
|
-
rb_io_t *fptr;
|
1678
1756
|
int ret, ret2;
|
1679
1757
|
VALUE cb_state;
|
1680
1758
|
int nonblock = opts != Qfalse;
|
1681
|
-
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
1682
|
-
unsigned long err;
|
1683
|
-
#endif
|
1684
1759
|
|
1685
1760
|
rb_ivar_set(self, ID_callback_state, Qnil);
|
1686
1761
|
|
1687
1762
|
GetSSL(self, ssl);
|
1688
1763
|
|
1689
|
-
|
1690
|
-
for(;;){
|
1691
|
-
|
1764
|
+
VALUE io = rb_attr_get(self, id_i_io);
|
1765
|
+
for (;;) {
|
1766
|
+
ret = func(ssl);
|
1692
1767
|
|
1693
|
-
|
1768
|
+
cb_state = rb_attr_get(self, ID_callback_state);
|
1694
1769
|
if (!NIL_P(cb_state)) {
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1770
|
+
/* must cleanup OpenSSL error stack before re-raising */
|
1771
|
+
ossl_clear_error();
|
1772
|
+
rb_jump_tag(NUM2INT(cb_state));
|
1773
|
+
}
|
1699
1774
|
|
1700
|
-
|
1701
|
-
|
1775
|
+
if (ret > 0)
|
1776
|
+
break;
|
1702
1777
|
|
1703
|
-
|
1704
|
-
|
1778
|
+
switch ((ret2 = ssl_get_error(ssl, ret))) {
|
1779
|
+
case SSL_ERROR_WANT_WRITE:
|
1705
1780
|
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1706
1781
|
write_would_block(nonblock);
|
1707
|
-
|
1782
|
+
io_wait_writable(io);
|
1708
1783
|
continue;
|
1709
|
-
|
1784
|
+
case SSL_ERROR_WANT_READ:
|
1710
1785
|
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1711
1786
|
read_would_block(nonblock);
|
1712
|
-
|
1787
|
+
io_wait_readable(io);
|
1713
1788
|
continue;
|
1714
|
-
|
1789
|
+
case SSL_ERROR_SYSCALL:
|
1715
1790
|
#ifdef __APPLE__
|
1716
1791
|
/* See ossl_ssl_write_internal() */
|
1717
1792
|
if (errno == EPROTOTYPE)
|
1718
1793
|
continue;
|
1719
1794
|
#endif
|
1720
|
-
|
1721
|
-
|
1795
|
+
if (errno) rb_sys_fail(funcname);
|
1796
|
+
/* fallthrough */
|
1797
|
+
default: {
|
1798
|
+
VALUE error_append = Qnil;
|
1722
1799
|
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
funcname, ret2, errno, SSL_state_string_long(ssl),
|
1736
|
-
err_msg, verify_msg);
|
1737
|
-
}
|
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
|
+
}
|
1738
1812
|
#endif
|
1739
|
-
|
1740
|
-
|
1741
|
-
|
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
|
+
}
|
1742
1824
|
}
|
1743
1825
|
|
1744
1826
|
return self;
|
@@ -1748,8 +1830,7 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|
1748
1830
|
* call-seq:
|
1749
1831
|
* ssl.connect => self
|
1750
1832
|
*
|
1751
|
-
* Initiates an SSL/TLS handshake with a server.
|
1752
|
-
* after unencrypted data has been sent over the socket.
|
1833
|
+
* Initiates an SSL/TLS handshake with a server.
|
1753
1834
|
*/
|
1754
1835
|
static VALUE
|
1755
1836
|
ossl_ssl_connect(VALUE self)
|
@@ -1796,8 +1877,7 @@ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
|
|
1796
1877
|
* call-seq:
|
1797
1878
|
* ssl.accept => self
|
1798
1879
|
*
|
1799
|
-
* Waits for a SSL/TLS client to initiate a handshake.
|
1800
|
-
* started after unencrypted data has been sent over the socket.
|
1880
|
+
* Waits for a SSL/TLS client to initiate a handshake.
|
1801
1881
|
*/
|
1802
1882
|
static VALUE
|
1803
1883
|
ossl_ssl_accept(VALUE self)
|
@@ -1844,16 +1924,18 @@ static VALUE
|
|
1844
1924
|
ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
1845
1925
|
{
|
1846
1926
|
SSL *ssl;
|
1847
|
-
int ilen
|
1927
|
+
int ilen;
|
1848
1928
|
VALUE len, str;
|
1849
|
-
|
1850
|
-
VALUE io, opts = Qnil;
|
1929
|
+
VALUE opts = Qnil;
|
1851
1930
|
|
1852
1931
|
if (nonblock) {
|
1853
1932
|
rb_scan_args(argc, argv, "11:", &len, &str, &opts);
|
1854
1933
|
} else {
|
1855
1934
|
rb_scan_args(argc, argv, "11", &len, &str);
|
1856
1935
|
}
|
1936
|
+
GetSSL(self, ssl);
|
1937
|
+
if (!ssl_started(ssl))
|
1938
|
+
rb_raise(eSSLError, "SSL session is not started yet");
|
1857
1939
|
|
1858
1940
|
ilen = NUM2INT(len);
|
1859
1941
|
if (NIL_P(str))
|
@@ -1869,85 +1951,59 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1869
1951
|
if (ilen == 0)
|
1870
1952
|
return str;
|
1871
1953
|
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1954
|
+
VALUE io = rb_attr_get(self, id_i_io);
|
1955
|
+
|
1956
|
+
rb_str_locktmp(str);
|
1957
|
+
for (;;) {
|
1958
|
+
int nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
|
1959
|
+
switch (ssl_get_error(ssl, nread)) {
|
1960
|
+
case SSL_ERROR_NONE:
|
1961
|
+
rb_str_unlocktmp(str);
|
1962
|
+
rb_str_set_len(str, nread);
|
1963
|
+
return str;
|
1964
|
+
case SSL_ERROR_ZERO_RETURN:
|
1965
|
+
rb_str_unlocktmp(str);
|
1966
|
+
if (no_exception_p(opts)) { return Qnil; }
|
1967
|
+
rb_eof_error();
|
1968
|
+
case SSL_ERROR_WANT_WRITE:
|
1969
|
+
if (nonblock) {
|
1881
1970
|
rb_str_unlocktmp(str);
|
1882
|
-
|
1883
|
-
|
1971
|
+
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1972
|
+
write_would_block(nonblock);
|
1973
|
+
}
|
1974
|
+
io_wait_writable(io);
|
1975
|
+
continue;
|
1976
|
+
case SSL_ERROR_WANT_READ:
|
1977
|
+
if (nonblock) {
|
1884
1978
|
rb_str_unlocktmp(str);
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
}
|
1893
|
-
rb_io_wait_writable(fptr->fd);
|
1894
|
-
continue;
|
1895
|
-
case SSL_ERROR_WANT_READ:
|
1896
|
-
if (nonblock) {
|
1897
|
-
rb_str_unlocktmp(str);
|
1898
|
-
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1899
|
-
read_would_block(nonblock);
|
1900
|
-
}
|
1901
|
-
rb_io_wait_readable(fptr->fd);
|
1902
|
-
continue;
|
1903
|
-
case SSL_ERROR_SYSCALL:
|
1904
|
-
if (!ERR_peek_error()) {
|
1905
|
-
rb_str_unlocktmp(str);
|
1906
|
-
if (errno)
|
1907
|
-
rb_sys_fail(0);
|
1908
|
-
else {
|
1909
|
-
/*
|
1910
|
-
* The underlying BIO returned 0. This is actually a
|
1911
|
-
* protocol error. But unfortunately, not all
|
1912
|
-
* implementations cleanly shutdown the TLS connection
|
1913
|
-
* but just shutdown/close the TCP connection. So report
|
1914
|
-
* EOF for now...
|
1915
|
-
*/
|
1916
|
-
if (no_exception_p(opts)) { return Qnil; }
|
1917
|
-
rb_eof_error();
|
1918
|
-
}
|
1919
|
-
}
|
1920
|
-
/* fall through */
|
1921
|
-
default:
|
1979
|
+
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1980
|
+
read_would_block(nonblock);
|
1981
|
+
}
|
1982
|
+
io_wait_readable(io);
|
1983
|
+
continue;
|
1984
|
+
case SSL_ERROR_SYSCALL:
|
1985
|
+
if (!ERR_peek_error()) {
|
1922
1986
|
rb_str_unlocktmp(str);
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
return rb_funcall(io, meth, 3, len, str, opts);
|
1987
|
+
if (errno)
|
1988
|
+
rb_sys_fail(0);
|
1989
|
+
else {
|
1990
|
+
/*
|
1991
|
+
* The underlying BIO returned 0. This is actually a
|
1992
|
+
* protocol error. But unfortunately, not all
|
1993
|
+
* implementations cleanly shutdown the TLS connection
|
1994
|
+
* but just shutdown/close the TCP connection. So report
|
1995
|
+
* EOF for now...
|
1996
|
+
*/
|
1997
|
+
if (no_exception_p(opts)) { return Qnil; }
|
1998
|
+
rb_eof_error();
|
1999
|
+
}
|
2000
|
+
}
|
2001
|
+
/* fall through */
|
2002
|
+
default:
|
2003
|
+
rb_str_unlocktmp(str);
|
2004
|
+
ossl_raise(eSSLError, "SSL_read");
|
1942
2005
|
}
|
1943
|
-
#endif
|
1944
|
-
else
|
1945
|
-
return rb_funcall(io, meth, 2, len, str);
|
1946
2006
|
}
|
1947
|
-
|
1948
|
-
end:
|
1949
|
-
rb_str_set_len(str, nread);
|
1950
|
-
return str;
|
1951
2007
|
}
|
1952
2008
|
|
1953
2009
|
/*
|
@@ -1987,77 +2043,55 @@ static VALUE
|
|
1987
2043
|
ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
1988
2044
|
{
|
1989
2045
|
SSL *ssl;
|
1990
|
-
int nwrite = 0;
|
1991
2046
|
rb_io_t *fptr;
|
1992
|
-
int nonblock = opts != Qfalse;
|
1993
|
-
VALUE tmp
|
2047
|
+
int num, nonblock = opts != Qfalse;
|
2048
|
+
VALUE tmp;
|
1994
2049
|
|
1995
|
-
tmp = rb_str_new_frozen(StringValue(str));
|
1996
2050
|
GetSSL(self, ssl);
|
1997
|
-
|
2051
|
+
if (!ssl_started(ssl))
|
2052
|
+
rb_raise(eSSLError, "SSL session is not started yet");
|
2053
|
+
|
2054
|
+
tmp = rb_str_new_frozen(StringValue(str));
|
2055
|
+
VALUE io = rb_attr_get(self, id_i_io);
|
1998
2056
|
GetOpenFile(io, fptr);
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2021
|
-
case SSL_ERROR_SYSCALL:
|
2057
|
+
|
2058
|
+
/* SSL_write(3ssl) manpage states num == 0 is undefined */
|
2059
|
+
num = RSTRING_LENINT(tmp);
|
2060
|
+
if (num == 0)
|
2061
|
+
return INT2FIX(0);
|
2062
|
+
|
2063
|
+
for (;;) {
|
2064
|
+
int nwritten = SSL_write(ssl, RSTRING_PTR(tmp), num);
|
2065
|
+
switch (ssl_get_error(ssl, nwritten)) {
|
2066
|
+
case SSL_ERROR_NONE:
|
2067
|
+
return INT2NUM(nwritten);
|
2068
|
+
case SSL_ERROR_WANT_WRITE:
|
2069
|
+
if (no_exception_p(opts)) { return sym_wait_writable; }
|
2070
|
+
write_would_block(nonblock);
|
2071
|
+
io_wait_writable(io);
|
2072
|
+
continue;
|
2073
|
+
case SSL_ERROR_WANT_READ:
|
2074
|
+
if (no_exception_p(opts)) { return sym_wait_readable; }
|
2075
|
+
read_would_block(nonblock);
|
2076
|
+
io_wait_readable(io);
|
2077
|
+
continue;
|
2078
|
+
case SSL_ERROR_SYSCALL:
|
2022
2079
|
#ifdef __APPLE__
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2080
|
+
/*
|
2081
|
+
* It appears that send syscall can return EPROTOTYPE if the
|
2082
|
+
* socket is being torn down. Retry to get a proper errno to
|
2083
|
+
* make the error handling in line with the socket library.
|
2084
|
+
* [Bug #14713] https://bugs.ruby-lang.org/issues/14713
|
2085
|
+
*/
|
2086
|
+
if (errno == EPROTOTYPE)
|
2087
|
+
continue;
|
2031
2088
|
#endif
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2089
|
+
if (errno) rb_sys_fail(0);
|
2090
|
+
/* fallthrough */
|
2091
|
+
default:
|
2092
|
+
ossl_raise(eSSLError, "SSL_write");
|
2036
2093
|
}
|
2037
2094
|
}
|
2038
|
-
else {
|
2039
|
-
ID meth = nonblock ?
|
2040
|
-
rb_intern("write_nonblock") : rb_intern("syswrite");
|
2041
|
-
|
2042
|
-
rb_warning("SSL session is not started yet.");
|
2043
|
-
#if defined(RB_PASS_KEYWORDS)
|
2044
|
-
if (nonblock) {
|
2045
|
-
VALUE argv[2];
|
2046
|
-
argv[0] = str;
|
2047
|
-
argv[1] = opts;
|
2048
|
-
return rb_funcallv_kw(io, meth, 2, argv, RB_PASS_KEYWORDS);
|
2049
|
-
}
|
2050
|
-
#else
|
2051
|
-
if (nonblock) {
|
2052
|
-
return rb_funcall(io, meth, 2, str, opts);
|
2053
|
-
}
|
2054
|
-
#endif
|
2055
|
-
else
|
2056
|
-
return rb_funcall(io, meth, 1, str);
|
2057
|
-
}
|
2058
|
-
|
2059
|
-
end:
|
2060
|
-
return INT2NUM(nwrite);
|
2061
2095
|
}
|
2062
2096
|
|
2063
2097
|
/*
|
@@ -2432,7 +2466,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
|
|
2432
2466
|
return ossl_x509name_sk2ary(ca);
|
2433
2467
|
}
|
2434
2468
|
|
2435
|
-
#
|
2469
|
+
# ifdef OSSL_USE_NEXTPROTONEG
|
2436
2470
|
/*
|
2437
2471
|
* call-seq:
|
2438
2472
|
* ssl.npn_protocol => String | nil
|
@@ -2457,7 +2491,6 @@ ossl_ssl_npn_protocol(VALUE self)
|
|
2457
2491
|
}
|
2458
2492
|
# endif
|
2459
2493
|
|
2460
|
-
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2461
2494
|
/*
|
2462
2495
|
* call-seq:
|
2463
2496
|
* ssl.alpn_protocol => String | nil
|
@@ -2480,9 +2513,50 @@ ossl_ssl_alpn_protocol(VALUE self)
|
|
2480
2513
|
else
|
2481
2514
|
return rb_str_new((const char *) out, outlen);
|
2482
2515
|
}
|
2483
|
-
# endif
|
2484
2516
|
|
2485
|
-
|
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
|
+
|
2486
2560
|
/*
|
2487
2561
|
* call-seq:
|
2488
2562
|
* ssl.tmp_key => PKey or nil
|
@@ -2500,7 +2574,6 @@ ossl_ssl_tmp_key(VALUE self)
|
|
2500
2574
|
return Qnil;
|
2501
2575
|
return ossl_pkey_new(key);
|
2502
2576
|
}
|
2503
|
-
# endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */
|
2504
2577
|
#endif /* !defined(OPENSSL_NO_SOCK) */
|
2505
2578
|
|
2506
2579
|
void
|
@@ -2513,6 +2586,7 @@ Init_ossl_ssl(void)
|
|
2513
2586
|
rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
|
2514
2587
|
#endif
|
2515
2588
|
|
2589
|
+
#ifndef OPENSSL_NO_SOCK
|
2516
2590
|
id_call = rb_intern_const("call");
|
2517
2591
|
ID_callback_state = rb_intern_const("callback_state");
|
2518
2592
|
|
@@ -2525,11 +2599,6 @@ Init_ossl_ssl(void)
|
|
2525
2599
|
ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
|
2526
2600
|
if (ossl_sslctx_ex_ptr_idx < 0)
|
2527
2601
|
ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
|
2528
|
-
#if !defined(HAVE_X509_STORE_UP_REF)
|
2529
|
-
ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_store_p", 0, 0, 0);
|
2530
|
-
if (ossl_sslctx_ex_store_p < 0)
|
2531
|
-
ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
|
2532
|
-
#endif
|
2533
2602
|
|
2534
2603
|
/* Document-module: OpenSSL::SSL
|
2535
2604
|
*
|
@@ -2540,16 +2609,6 @@ Init_ossl_ssl(void)
|
|
2540
2609
|
*/
|
2541
2610
|
mSSL = rb_define_module_under(mOSSL, "SSL");
|
2542
2611
|
|
2543
|
-
/* Document-module: OpenSSL::ExtConfig
|
2544
|
-
*
|
2545
|
-
* This module contains configuration information about the SSL extension,
|
2546
|
-
* for example if socket support is enabled, or the host name TLS extension
|
2547
|
-
* is enabled. Constants in this module will always be defined, but contain
|
2548
|
-
* +true+ or +false+ values depending on the configuration of your OpenSSL
|
2549
|
-
* installation.
|
2550
|
-
*/
|
2551
|
-
mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig");
|
2552
|
-
|
2553
2612
|
/* Document-class: OpenSSL::SSL::SSLError
|
2554
2613
|
*
|
2555
2614
|
* Generic error class raised by SSLSocket and SSLContext.
|
@@ -2677,20 +2736,6 @@ Init_ossl_ssl(void)
|
|
2677
2736
|
*/
|
2678
2737
|
rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
|
2679
2738
|
|
2680
|
-
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
2681
|
-
/*
|
2682
|
-
* A callback invoked when ECDH parameters are required.
|
2683
|
-
*
|
2684
|
-
* The callback is invoked with the Session for the key exchange, an
|
2685
|
-
* flag indicating the use of an export cipher and the keylength
|
2686
|
-
* required.
|
2687
|
-
*
|
2688
|
-
* The callback is deprecated. This does not work with recent versions of
|
2689
|
-
* OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead.
|
2690
|
-
*/
|
2691
|
-
rb_attr(cSSLContext, rb_intern_const("tmp_ecdh_callback"), 1, 1, Qfalse);
|
2692
|
-
#endif
|
2693
|
-
|
2694
2739
|
/*
|
2695
2740
|
* Sets the context in which a session can be reused. This allows
|
2696
2741
|
* sessions for multiple applications to be distinguished, for example, by
|
@@ -2726,8 +2771,6 @@ Init_ossl_ssl(void)
|
|
2726
2771
|
*/
|
2727
2772
|
rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
|
2728
2773
|
|
2729
|
-
rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
|
2730
|
-
|
2731
2774
|
/*
|
2732
2775
|
* A callback invoked whenever a new handshake is initiated on an
|
2733
2776
|
* established connection. May be used to disable renegotiation entirely.
|
@@ -2748,7 +2791,7 @@ Init_ossl_ssl(void)
|
|
2748
2791
|
* end
|
2749
2792
|
*/
|
2750
2793
|
rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
|
2751
|
-
#
|
2794
|
+
#ifdef OSSL_USE_NEXTPROTONEG
|
2752
2795
|
/*
|
2753
2796
|
* An Enumerable of Strings. Each String represents a protocol to be
|
2754
2797
|
* advertised as the list of supported protocols for Next Protocol
|
@@ -2780,7 +2823,6 @@ Init_ossl_ssl(void)
|
|
2780
2823
|
rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse);
|
2781
2824
|
#endif
|
2782
2825
|
|
2783
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2784
2826
|
/*
|
2785
2827
|
* An Enumerable of Strings. Each String represents a protocol to be
|
2786
2828
|
* advertised as the list of supported protocols for Application-Layer
|
@@ -2810,7 +2852,29 @@ Init_ossl_ssl(void)
|
|
2810
2852
|
* end
|
2811
2853
|
*/
|
2812
2854
|
rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
|
2813
|
-
|
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);
|
2814
2878
|
|
2815
2879
|
rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
|
2816
2880
|
rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
|
@@ -2818,6 +2882,12 @@ Init_ossl_ssl(void)
|
|
2818
2882
|
ossl_sslctx_set_minmax_proto_version, 2);
|
2819
2883
|
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
|
2820
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
|
2888
|
+
#ifndef OPENSSL_NO_DH
|
2889
|
+
rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
|
2890
|
+
#endif
|
2821
2891
|
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
|
2822
2892
|
rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
|
2823
2893
|
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
|
@@ -2891,11 +2961,6 @@ Init_ossl_ssl(void)
|
|
2891
2961
|
* Document-class: OpenSSL::SSL::SSLSocket
|
2892
2962
|
*/
|
2893
2963
|
cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
|
2894
|
-
#ifdef OPENSSL_NO_SOCK
|
2895
|
-
rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue);
|
2896
|
-
rb_define_method(cSSLSocket, "initialize", rb_f_notimplement, -1);
|
2897
|
-
#else
|
2898
|
-
rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse);
|
2899
2964
|
rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
|
2900
2965
|
rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
|
2901
2966
|
rb_undef_method(cSSLSocket, "initialize_copy");
|
@@ -2924,16 +2989,12 @@ Init_ossl_ssl(void)
|
|
2924
2989
|
rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
|
2925
2990
|
rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0);
|
2926
2991
|
rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
|
2927
|
-
# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
|
2928
2992
|
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
|
2929
|
-
# endif
|
2930
|
-
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2931
2993
|
rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
|
2932
|
-
|
2933
|
-
#
|
2994
|
+
rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1);
|
2995
|
+
# ifdef OSSL_USE_NEXTPROTONEG
|
2934
2996
|
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
|
2935
2997
|
# endif
|
2936
|
-
#endif
|
2937
2998
|
|
2938
2999
|
rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
|
2939
3000
|
rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
|
@@ -2941,12 +3002,23 @@ Init_ossl_ssl(void)
|
|
2941
3002
|
rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
|
2942
3003
|
|
2943
3004
|
rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL));
|
3005
|
+
#ifdef SSL_OP_CLEANSE_PLAINTEXT /* OpenSSL 3.0 */
|
3006
|
+
rb_define_const(mSSL, "OP_CLEANSE_PLAINTEXT", ULONG2NUM(SSL_OP_CLEANSE_PLAINTEXT));
|
3007
|
+
#endif
|
2944
3008
|
rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
|
2945
|
-
#ifdef
|
2946
|
-
rb_define_const(mSSL, "
|
3009
|
+
#ifdef SSL_OP_ENABLE_KTLS /* OpenSSL 3.0 */
|
3010
|
+
rb_define_const(mSSL, "OP_ENABLE_KTLS", ULONG2NUM(SSL_OP_ENABLE_KTLS));
|
2947
3011
|
#endif
|
2948
|
-
|
3012
|
+
rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
|
2949
3013
|
rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG));
|
3014
|
+
#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* OpenSSL 3.0 */
|
3015
|
+
rb_define_const(mSSL, "OP_IGNORE_UNEXPECTED_EOF", ULONG2NUM(SSL_OP_IGNORE_UNEXPECTED_EOF));
|
3016
|
+
#endif
|
3017
|
+
#ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION /* OpenSSL 3.0 */
|
3018
|
+
rb_define_const(mSSL, "OP_ALLOW_CLIENT_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_CLIENT_RENEGOTIATION));
|
3019
|
+
#endif
|
3020
|
+
#ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */
|
3021
|
+
rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES));
|
2950
3022
|
#endif
|
2951
3023
|
#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
|
2952
3024
|
rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
|
@@ -2959,13 +3031,15 @@ Init_ossl_ssl(void)
|
|
2959
3031
|
#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
|
2960
3032
|
rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
|
2961
3033
|
#endif
|
2962
|
-
|
2963
|
-
rb_define_const(mSSL, "
|
2964
|
-
#
|
2965
|
-
|
3034
|
+
#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */
|
3035
|
+
rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT));
|
3036
|
+
#endif
|
3037
|
+
#ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */
|
3038
|
+
rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA));
|
3039
|
+
#endif
|
3040
|
+
#ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */
|
3041
|
+
rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY));
|
2966
3042
|
#endif
|
2967
|
-
rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
|
2968
|
-
|
2969
3043
|
rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
|
2970
3044
|
rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
|
2971
3045
|
rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
|
@@ -2973,6 +3047,12 @@ Init_ossl_ssl(void)
|
|
2973
3047
|
#ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
|
2974
3048
|
rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
|
2975
3049
|
#endif
|
3050
|
+
rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
|
3051
|
+
rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
|
3052
|
+
#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
|
3053
|
+
rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
|
3054
|
+
#endif
|
3055
|
+
rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
|
2976
3056
|
|
2977
3057
|
/* SSL_OP_* flags for DTLS */
|
2978
3058
|
#if 0
|
@@ -3042,7 +3122,6 @@ Init_ossl_ssl(void)
|
|
3042
3122
|
sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
|
3043
3123
|
|
3044
3124
|
id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
|
3045
|
-
id_tmp_ecdh_callback = rb_intern_const("tmp_ecdh_callback");
|
3046
3125
|
id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
|
3047
3126
|
id_each = rb_intern_const("each");
|
3048
3127
|
|
@@ -3061,7 +3140,6 @@ Init_ossl_ssl(void)
|
|
3061
3140
|
DefIVarID(key);
|
3062
3141
|
DefIVarID(extra_chain_cert);
|
3063
3142
|
DefIVarID(client_cert_cb);
|
3064
|
-
DefIVarID(tmp_ecdh_callback);
|
3065
3143
|
DefIVarID(timeout);
|
3066
3144
|
DefIVarID(session_id_context);
|
3067
3145
|
DefIVarID(session_get_cb);
|
@@ -3073,8 +3151,10 @@ Init_ossl_ssl(void)
|
|
3073
3151
|
DefIVarID(alpn_select_cb);
|
3074
3152
|
DefIVarID(servername_cb);
|
3075
3153
|
DefIVarID(verify_hostname);
|
3154
|
+
DefIVarID(keylog_cb);
|
3076
3155
|
|
3077
3156
|
DefIVarID(io);
|
3078
3157
|
DefIVarID(context);
|
3079
3158
|
DefIVarID(hostname);
|
3159
|
+
#endif /* !defined(OPENSSL_NO_SOCK) */
|
3080
3160
|
}
|