openssl 2.1.0 → 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 +35 -45
- data/History.md +426 -0
- data/README.md +38 -21
- data/ext/openssl/extconf.rb +132 -72
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +62 -46
- data/ext/openssl/ossl.c +177 -252
- data/ext/openssl/ossl.h +39 -17
- data/ext/openssl/ossl_asn1.c +53 -14
- data/ext/openssl/ossl_bn.c +288 -146
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +42 -32
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +32 -63
- data/ext/openssl/ossl_engine.c +19 -28
- data/ext/openssl/ossl_hmac.c +61 -146
- data/ext/openssl/ossl_kdf.c +15 -23
- data/ext/openssl/ossl_ns_spki.c +2 -2
- data/ext/openssl/ossl_ocsp.c +17 -70
- data/ext/openssl/ossl_ocsp.h +3 -3
- data/ext/openssl/ossl_pkcs12.c +23 -4
- data/ext/openssl/ossl_pkcs7.c +49 -81
- data/ext/openssl/ossl_pkcs7.h +16 -0
- data/ext/openssl/ossl_pkey.c +1508 -195
- data/ext/openssl/ossl_pkey.h +41 -78
- data/ext/openssl/ossl_pkey_dh.c +153 -348
- data/ext/openssl/ossl_pkey_dsa.c +157 -413
- data/ext/openssl/ossl_pkey_ec.c +257 -343
- data/ext/openssl/ossl_pkey_rsa.c +166 -490
- data/ext/openssl/ossl_provider.c +211 -0
- data/ext/openssl/ossl_provider.h +5 -0
- data/ext/openssl/ossl_rand.c +2 -40
- data/ext/openssl/ossl_ssl.c +666 -456
- data/ext/openssl/ossl_ssl_session.c +29 -30
- data/ext/openssl/ossl_ts.c +1539 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509.c +86 -1
- data/ext/openssl/ossl_x509attr.c +1 -1
- data/ext/openssl/ossl_x509cert.c +170 -14
- data/ext/openssl/ossl_x509crl.c +14 -11
- data/ext/openssl/ossl_x509ext.c +29 -9
- data/ext/openssl/ossl_x509name.c +24 -12
- data/ext/openssl/ossl_x509req.c +14 -11
- data/ext/openssl/ossl_x509revoked.c +4 -4
- data/ext/openssl/ossl_x509store.c +205 -96
- data/lib/openssl/bn.rb +1 -1
- data/lib/openssl/buffering.rb +42 -20
- data/lib/openssl/cipher.rb +1 -1
- data/lib/openssl/digest.rb +10 -16
- data/lib/openssl/hmac.rb +78 -0
- data/lib/openssl/marshal.rb +30 -0
- data/lib/openssl/pkcs5.rb +1 -1
- data/lib/openssl/pkey.rb +447 -1
- data/lib/openssl/ssl.rb +68 -24
- data/lib/openssl/version.rb +5 -0
- data/lib/openssl/x509.rb +177 -1
- data/lib/openssl.rb +24 -9
- metadata +18 -71
- data/ext/openssl/deprecation.rb +0 -23
- data/ext/openssl/ossl_version.h +0 -15
- data/ext/openssl/ruby_missing.h +0 -24
- data/lib/openssl/config.rb +0 -474
data/ext/openssl/ossl_ssl.c
CHANGED
@@ -11,8 +11,18 @@
|
|
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
|
+
|
21
|
+
#if !defined(TLS1_3_VERSION) && \
|
22
|
+
OSSL_LIBRESSL_PREREQ(3, 2, 0) && !OSSL_LIBRESSL_PREREQ(3, 4, 0)
|
23
|
+
# define TLS1_3_VERSION 0x0304
|
24
|
+
#endif
|
25
|
+
|
16
26
|
#ifdef _WIN32
|
17
27
|
# define TO_SOCKET(s) _get_osfhandle(s)
|
18
28
|
#else
|
@@ -24,7 +34,6 @@
|
|
24
34
|
} while (0)
|
25
35
|
|
26
36
|
VALUE mSSL;
|
27
|
-
static VALUE mSSLExtConfig;
|
28
37
|
static VALUE eSSLError;
|
29
38
|
VALUE cSSLContext;
|
30
39
|
VALUE cSSLSocket;
|
@@ -32,44 +41,43 @@ VALUE cSSLSocket;
|
|
32
41
|
static VALUE eSSLErrorWaitReadable;
|
33
42
|
static VALUE eSSLErrorWaitWritable;
|
34
43
|
|
35
|
-
static ID id_call, ID_callback_state, id_tmp_dh_callback,
|
36
|
-
id_npn_protocols_encoded;
|
44
|
+
static ID id_call, ID_callback_state, id_tmp_dh_callback,
|
45
|
+
id_npn_protocols_encoded, id_each;
|
37
46
|
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
|
38
47
|
|
39
48
|
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
|
40
49
|
id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
|
41
50
|
id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
|
42
|
-
id_i_client_cert_cb,
|
51
|
+
id_i_client_cert_cb, id_i_timeout,
|
43
52
|
id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
|
44
53
|
id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
|
45
54
|
id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
|
46
|
-
id_i_verify_hostname;
|
55
|
+
id_i_verify_hostname, id_i_keylog_cb;
|
47
56
|
static ID id_i_io, id_i_context, id_i_hostname;
|
48
57
|
|
49
58
|
static int ossl_ssl_ex_vcb_idx;
|
50
59
|
static int ossl_ssl_ex_ptr_idx;
|
51
60
|
static int ossl_sslctx_ex_ptr_idx;
|
52
|
-
#if !defined(HAVE_X509_STORE_UP_REF)
|
53
|
-
static int ossl_sslctx_ex_store_p;
|
54
|
-
#endif
|
55
61
|
|
56
62
|
static void
|
57
|
-
|
63
|
+
ossl_sslctx_mark(void *ptr)
|
58
64
|
{
|
59
65
|
SSL_CTX *ctx = ptr;
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
66
|
+
rb_gc_mark((VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx));
|
67
|
+
}
|
68
|
+
|
69
|
+
static void
|
70
|
+
ossl_sslctx_free(void *ptr)
|
71
|
+
{
|
72
|
+
SSL_CTX_free(ptr);
|
65
73
|
}
|
66
74
|
|
67
75
|
static const rb_data_type_t ossl_sslctx_type = {
|
68
76
|
"OpenSSL/SSL/CTX",
|
69
77
|
{
|
70
|
-
|
78
|
+
ossl_sslctx_mark, ossl_sslctx_free,
|
71
79
|
},
|
72
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
80
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
73
81
|
};
|
74
82
|
|
75
83
|
static VALUE
|
@@ -83,7 +91,7 @@ ossl_sslctx_s_alloc(VALUE klass)
|
|
83
91
|
VALUE obj;
|
84
92
|
|
85
93
|
obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
|
86
|
-
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
94
|
+
#if OPENSSL_VERSION_NUMBER >= 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
|
87
95
|
ctx = SSL_CTX_new(TLS_method());
|
88
96
|
#else
|
89
97
|
ctx = SSL_CTX_new(SSLv23_method());
|
@@ -95,14 +103,15 @@ ossl_sslctx_s_alloc(VALUE klass)
|
|
95
103
|
RTYPEDDATA_DATA(obj) = ctx;
|
96
104
|
SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj);
|
97
105
|
|
98
|
-
#if !defined(OPENSSL_NO_EC) &&
|
106
|
+
#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER < 0x10100000 && \
|
107
|
+
!defined(LIBRESSL_VERSION_NUMBER)
|
99
108
|
/* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
|
100
109
|
* allows to specify multiple curve names and OpenSSL will select
|
101
110
|
* automatically from them. In OpenSSL 1.0.2, the automatic selection has to
|
102
|
-
* be enabled explicitly.
|
103
|
-
* always enabled. To uniform the behavior, we enable the
|
104
|
-
* selection also in 1.0.2. Users can still disable ECDH by
|
105
|
-
* 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=. */
|
106
115
|
if (!SSL_CTX_set_ecdh_auto(ctx, 1))
|
107
116
|
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
108
117
|
#endif
|
@@ -184,8 +193,10 @@ ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
|
|
184
193
|
|
185
194
|
for (i = 0; i < numberof(options_map); i++) {
|
186
195
|
sum |= options_map[i].opts;
|
187
|
-
|
196
|
+
if ((min && min > options_map[i].ver) ||
|
197
|
+
(max && max < options_map[i].ver)) {
|
188
198
|
opts |= options_map[i].opts;
|
199
|
+
}
|
189
200
|
}
|
190
201
|
SSL_CTX_clear_options(ctx, sum);
|
191
202
|
SSL_CTX_set_options(ctx, opts);
|
@@ -229,8 +240,7 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
|
229
240
|
return 1;
|
230
241
|
}
|
231
242
|
|
232
|
-
#if !defined(OPENSSL_NO_DH)
|
233
|
-
!defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
243
|
+
#if !defined(OPENSSL_NO_DH)
|
234
244
|
struct tmp_dh_callback_args {
|
235
245
|
VALUE ssl_obj;
|
236
246
|
ID id;
|
@@ -239,22 +249,23 @@ struct tmp_dh_callback_args {
|
|
239
249
|
int keylength;
|
240
250
|
};
|
241
251
|
|
242
|
-
static
|
243
|
-
ossl_call_tmp_dh_callback(
|
252
|
+
static VALUE
|
253
|
+
ossl_call_tmp_dh_callback(VALUE arg)
|
244
254
|
{
|
255
|
+
struct tmp_dh_callback_args *args = (struct tmp_dh_callback_args *)arg;
|
245
256
|
VALUE cb, dh;
|
246
257
|
EVP_PKEY *pkey;
|
247
258
|
|
248
259
|
cb = rb_funcall(args->ssl_obj, args->id, 0);
|
249
260
|
if (NIL_P(cb))
|
250
|
-
return NULL;
|
261
|
+
return (VALUE)NULL;
|
251
262
|
dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
|
252
263
|
INT2NUM(args->keylength));
|
253
264
|
pkey = GetPKeyPtr(dh);
|
254
265
|
if (EVP_PKEY_base_id(pkey) != args->type)
|
255
|
-
return NULL;
|
266
|
+
return (VALUE)NULL;
|
256
267
|
|
257
|
-
return pkey;
|
268
|
+
return (VALUE)pkey;
|
258
269
|
}
|
259
270
|
#endif
|
260
271
|
|
@@ -274,7 +285,7 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
|
274
285
|
args.keylength = keylength;
|
275
286
|
args.type = EVP_PKEY_DH;
|
276
287
|
|
277
|
-
pkey = (EVP_PKEY *)rb_protect(
|
288
|
+
pkey = (EVP_PKEY *)rb_protect(ossl_call_tmp_dh_callback,
|
278
289
|
(VALUE)&args, &state);
|
279
290
|
if (state) {
|
280
291
|
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
@@ -283,39 +294,10 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
|
283
294
|
if (!pkey)
|
284
295
|
return NULL;
|
285
296
|
|
286
|
-
return EVP_PKEY_get0_DH(pkey);
|
297
|
+
return (DH *)EVP_PKEY_get0_DH(pkey);
|
287
298
|
}
|
288
299
|
#endif /* OPENSSL_NO_DH */
|
289
300
|
|
290
|
-
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
291
|
-
static EC_KEY *
|
292
|
-
ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
|
293
|
-
{
|
294
|
-
VALUE rb_ssl;
|
295
|
-
EVP_PKEY *pkey;
|
296
|
-
struct tmp_dh_callback_args args;
|
297
|
-
int state;
|
298
|
-
|
299
|
-
rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
300
|
-
args.ssl_obj = rb_ssl;
|
301
|
-
args.id = id_tmp_ecdh_callback;
|
302
|
-
args.is_export = is_export;
|
303
|
-
args.keylength = keylength;
|
304
|
-
args.type = EVP_PKEY_EC;
|
305
|
-
|
306
|
-
pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
|
307
|
-
(VALUE)&args, &state);
|
308
|
-
if (state) {
|
309
|
-
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
310
|
-
return NULL;
|
311
|
-
}
|
312
|
-
if (!pkey)
|
313
|
-
return NULL;
|
314
|
-
|
315
|
-
return EVP_PKEY_get0_EC_KEY(pkey);
|
316
|
-
}
|
317
|
-
#endif
|
318
|
-
|
319
301
|
static VALUE
|
320
302
|
call_verify_certificate_identity(VALUE ctx_v)
|
321
303
|
{
|
@@ -357,7 +339,14 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|
357
339
|
rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
|
358
340
|
return 0;
|
359
341
|
}
|
360
|
-
|
342
|
+
if (ret != Qtrue) {
|
343
|
+
preverify_ok = 0;
|
344
|
+
#if defined(X509_V_ERR_HOSTNAME_MISMATCH)
|
345
|
+
X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
|
346
|
+
#else
|
347
|
+
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
|
348
|
+
#endif
|
349
|
+
}
|
361
350
|
}
|
362
351
|
|
363
352
|
return ossl_verify_cb_call(cb, preverify_ok, ctx);
|
@@ -378,7 +367,7 @@ ossl_call_session_get_cb(VALUE ary)
|
|
378
367
|
}
|
379
368
|
|
380
369
|
static SSL_SESSION *
|
381
|
-
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
370
|
+
#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
|
382
371
|
ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
|
383
372
|
#else
|
384
373
|
ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
|
@@ -455,6 +444,54 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
|
|
455
444
|
return 0;
|
456
445
|
}
|
457
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
|
+
|
458
495
|
static VALUE
|
459
496
|
ossl_call_session_remove_cb(VALUE ary)
|
460
497
|
{
|
@@ -587,10 +624,8 @@ ssl_renegotiation_cb(const SSL *ssl)
|
|
587
624
|
rb_funcallv(cb, id_call, 1, &ssl_obj);
|
588
625
|
}
|
589
626
|
|
590
|
-
#if !defined(OPENSSL_NO_NEXTPROTONEG) || \
|
591
|
-
defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
|
592
627
|
static VALUE
|
593
|
-
ssl_npn_encode_protocol_i(
|
628
|
+
ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
|
594
629
|
{
|
595
630
|
int len = RSTRING_LENINT(cur);
|
596
631
|
char len_byte;
|
@@ -607,7 +642,7 @@ static VALUE
|
|
607
642
|
ssl_encode_npn_protocols(VALUE protocols)
|
608
643
|
{
|
609
644
|
VALUE encoded = rb_str_new(NULL, 0);
|
610
|
-
|
645
|
+
rb_block_call(protocols, id_each, 0, 0, ssl_npn_encode_protocol_i, encoded);
|
611
646
|
return encoded;
|
612
647
|
}
|
613
648
|
|
@@ -670,14 +705,13 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
|
|
670
705
|
|
671
706
|
return SSL_TLSEXT_ERR_OK;
|
672
707
|
}
|
673
|
-
#endif
|
674
708
|
|
675
|
-
#
|
709
|
+
#ifdef OSSL_USE_NEXTPROTONEG
|
676
710
|
static int
|
677
711
|
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
|
678
712
|
void *arg)
|
679
713
|
{
|
680
|
-
VALUE protocols = (VALUE)arg;
|
714
|
+
VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded);
|
681
715
|
|
682
716
|
*out = (const unsigned char *) RSTRING_PTR(protocols);
|
683
717
|
*outlen = RSTRING_LENINT(protocols);
|
@@ -699,7 +733,6 @@ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
|
|
699
733
|
}
|
700
734
|
#endif
|
701
735
|
|
702
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
703
736
|
static int
|
704
737
|
ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
705
738
|
const unsigned char *in, unsigned int inlen, void *arg)
|
@@ -711,7 +744,6 @@ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
|
711
744
|
|
712
745
|
return ssl_npn_select_cb_common(ssl, cb, out, outlen, in, inlen);
|
713
746
|
}
|
714
|
-
#endif
|
715
747
|
|
716
748
|
/* This function may serve as the entry point to support further callbacks. */
|
717
749
|
static void
|
@@ -788,41 +820,15 @@ ossl_sslctx_setup(VALUE self)
|
|
788
820
|
SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
|
789
821
|
#endif
|
790
822
|
|
791
|
-
#
|
792
|
-
|
793
|
-
|
794
|
-
if (RTEST(rb_attr_get(self, id_i_tmp_ecdh_callback))) {
|
795
|
-
# if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
796
|
-
rb_warn("#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
|
797
|
-
SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
|
798
|
-
# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
|
799
|
-
/* tmp_ecdh_callback and ecdh_auto conflict; OpenSSL ignores
|
800
|
-
* tmp_ecdh_callback. So disable ecdh_auto. */
|
801
|
-
if (!SSL_CTX_set_ecdh_auto(ctx, 0))
|
802
|
-
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
803
|
-
# endif
|
804
|
-
# else
|
805
|
-
ossl_raise(eSSLError, "OpenSSL does not support tmp_ecdh_callback; "
|
806
|
-
"use #ecdh_curves= instead");
|
807
|
-
# endif
|
808
|
-
}
|
809
|
-
#endif /* OPENSSL_NO_EC */
|
823
|
+
#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
|
824
|
+
SSL_CTX_set_post_handshake_auth(ctx, 1);
|
825
|
+
#endif
|
810
826
|
|
811
827
|
val = rb_attr_get(self, id_i_cert_store);
|
812
828
|
if (!NIL_P(val)) {
|
813
829
|
X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
|
814
830
|
SSL_CTX_set_cert_store(ctx, store);
|
815
|
-
#if !defined(HAVE_X509_STORE_UP_REF)
|
816
|
-
/*
|
817
|
-
* WORKAROUND:
|
818
|
-
* X509_STORE can count references, but
|
819
|
-
* X509_STORE_free() doesn't care it.
|
820
|
-
* So we won't increment it but mark it by ex_data.
|
821
|
-
*/
|
822
|
-
SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
|
823
|
-
#else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
|
824
831
|
X509_STORE_up_ref(store);
|
825
|
-
#endif
|
826
832
|
}
|
827
833
|
|
828
834
|
val = rb_attr_get(self, id_i_extra_chain_cert);
|
@@ -873,10 +879,17 @@ ossl_sslctx_setup(VALUE self)
|
|
873
879
|
ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
|
874
880
|
val = rb_attr_get(self, id_i_ca_path);
|
875
881
|
ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
|
876
|
-
|
877
|
-
|
878
|
-
|
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");
|
879
891
|
}
|
892
|
+
#endif
|
880
893
|
|
881
894
|
val = rb_attr_get(self, id_i_verify_mode);
|
882
895
|
verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
|
@@ -890,12 +903,12 @@ ossl_sslctx_setup(VALUE self)
|
|
890
903
|
val = rb_attr_get(self, id_i_verify_depth);
|
891
904
|
if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
|
892
905
|
|
893
|
-
#
|
906
|
+
#ifdef OSSL_USE_NEXTPROTONEG
|
894
907
|
val = rb_attr_get(self, id_i_npn_protocols);
|
895
908
|
if (!NIL_P(val)) {
|
896
909
|
VALUE encoded = ssl_encode_npn_protocols(val);
|
897
910
|
rb_ivar_set(self, id_npn_protocols_encoded, encoded);
|
898
|
-
SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)
|
911
|
+
SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
|
899
912
|
OSSL_Debug("SSL NPN advertise callback added");
|
900
913
|
}
|
901
914
|
if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
|
@@ -904,7 +917,6 @@ ossl_sslctx_setup(VALUE self)
|
|
904
917
|
}
|
905
918
|
#endif
|
906
919
|
|
907
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
908
920
|
val = rb_attr_get(self, id_i_alpn_protocols);
|
909
921
|
if (!NIL_P(val)) {
|
910
922
|
VALUE rprotos = ssl_encode_npn_protocols(val);
|
@@ -919,7 +931,6 @@ ossl_sslctx_setup(VALUE self)
|
|
919
931
|
SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
|
920
932
|
OSSL_Debug("SSL ALPN select callback added");
|
921
933
|
}
|
922
|
-
#endif
|
923
934
|
|
924
935
|
rb_obj_freeze(self);
|
925
936
|
|
@@ -951,6 +962,18 @@ ossl_sslctx_setup(VALUE self)
|
|
951
962
|
OSSL_Debug("SSL TLSEXT servername callback added");
|
952
963
|
}
|
953
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
|
+
|
954
977
|
return Qtrue;
|
955
978
|
}
|
956
979
|
|
@@ -999,27 +1022,13 @@ ossl_sslctx_get_ciphers(VALUE self)
|
|
999
1022
|
return ary;
|
1000
1023
|
}
|
1001
1024
|
|
1002
|
-
/*
|
1003
|
-
* call-seq:
|
1004
|
-
* ctx.ciphers = "cipher1:cipher2:..."
|
1005
|
-
* ctx.ciphers = [name, ...]
|
1006
|
-
* ctx.ciphers = [[name, version, bits, alg_bits], ...]
|
1007
|
-
*
|
1008
|
-
* Sets the list of available cipher suites for this context. Note in a server
|
1009
|
-
* context some ciphers require the appropriate certificates. For example, an
|
1010
|
-
* RSA cipher suite can only be chosen when an RSA certificate is available.
|
1011
|
-
*/
|
1012
1025
|
static VALUE
|
1013
|
-
|
1026
|
+
build_cipher_string(VALUE v)
|
1014
1027
|
{
|
1015
|
-
SSL_CTX *ctx;
|
1016
1028
|
VALUE str, elem;
|
1017
1029
|
int i;
|
1018
1030
|
|
1019
|
-
|
1020
|
-
if (NIL_P(v))
|
1021
|
-
return v;
|
1022
|
-
else if (RB_TYPE_P(v, T_ARRAY)) {
|
1031
|
+
if (RB_TYPE_P(v, T_ARRAY)) {
|
1023
1032
|
str = rb_str_new(0, 0);
|
1024
1033
|
for (i = 0; i < RARRAY_LEN(v); i++) {
|
1025
1034
|
elem = rb_ary_entry(v, i);
|
@@ -1033,14 +1042,113 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
|
1033
1042
|
StringValue(str);
|
1034
1043
|
}
|
1035
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
|
+
|
1036
1070
|
GetSSLCTX(self, ctx);
|
1037
|
-
if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
|
1071
|
+
if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
|
1038
1072
|
ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
|
1039
|
-
}
|
1040
1073
|
|
1041
1074
|
return v;
|
1042
1075
|
}
|
1043
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
|
+
|
1044
1152
|
#if !defined(OPENSSL_NO_EC)
|
1045
1153
|
/*
|
1046
1154
|
* call-seq:
|
@@ -1052,9 +1160,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
|
1052
1160
|
* Extension. For a server, the list is used by OpenSSL to determine the set of
|
1053
1161
|
* shared curves. OpenSSL will pick the most appropriate one from it.
|
1054
1162
|
*
|
1055
|
-
* Note that this works differently with old OpenSSL (<= 1.0.1). Only one curve
|
1056
|
-
* can be set, and this has no effect for TLS clients.
|
1057
|
-
*
|
1058
1163
|
* === Example
|
1059
1164
|
* ctx1 = OpenSSL::SSL::SSLContext.new
|
1060
1165
|
* ctx1.ecdh_curves = "X25519:P-256:P-224"
|
@@ -1078,48 +1183,8 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
|
|
1078
1183
|
GetSSLCTX(self, ctx);
|
1079
1184
|
StringValueCStr(arg);
|
1080
1185
|
|
1081
|
-
#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
|
1082
1186
|
if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
|
1083
1187
|
ossl_raise(eSSLError, NULL);
|
1084
|
-
#else
|
1085
|
-
/* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to
|
1086
|
-
* SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */
|
1087
|
-
{
|
1088
|
-
VALUE curve, splitted;
|
1089
|
-
EC_KEY *ec;
|
1090
|
-
int nid;
|
1091
|
-
|
1092
|
-
splitted = rb_str_split(arg, ":");
|
1093
|
-
if (!RARRAY_LEN(splitted))
|
1094
|
-
ossl_raise(eSSLError, "invalid input format");
|
1095
|
-
curve = RARRAY_AREF(splitted, 0);
|
1096
|
-
StringValueCStr(curve);
|
1097
|
-
|
1098
|
-
/* SSL_CTX_set1_curves_list() accepts NIST names */
|
1099
|
-
nid = EC_curve_nist2nid(RSTRING_PTR(curve));
|
1100
|
-
if (nid == NID_undef)
|
1101
|
-
nid = OBJ_txt2nid(RSTRING_PTR(curve));
|
1102
|
-
if (nid == NID_undef)
|
1103
|
-
ossl_raise(eSSLError, "unknown curve name");
|
1104
|
-
|
1105
|
-
ec = EC_KEY_new_by_curve_name(nid);
|
1106
|
-
if (!ec)
|
1107
|
-
ossl_raise(eSSLError, NULL);
|
1108
|
-
EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
|
1109
|
-
if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
|
1110
|
-
EC_KEY_free(ec);
|
1111
|
-
ossl_raise(eSSLError, "SSL_CTX_set_tmp_ecdh");
|
1112
|
-
}
|
1113
|
-
EC_KEY_free(ec);
|
1114
|
-
# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
|
1115
|
-
/* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto
|
1116
|
-
* is enabled. So disable ecdh_auto. */
|
1117
|
-
if (!SSL_CTX_set_ecdh_auto(ctx, 0))
|
1118
|
-
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
1119
|
-
# endif
|
1120
|
-
}
|
1121
|
-
#endif
|
1122
|
-
|
1123
1188
|
return arg;
|
1124
1189
|
}
|
1125
1190
|
#else
|
@@ -1210,7 +1275,7 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
|
|
1210
1275
|
|
1211
1276
|
/*
|
1212
1277
|
* call-seq:
|
1213
|
-
* ctx.add_certificate(
|
1278
|
+
* ctx.add_certificate(certificate, pkey [, extra_certs]) -> self
|
1214
1279
|
*
|
1215
1280
|
* Adds a certificate to the context. _pkey_ must be a corresponding private
|
1216
1281
|
* key with _certificate_.
|
@@ -1242,10 +1307,6 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
|
|
1242
1307
|
* ecdsa_pkey = ...
|
1243
1308
|
* another_ca_cert = ...
|
1244
1309
|
* ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])
|
1245
|
-
*
|
1246
|
-
* === Note
|
1247
|
-
* OpenSSL before the version 1.0.2 could handle only one extra chain across
|
1248
|
-
* all key types. Calling this method discards the chain set previously.
|
1249
1310
|
*/
|
1250
1311
|
static VALUE
|
1251
1312
|
ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
@@ -1270,7 +1331,7 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
|
1270
1331
|
EVP_PKEY_free(pub_pkey);
|
1271
1332
|
if (!pub_pkey)
|
1272
1333
|
rb_raise(rb_eArgError, "certificate does not contain public key");
|
1273
|
-
if (
|
1334
|
+
if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
|
1274
1335
|
rb_raise(rb_eArgError, "public key mismatch");
|
1275
1336
|
|
1276
1337
|
if (argc >= 3)
|
@@ -1284,34 +1345,9 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
|
1284
1345
|
sk_X509_pop_free(extra_chain, X509_free);
|
1285
1346
|
ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
|
1286
1347
|
}
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
|
1291
|
-
sk_X509_pop_free(extra_chain, X509_free);
|
1292
|
-
ossl_raise(eSSLError, "SSL_CTX_set0_chain");
|
1293
|
-
}
|
1294
|
-
#else
|
1295
|
-
STACK_OF(X509) *orig_extra_chain;
|
1296
|
-
X509 *x509_tmp;
|
1297
|
-
|
1298
|
-
/* First, clear the existing chain */
|
1299
|
-
SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
|
1300
|
-
if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
|
1301
|
-
rb_warning("SSL_CTX_set0_chain() is not available; " \
|
1302
|
-
"clearing previously set certificate chain");
|
1303
|
-
SSL_CTX_clear_extra_chain_certs(ctx);
|
1304
|
-
}
|
1305
|
-
while ((x509_tmp = sk_X509_shift(extra_chain))) {
|
1306
|
-
/* Transfers ownership */
|
1307
|
-
if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
|
1308
|
-
X509_free(x509_tmp);
|
1309
|
-
sk_X509_pop_free(extra_chain, X509_free);
|
1310
|
-
ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert");
|
1311
|
-
}
|
1312
|
-
}
|
1313
|
-
sk_X509_free(extra_chain);
|
1314
|
-
#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");
|
1315
1351
|
}
|
1316
1352
|
return self;
|
1317
1353
|
}
|
@@ -1505,12 +1541,23 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
|
|
1505
1541
|
/*
|
1506
1542
|
* SSLSocket class
|
1507
1543
|
*/
|
1508
|
-
#ifndef OPENSSL_NO_SOCK
|
1509
1544
|
static inline int
|
1510
1545
|
ssl_started(SSL *ssl)
|
1511
1546
|
{
|
1512
|
-
/*
|
1513
|
-
return
|
1547
|
+
/* BIO is created through ossl_ssl_setup(), called by #connect or #accept */
|
1548
|
+
return SSL_get_rbio(ssl) != NULL;
|
1549
|
+
}
|
1550
|
+
|
1551
|
+
static void
|
1552
|
+
ossl_ssl_mark(void *ptr)
|
1553
|
+
{
|
1554
|
+
SSL *ssl = ptr;
|
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.
|
1560
|
+
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
|
1514
1561
|
}
|
1515
1562
|
|
1516
1563
|
static void
|
@@ -1522,9 +1569,9 @@ ossl_ssl_free(void *ssl)
|
|
1522
1569
|
const rb_data_type_t ossl_ssl_type = {
|
1523
1570
|
"OpenSSL/SSL",
|
1524
1571
|
{
|
1525
|
-
|
1572
|
+
ossl_ssl_mark, ossl_ssl_free,
|
1526
1573
|
},
|
1527
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
1574
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
1528
1575
|
};
|
1529
1576
|
|
1530
1577
|
static VALUE
|
@@ -1533,6 +1580,29 @@ ossl_ssl_s_alloc(VALUE klass)
|
|
1533
1580
|
return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
|
1534
1581
|
}
|
1535
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
|
+
|
1536
1606
|
/*
|
1537
1607
|
* call-seq:
|
1538
1608
|
* SSLSocket.new(io) => aSSLSocket
|
@@ -1569,6 +1639,7 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
|
1569
1639
|
|
1570
1640
|
if (rb_respond_to(io, rb_intern("nonblock=")))
|
1571
1641
|
rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
|
1642
|
+
Check_Type(io, T_FILE);
|
1572
1643
|
rb_ivar_set(self, id_i_io, io);
|
1573
1644
|
|
1574
1645
|
ssl = SSL_new(ctx);
|
@@ -1579,6 +1650,8 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
|
1579
1650
|
SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
|
1580
1651
|
SSL_set_info_callback(ssl, ssl_info_cb);
|
1581
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.
|
1582
1655
|
SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
|
1583
1656
|
|
1584
1657
|
rb_call_super(0, NULL);
|
@@ -1586,6 +1659,17 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
|
1586
1659
|
return self;
|
1587
1660
|
}
|
1588
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
|
+
|
1589
1673
|
static VALUE
|
1590
1674
|
ossl_ssl_setup(VALUE self)
|
1591
1675
|
{
|
@@ -1601,8 +1685,8 @@ ossl_ssl_setup(VALUE self)
|
|
1601
1685
|
GetOpenFile(io, fptr);
|
1602
1686
|
rb_io_check_readable(fptr);
|
1603
1687
|
rb_io_check_writable(fptr);
|
1604
|
-
if (!SSL_set_fd(ssl, TO_SOCKET(
|
1605
|
-
|
1688
|
+
if (!SSL_set_fd(ssl, TO_SOCKET(rb_io_descriptor(io))))
|
1689
|
+
ossl_raise(eSSLError, "SSL_set_fd");
|
1606
1690
|
|
1607
1691
|
return Qtrue;
|
1608
1692
|
}
|
@@ -1636,70 +1720,107 @@ no_exception_p(VALUE opts)
|
|
1636
1720
|
return 0;
|
1637
1721
|
}
|
1638
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
|
+
|
1639
1752
|
static VALUE
|
1640
|
-
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)
|
1641
1754
|
{
|
1642
1755
|
SSL *ssl;
|
1643
|
-
rb_io_t *fptr;
|
1644
1756
|
int ret, ret2;
|
1645
1757
|
VALUE cb_state;
|
1646
1758
|
int nonblock = opts != Qfalse;
|
1647
|
-
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
1648
|
-
unsigned long err;
|
1649
|
-
#endif
|
1650
1759
|
|
1651
1760
|
rb_ivar_set(self, ID_callback_state, Qnil);
|
1652
1761
|
|
1653
1762
|
GetSSL(self, ssl);
|
1654
1763
|
|
1655
|
-
|
1656
|
-
for(;;){
|
1657
|
-
|
1764
|
+
VALUE io = rb_attr_get(self, id_i_io);
|
1765
|
+
for (;;) {
|
1766
|
+
ret = func(ssl);
|
1658
1767
|
|
1659
|
-
|
1768
|
+
cb_state = rb_attr_get(self, ID_callback_state);
|
1660
1769
|
if (!NIL_P(cb_state)) {
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1770
|
+
/* must cleanup OpenSSL error stack before re-raising */
|
1771
|
+
ossl_clear_error();
|
1772
|
+
rb_jump_tag(NUM2INT(cb_state));
|
1773
|
+
}
|
1665
1774
|
|
1666
|
-
|
1667
|
-
|
1775
|
+
if (ret > 0)
|
1776
|
+
break;
|
1668
1777
|
|
1669
|
-
|
1670
|
-
|
1778
|
+
switch ((ret2 = ssl_get_error(ssl, ret))) {
|
1779
|
+
case SSL_ERROR_WANT_WRITE:
|
1671
1780
|
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1672
1781
|
write_would_block(nonblock);
|
1673
|
-
|
1782
|
+
io_wait_writable(io);
|
1674
1783
|
continue;
|
1675
|
-
|
1784
|
+
case SSL_ERROR_WANT_READ:
|
1676
1785
|
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1677
1786
|
read_would_block(nonblock);
|
1678
|
-
|
1787
|
+
io_wait_readable(io);
|
1679
1788
|
continue;
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1789
|
+
case SSL_ERROR_SYSCALL:
|
1790
|
+
#ifdef __APPLE__
|
1791
|
+
/* See ossl_ssl_write_internal() */
|
1792
|
+
if (errno == EPROTOTYPE)
|
1793
|
+
continue;
|
1794
|
+
#endif
|
1795
|
+
if (errno) rb_sys_fail(funcname);
|
1796
|
+
/* fallthrough */
|
1797
|
+
default: {
|
1798
|
+
VALUE error_append = Qnil;
|
1683
1799
|
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
funcname, ret2, errno, SSL_state_string_long(ssl),
|
1697
|
-
err_msg, verify_msg);
|
1698
|
-
}
|
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
|
+
}
|
1699
1812
|
#endif
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
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
|
+
}
|
1703
1824
|
}
|
1704
1825
|
|
1705
1826
|
return self;
|
@@ -1709,8 +1830,7 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|
1709
1830
|
* call-seq:
|
1710
1831
|
* ssl.connect => self
|
1711
1832
|
*
|
1712
|
-
* Initiates an SSL/TLS handshake with a server.
|
1713
|
-
* after unencrypted data has been sent over the socket.
|
1833
|
+
* Initiates an SSL/TLS handshake with a server.
|
1714
1834
|
*/
|
1715
1835
|
static VALUE
|
1716
1836
|
ossl_ssl_connect(VALUE self)
|
@@ -1757,8 +1877,7 @@ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
|
|
1757
1877
|
* call-seq:
|
1758
1878
|
* ssl.accept => self
|
1759
1879
|
*
|
1760
|
-
* Waits for a SSL/TLS client to initiate a handshake.
|
1761
|
-
* started after unencrypted data has been sent over the socket.
|
1880
|
+
* Waits for a SSL/TLS client to initiate a handshake.
|
1762
1881
|
*/
|
1763
1882
|
static VALUE
|
1764
1883
|
ossl_ssl_accept(VALUE self)
|
@@ -1805,16 +1924,18 @@ static VALUE
|
|
1805
1924
|
ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
1806
1925
|
{
|
1807
1926
|
SSL *ssl;
|
1808
|
-
int ilen
|
1927
|
+
int ilen;
|
1809
1928
|
VALUE len, str;
|
1810
|
-
|
1811
|
-
VALUE io, opts = Qnil;
|
1929
|
+
VALUE opts = Qnil;
|
1812
1930
|
|
1813
1931
|
if (nonblock) {
|
1814
1932
|
rb_scan_args(argc, argv, "11:", &len, &str, &opts);
|
1815
1933
|
} else {
|
1816
1934
|
rb_scan_args(argc, argv, "11", &len, &str);
|
1817
1935
|
}
|
1936
|
+
GetSSL(self, ssl);
|
1937
|
+
if (!ssl_started(ssl))
|
1938
|
+
rb_raise(eSSLError, "SSL session is not started yet");
|
1818
1939
|
|
1819
1940
|
ilen = NUM2INT(len);
|
1820
1941
|
if (NIL_P(str))
|
@@ -1826,67 +1947,63 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1826
1947
|
else
|
1827
1948
|
rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
|
1828
1949
|
}
|
1829
|
-
OBJ_TAINT(str);
|
1830
1950
|
rb_str_set_len(str, 0);
|
1831
1951
|
if (ilen == 0)
|
1832
1952
|
return str;
|
1833
1953
|
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
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) {
|
1970
|
+
rb_str_unlocktmp(str);
|
1971
|
+
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1848
1972
|
write_would_block(nonblock);
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1973
|
+
}
|
1974
|
+
io_wait_writable(io);
|
1975
|
+
continue;
|
1976
|
+
case SSL_ERROR_WANT_READ:
|
1977
|
+
if (nonblock) {
|
1978
|
+
rb_str_unlocktmp(str);
|
1979
|
+
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1853
1980
|
read_would_block(nonblock);
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1981
|
+
}
|
1982
|
+
io_wait_readable(io);
|
1983
|
+
continue;
|
1984
|
+
case SSL_ERROR_SYSCALL:
|
1985
|
+
if (!ERR_peek_error()) {
|
1986
|
+
rb_str_unlocktmp(str);
|
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");
|
1875
2005
|
}
|
1876
2006
|
}
|
1877
|
-
else {
|
1878
|
-
ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
|
1879
|
-
|
1880
|
-
rb_warning("SSL session is not started yet.");
|
1881
|
-
if (nonblock)
|
1882
|
-
return rb_funcall(io, meth, 3, len, str, opts);
|
1883
|
-
else
|
1884
|
-
return rb_funcall(io, meth, 2, len, str);
|
1885
|
-
}
|
1886
|
-
|
1887
|
-
end:
|
1888
|
-
rb_str_set_len(str, nread);
|
1889
|
-
return str;
|
1890
2007
|
}
|
1891
2008
|
|
1892
2009
|
/*
|
@@ -1926,57 +2043,55 @@ static VALUE
|
|
1926
2043
|
ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
1927
2044
|
{
|
1928
2045
|
SSL *ssl;
|
1929
|
-
int nwrite = 0;
|
1930
2046
|
rb_io_t *fptr;
|
1931
|
-
int nonblock = opts != Qfalse;
|
1932
|
-
VALUE
|
2047
|
+
int num, nonblock = opts != Qfalse;
|
2048
|
+
VALUE tmp;
|
1933
2049
|
|
1934
|
-
StringValue(str);
|
1935
2050
|
GetSSL(self, ssl);
|
1936
|
-
|
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);
|
1937
2056
|
GetOpenFile(io, fptr);
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
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:
|
2079
|
+
#ifdef __APPLE__
|
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)
|
1959
2087
|
continue;
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
2088
|
+
#endif
|
2089
|
+
if (errno) rb_sys_fail(0);
|
2090
|
+
/* fallthrough */
|
2091
|
+
default:
|
2092
|
+
ossl_raise(eSSLError, "SSL_write");
|
1965
2093
|
}
|
1966
2094
|
}
|
1967
|
-
else {
|
1968
|
-
ID meth = nonblock ?
|
1969
|
-
rb_intern("write_nonblock") : rb_intern("syswrite");
|
1970
|
-
|
1971
|
-
rb_warning("SSL session is not started yet.");
|
1972
|
-
if (nonblock)
|
1973
|
-
return rb_funcall(io, meth, 2, str, opts);
|
1974
|
-
else
|
1975
|
-
return rb_funcall(io, meth, 1, str);
|
1976
|
-
}
|
1977
|
-
|
1978
|
-
end:
|
1979
|
-
return INT2NUM(nwrite);
|
1980
2095
|
}
|
1981
2096
|
|
1982
2097
|
/*
|
@@ -2275,7 +2390,57 @@ ossl_ssl_get_verify_result(VALUE self)
|
|
2275
2390
|
|
2276
2391
|
GetSSL(self, ssl);
|
2277
2392
|
|
2278
|
-
return
|
2393
|
+
return LONG2NUM(SSL_get_verify_result(ssl));
|
2394
|
+
}
|
2395
|
+
|
2396
|
+
/*
|
2397
|
+
* call-seq:
|
2398
|
+
* ssl.finished_message => "finished message"
|
2399
|
+
*
|
2400
|
+
* Returns the last *Finished* message sent
|
2401
|
+
*
|
2402
|
+
*/
|
2403
|
+
static VALUE
|
2404
|
+
ossl_ssl_get_finished(VALUE self)
|
2405
|
+
{
|
2406
|
+
SSL *ssl;
|
2407
|
+
char sizer[1], *buf;
|
2408
|
+
size_t len;
|
2409
|
+
|
2410
|
+
GetSSL(self, ssl);
|
2411
|
+
|
2412
|
+
len = SSL_get_finished(ssl, sizer, 0);
|
2413
|
+
if (len == 0)
|
2414
|
+
return Qnil;
|
2415
|
+
|
2416
|
+
buf = ALLOCA_N(char, len);
|
2417
|
+
SSL_get_finished(ssl, buf, len);
|
2418
|
+
return rb_str_new(buf, len);
|
2419
|
+
}
|
2420
|
+
|
2421
|
+
/*
|
2422
|
+
* call-seq:
|
2423
|
+
* ssl.peer_finished_message => "peer finished message"
|
2424
|
+
*
|
2425
|
+
* Returns the last *Finished* message received
|
2426
|
+
*
|
2427
|
+
*/
|
2428
|
+
static VALUE
|
2429
|
+
ossl_ssl_get_peer_finished(VALUE self)
|
2430
|
+
{
|
2431
|
+
SSL *ssl;
|
2432
|
+
char sizer[1], *buf;
|
2433
|
+
size_t len;
|
2434
|
+
|
2435
|
+
GetSSL(self, ssl);
|
2436
|
+
|
2437
|
+
len = SSL_get_peer_finished(ssl, sizer, 0);
|
2438
|
+
if (len == 0)
|
2439
|
+
return Qnil;
|
2440
|
+
|
2441
|
+
buf = ALLOCA_N(char, len);
|
2442
|
+
SSL_get_peer_finished(ssl, buf, len);
|
2443
|
+
return rb_str_new(buf, len);
|
2279
2444
|
}
|
2280
2445
|
|
2281
2446
|
/*
|
@@ -2301,7 +2466,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
|
|
2301
2466
|
return ossl_x509name_sk2ary(ca);
|
2302
2467
|
}
|
2303
2468
|
|
2304
|
-
#
|
2469
|
+
# ifdef OSSL_USE_NEXTPROTONEG
|
2305
2470
|
/*
|
2306
2471
|
* call-seq:
|
2307
2472
|
* ssl.npn_protocol => String | nil
|
@@ -2326,7 +2491,6 @@ ossl_ssl_npn_protocol(VALUE self)
|
|
2326
2491
|
}
|
2327
2492
|
# endif
|
2328
2493
|
|
2329
|
-
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2330
2494
|
/*
|
2331
2495
|
* call-seq:
|
2332
2496
|
* ssl.alpn_protocol => String | nil
|
@@ -2349,9 +2513,50 @@ ossl_ssl_alpn_protocol(VALUE self)
|
|
2349
2513
|
else
|
2350
2514
|
return rb_str_new((const char *) out, outlen);
|
2351
2515
|
}
|
2352
|
-
# endif
|
2353
2516
|
|
2354
|
-
|
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
|
+
|
2355
2560
|
/*
|
2356
2561
|
* call-seq:
|
2357
2562
|
* ssl.tmp_key => PKey or nil
|
@@ -2369,11 +2574,8 @@ ossl_ssl_tmp_key(VALUE self)
|
|
2369
2574
|
return Qnil;
|
2370
2575
|
return ossl_pkey_new(key);
|
2371
2576
|
}
|
2372
|
-
# endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */
|
2373
2577
|
#endif /* !defined(OPENSSL_NO_SOCK) */
|
2374
2578
|
|
2375
|
-
#undef rb_intern
|
2376
|
-
#define rb_intern(s) rb_intern_const(s)
|
2377
2579
|
void
|
2378
2580
|
Init_ossl_ssl(void)
|
2379
2581
|
{
|
@@ -2384,8 +2586,9 @@ Init_ossl_ssl(void)
|
|
2384
2586
|
rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
|
2385
2587
|
#endif
|
2386
2588
|
|
2387
|
-
|
2388
|
-
|
2589
|
+
#ifndef OPENSSL_NO_SOCK
|
2590
|
+
id_call = rb_intern_const("call");
|
2591
|
+
ID_callback_state = rb_intern_const("callback_state");
|
2389
2592
|
|
2390
2593
|
ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0);
|
2391
2594
|
if (ossl_ssl_ex_vcb_idx < 0)
|
@@ -2396,11 +2599,6 @@ Init_ossl_ssl(void)
|
|
2396
2599
|
ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
|
2397
2600
|
if (ossl_sslctx_ex_ptr_idx < 0)
|
2398
2601
|
ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
|
2399
|
-
#if !defined(HAVE_X509_STORE_UP_REF)
|
2400
|
-
ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_store_p", 0, 0, 0);
|
2401
|
-
if (ossl_sslctx_ex_store_p < 0)
|
2402
|
-
ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
|
2403
|
-
#endif
|
2404
2602
|
|
2405
2603
|
/* Document-module: OpenSSL::SSL
|
2406
2604
|
*
|
@@ -2411,16 +2609,6 @@ Init_ossl_ssl(void)
|
|
2411
2609
|
*/
|
2412
2610
|
mSSL = rb_define_module_under(mOSSL, "SSL");
|
2413
2611
|
|
2414
|
-
/* Document-module: OpenSSL::ExtConfig
|
2415
|
-
*
|
2416
|
-
* This module contains configuration information about the SSL extension,
|
2417
|
-
* for example if socket support is enabled, or the host name TLS extension
|
2418
|
-
* is enabled. Constants in this module will always be defined, but contain
|
2419
|
-
* +true+ or +false+ values depending on the configuration of your OpenSSL
|
2420
|
-
* installation.
|
2421
|
-
*/
|
2422
|
-
mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig");
|
2423
|
-
|
2424
2612
|
/* Document-class: OpenSSL::SSL::SSLError
|
2425
2613
|
*
|
2426
2614
|
* Generic error class raised by SSLSocket and SSLContext.
|
@@ -2452,7 +2640,7 @@ Init_ossl_ssl(void)
|
|
2452
2640
|
* The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
|
2453
2641
|
* It is recommended to use #add_certificate instead.
|
2454
2642
|
*/
|
2455
|
-
rb_attr(cSSLContext,
|
2643
|
+
rb_attr(cSSLContext, rb_intern_const("cert"), 1, 1, Qfalse);
|
2456
2644
|
|
2457
2645
|
/*
|
2458
2646
|
* Context private key
|
@@ -2460,29 +2648,29 @@ Init_ossl_ssl(void)
|
|
2460
2648
|
* The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
|
2461
2649
|
* It is recommended to use #add_certificate instead.
|
2462
2650
|
*/
|
2463
|
-
rb_attr(cSSLContext,
|
2651
|
+
rb_attr(cSSLContext, rb_intern_const("key"), 1, 1, Qfalse);
|
2464
2652
|
|
2465
2653
|
/*
|
2466
2654
|
* A certificate or Array of certificates that will be sent to the client.
|
2467
2655
|
*/
|
2468
|
-
rb_attr(cSSLContext,
|
2656
|
+
rb_attr(cSSLContext, rb_intern_const("client_ca"), 1, 1, Qfalse);
|
2469
2657
|
|
2470
2658
|
/*
|
2471
2659
|
* The path to a file containing a PEM-format CA certificate
|
2472
2660
|
*/
|
2473
|
-
rb_attr(cSSLContext,
|
2661
|
+
rb_attr(cSSLContext, rb_intern_const("ca_file"), 1, 1, Qfalse);
|
2474
2662
|
|
2475
2663
|
/*
|
2476
2664
|
* The path to a directory containing CA certificates in PEM format.
|
2477
2665
|
*
|
2478
2666
|
* Files are looked up by subject's X509 name's hash value.
|
2479
2667
|
*/
|
2480
|
-
rb_attr(cSSLContext,
|
2668
|
+
rb_attr(cSSLContext, rb_intern_const("ca_path"), 1, 1, Qfalse);
|
2481
2669
|
|
2482
2670
|
/*
|
2483
2671
|
* Maximum session lifetime in seconds.
|
2484
2672
|
*/
|
2485
|
-
rb_attr(cSSLContext,
|
2673
|
+
rb_attr(cSSLContext, rb_intern_const("timeout"), 1, 1, Qfalse);
|
2486
2674
|
|
2487
2675
|
/*
|
2488
2676
|
* Session verification mode.
|
@@ -2495,12 +2683,12 @@ Init_ossl_ssl(void)
|
|
2495
2683
|
*
|
2496
2684
|
* See SSL_CTX_set_verify(3) for details.
|
2497
2685
|
*/
|
2498
|
-
rb_attr(cSSLContext,
|
2686
|
+
rb_attr(cSSLContext, rb_intern_const("verify_mode"), 1, 1, Qfalse);
|
2499
2687
|
|
2500
2688
|
/*
|
2501
2689
|
* Number of CA certificates to walk when verifying a certificate chain.
|
2502
2690
|
*/
|
2503
|
-
rb_attr(cSSLContext,
|
2691
|
+
rb_attr(cSSLContext, rb_intern_const("verify_depth"), 1, 1, Qfalse);
|
2504
2692
|
|
2505
2693
|
/*
|
2506
2694
|
* A callback for additional certificate verification. The callback is
|
@@ -2514,7 +2702,7 @@ Init_ossl_ssl(void)
|
|
2514
2702
|
* If the callback returns +false+, the chain verification is immediately
|
2515
2703
|
* stopped and a bad_certificate alert is then sent.
|
2516
2704
|
*/
|
2517
|
-
rb_attr(cSSLContext,
|
2705
|
+
rb_attr(cSSLContext, rb_intern_const("verify_callback"), 1, 1, Qfalse);
|
2518
2706
|
|
2519
2707
|
/*
|
2520
2708
|
* Whether to check the server certificate is valid for the hostname.
|
@@ -2522,12 +2710,12 @@ Init_ossl_ssl(void)
|
|
2522
2710
|
* In order to make this work, verify_mode must be set to VERIFY_PEER and
|
2523
2711
|
* the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=.
|
2524
2712
|
*/
|
2525
|
-
rb_attr(cSSLContext,
|
2713
|
+
rb_attr(cSSLContext, rb_intern_const("verify_hostname"), 1, 1, Qfalse);
|
2526
2714
|
|
2527
2715
|
/*
|
2528
2716
|
* An OpenSSL::X509::Store used for certificate verification.
|
2529
2717
|
*/
|
2530
|
-
rb_attr(cSSLContext,
|
2718
|
+
rb_attr(cSSLContext, rb_intern_const("cert_store"), 1, 1, Qfalse);
|
2531
2719
|
|
2532
2720
|
/*
|
2533
2721
|
* An Array of extra X509 certificates to be added to the certificate
|
@@ -2536,7 +2724,7 @@ Init_ossl_ssl(void)
|
|
2536
2724
|
* The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
|
2537
2725
|
* It is recommended to use #add_certificate instead.
|
2538
2726
|
*/
|
2539
|
-
rb_attr(cSSLContext,
|
2727
|
+
rb_attr(cSSLContext, rb_intern_const("extra_chain_cert"), 1, 1, Qfalse);
|
2540
2728
|
|
2541
2729
|
/*
|
2542
2730
|
* A callback invoked when a client certificate is requested by a server
|
@@ -2546,28 +2734,14 @@ Init_ossl_ssl(void)
|
|
2546
2734
|
* containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any
|
2547
2735
|
* other value is returned the handshake is suspended.
|
2548
2736
|
*/
|
2549
|
-
rb_attr(cSSLContext,
|
2550
|
-
|
2551
|
-
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
2552
|
-
/*
|
2553
|
-
* A callback invoked when ECDH parameters are required.
|
2554
|
-
*
|
2555
|
-
* The callback is invoked with the Session for the key exchange, an
|
2556
|
-
* flag indicating the use of an export cipher and the keylength
|
2557
|
-
* required.
|
2558
|
-
*
|
2559
|
-
* The callback is deprecated. This does not work with recent versions of
|
2560
|
-
* OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead.
|
2561
|
-
*/
|
2562
|
-
rb_attr(cSSLContext, rb_intern("tmp_ecdh_callback"), 1, 1, Qfalse);
|
2563
|
-
#endif
|
2737
|
+
rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
|
2564
2738
|
|
2565
2739
|
/*
|
2566
2740
|
* Sets the context in which a session can be reused. This allows
|
2567
2741
|
* sessions for multiple applications to be distinguished, for example, by
|
2568
2742
|
* name.
|
2569
2743
|
*/
|
2570
|
-
rb_attr(cSSLContext,
|
2744
|
+
rb_attr(cSSLContext, rb_intern_const("session_id_context"), 1, 1, Qfalse);
|
2571
2745
|
|
2572
2746
|
/*
|
2573
2747
|
* A callback invoked on a server when a session is proposed by the client
|
@@ -2576,7 +2750,7 @@ Init_ossl_ssl(void)
|
|
2576
2750
|
* The callback is invoked with the SSLSocket and session id. The
|
2577
2751
|
* callback may return a Session from an external cache.
|
2578
2752
|
*/
|
2579
|
-
rb_attr(cSSLContext,
|
2753
|
+
rb_attr(cSSLContext, rb_intern_const("session_get_cb"), 1, 1, Qfalse);
|
2580
2754
|
|
2581
2755
|
/*
|
2582
2756
|
* A callback invoked when a new session was negotiated.
|
@@ -2584,7 +2758,7 @@ Init_ossl_ssl(void)
|
|
2584
2758
|
* The callback is invoked with an SSLSocket. If +false+ is returned the
|
2585
2759
|
* session will be removed from the internal cache.
|
2586
2760
|
*/
|
2587
|
-
rb_attr(cSSLContext,
|
2761
|
+
rb_attr(cSSLContext, rb_intern_const("session_new_cb"), 1, 1, Qfalse);
|
2588
2762
|
|
2589
2763
|
/*
|
2590
2764
|
* A callback invoked when a session is removed from the internal cache.
|
@@ -2595,18 +2769,16 @@ Init_ossl_ssl(void)
|
|
2595
2769
|
* multi-threaded application. The callback is called inside a global lock
|
2596
2770
|
* and it can randomly cause deadlock on Ruby thread switching.
|
2597
2771
|
*/
|
2598
|
-
rb_attr(cSSLContext,
|
2599
|
-
|
2600
|
-
rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
|
2772
|
+
rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
|
2601
2773
|
|
2602
2774
|
/*
|
2603
|
-
* A callback invoked whenever a new handshake is initiated
|
2604
|
-
* to disable renegotiation entirely.
|
2775
|
+
* A callback invoked whenever a new handshake is initiated on an
|
2776
|
+
* established connection. May be used to disable renegotiation entirely.
|
2605
2777
|
*
|
2606
2778
|
* The callback is invoked with the active SSLSocket. The callback's
|
2607
|
-
* return value is
|
2779
|
+
* return value is ignored. A normal return indicates "approval" of the
|
2608
2780
|
* renegotiation and will continue the process. To forbid renegotiation
|
2609
|
-
* and to cancel the process, an
|
2781
|
+
* and to cancel the process, raise an exception within the callback.
|
2610
2782
|
*
|
2611
2783
|
* === Disable client renegotiation
|
2612
2784
|
*
|
@@ -2614,14 +2786,12 @@ Init_ossl_ssl(void)
|
|
2614
2786
|
* renegotiation entirely. You may use a callback as follows to implement
|
2615
2787
|
* this feature:
|
2616
2788
|
*
|
2617
|
-
* num_handshakes = 0
|
2618
2789
|
* ctx.renegotiation_cb = lambda do |ssl|
|
2619
|
-
*
|
2620
|
-
* raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
|
2790
|
+
* raise RuntimeError, "Client renegotiation disabled"
|
2621
2791
|
* end
|
2622
2792
|
*/
|
2623
|
-
rb_attr(cSSLContext,
|
2624
|
-
#
|
2793
|
+
rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
|
2794
|
+
#ifdef OSSL_USE_NEXTPROTONEG
|
2625
2795
|
/*
|
2626
2796
|
* An Enumerable of Strings. Each String represents a protocol to be
|
2627
2797
|
* advertised as the list of supported protocols for Next Protocol
|
@@ -2633,7 +2803,7 @@ Init_ossl_ssl(void)
|
|
2633
2803
|
*
|
2634
2804
|
* ctx.npn_protocols = ["http/1.1", "spdy/2"]
|
2635
2805
|
*/
|
2636
|
-
rb_attr(cSSLContext,
|
2806
|
+
rb_attr(cSSLContext, rb_intern_const("npn_protocols"), 1, 1, Qfalse);
|
2637
2807
|
/*
|
2638
2808
|
* A callback invoked on the client side when the client needs to select
|
2639
2809
|
* a protocol from the list sent by the server. Supported in OpenSSL 1.0.1
|
@@ -2650,10 +2820,9 @@ Init_ossl_ssl(void)
|
|
2650
2820
|
* protocols.first
|
2651
2821
|
* end
|
2652
2822
|
*/
|
2653
|
-
rb_attr(cSSLContext,
|
2823
|
+
rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse);
|
2654
2824
|
#endif
|
2655
2825
|
|
2656
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2657
2826
|
/*
|
2658
2827
|
* An Enumerable of Strings. Each String represents a protocol to be
|
2659
2828
|
* advertised as the list of supported protocols for Application-Layer
|
@@ -2665,7 +2834,7 @@ Init_ossl_ssl(void)
|
|
2665
2834
|
*
|
2666
2835
|
* ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"]
|
2667
2836
|
*/
|
2668
|
-
rb_attr(cSSLContext,
|
2837
|
+
rb_attr(cSSLContext, rb_intern_const("alpn_protocols"), 1, 1, Qfalse);
|
2669
2838
|
/*
|
2670
2839
|
* A callback invoked on the server side when the server needs to select
|
2671
2840
|
* a protocol from the list sent by the client. Supported in OpenSSL 1.0.2
|
@@ -2682,8 +2851,30 @@ Init_ossl_ssl(void)
|
|
2682
2851
|
* protocols.first
|
2683
2852
|
* end
|
2684
2853
|
*/
|
2685
|
-
rb_attr(cSSLContext,
|
2686
|
-
|
2854
|
+
rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
|
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);
|
2687
2878
|
|
2688
2879
|
rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
|
2689
2880
|
rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
|
@@ -2691,6 +2882,12 @@ Init_ossl_ssl(void)
|
|
2691
2882
|
ossl_sslctx_set_minmax_proto_version, 2);
|
2692
2883
|
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
|
2693
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
|
2694
2891
|
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
|
2695
2892
|
rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
|
2696
2893
|
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
|
@@ -2764,11 +2961,6 @@ Init_ossl_ssl(void)
|
|
2764
2961
|
* Document-class: OpenSSL::SSL::SSLSocket
|
2765
2962
|
*/
|
2766
2963
|
cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
|
2767
|
-
#ifdef OPENSSL_NO_SOCK
|
2768
|
-
rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue);
|
2769
|
-
rb_define_method(cSSLSocket, "initialize", rb_f_notimplement, -1);
|
2770
|
-
#else
|
2771
|
-
rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse);
|
2772
2964
|
rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
|
2773
2965
|
rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
|
2774
2966
|
rb_undef_method(cSSLSocket, "initialize_copy");
|
@@ -2795,16 +2987,14 @@ Init_ossl_ssl(void)
|
|
2795
2987
|
rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
|
2796
2988
|
/* #hostname is defined in lib/openssl/ssl.rb */
|
2797
2989
|
rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
|
2798
|
-
|
2990
|
+
rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0);
|
2991
|
+
rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
|
2799
2992
|
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
|
2800
|
-
# endif
|
2801
|
-
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2802
2993
|
rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
|
2803
|
-
|
2804
|
-
#
|
2994
|
+
rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1);
|
2995
|
+
# ifdef OSSL_USE_NEXTPROTONEG
|
2805
2996
|
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
|
2806
2997
|
# endif
|
2807
|
-
#endif
|
2808
2998
|
|
2809
2999
|
rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
|
2810
3000
|
rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
|
@@ -2812,12 +3002,23 @@ Init_ossl_ssl(void)
|
|
2812
3002
|
rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
|
2813
3003
|
|
2814
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
|
2815
3008
|
rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
|
2816
|
-
#ifdef
|
2817
|
-
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));
|
2818
3011
|
#endif
|
2819
|
-
|
3012
|
+
rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
|
2820
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));
|
2821
3022
|
#endif
|
2822
3023
|
#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
|
2823
3024
|
rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
|
@@ -2830,13 +3031,15 @@ Init_ossl_ssl(void)
|
|
2830
3031
|
#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
|
2831
3032
|
rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
|
2832
3033
|
#endif
|
2833
|
-
|
2834
|
-
rb_define_const(mSSL, "
|
2835
|
-
#
|
2836
|
-
|
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));
|
2837
3042
|
#endif
|
2838
|
-
rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
|
2839
|
-
|
2840
3043
|
rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
|
2841
3044
|
rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
|
2842
3045
|
rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
|
@@ -2844,6 +3047,12 @@ Init_ossl_ssl(void)
|
|
2844
3047
|
#ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
|
2845
3048
|
rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
|
2846
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));
|
2847
3056
|
|
2848
3057
|
/* SSL_OP_* flags for DTLS */
|
2849
3058
|
#if 0
|
@@ -2908,16 +3117,16 @@ Init_ossl_ssl(void)
|
|
2908
3117
|
#endif
|
2909
3118
|
|
2910
3119
|
|
2911
|
-
sym_exception = ID2SYM(
|
2912
|
-
sym_wait_readable = ID2SYM(
|
2913
|
-
sym_wait_writable = ID2SYM(
|
3120
|
+
sym_exception = ID2SYM(rb_intern_const("exception"));
|
3121
|
+
sym_wait_readable = ID2SYM(rb_intern_const("wait_readable"));
|
3122
|
+
sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
|
2914
3123
|
|
2915
|
-
id_tmp_dh_callback =
|
2916
|
-
|
2917
|
-
|
3124
|
+
id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
|
3125
|
+
id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
|
3126
|
+
id_each = rb_intern_const("each");
|
2918
3127
|
|
2919
3128
|
#define DefIVarID(name) do \
|
2920
|
-
id_i_##name =
|
3129
|
+
id_i_##name = rb_intern_const("@"#name); while (0)
|
2921
3130
|
|
2922
3131
|
DefIVarID(cert_store);
|
2923
3132
|
DefIVarID(ca_file);
|
@@ -2931,7 +3140,6 @@ Init_ossl_ssl(void)
|
|
2931
3140
|
DefIVarID(key);
|
2932
3141
|
DefIVarID(extra_chain_cert);
|
2933
3142
|
DefIVarID(client_cert_cb);
|
2934
|
-
DefIVarID(tmp_ecdh_callback);
|
2935
3143
|
DefIVarID(timeout);
|
2936
3144
|
DefIVarID(session_id_context);
|
2937
3145
|
DefIVarID(session_get_cb);
|
@@ -2943,8 +3151,10 @@ Init_ossl_ssl(void)
|
|
2943
3151
|
DefIVarID(alpn_select_cb);
|
2944
3152
|
DefIVarID(servername_cb);
|
2945
3153
|
DefIVarID(verify_hostname);
|
3154
|
+
DefIVarID(keylog_cb);
|
2946
3155
|
|
2947
3156
|
DefIVarID(io);
|
2948
3157
|
DefIVarID(context);
|
2949
3158
|
DefIVarID(hostname);
|
3159
|
+
#endif /* !defined(OPENSSL_NO_SOCK) */
|
2950
3160
|
}
|