openssl 2.1.2 → 3.0.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 +232 -0
- data/README.md +2 -2
- data/ext/openssl/extconf.rb +61 -46
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +60 -44
- data/ext/openssl/ossl.c +112 -66
- data/ext/openssl/ossl.h +28 -11
- data/ext/openssl/ossl_asn1.c +42 -5
- data/ext/openssl/ossl_bn.c +276 -146
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +38 -29
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +31 -62
- data/ext/openssl/ossl_engine.c +18 -27
- data/ext/openssl/ossl_hmac.c +52 -145
- data/ext/openssl/ossl_kdf.c +11 -19
- data/ext/openssl/ossl_ns_spki.c +1 -1
- data/ext/openssl/ossl_ocsp.c +9 -62
- data/ext/openssl/ossl_ocsp.h +3 -3
- data/ext/openssl/ossl_pkcs12.c +21 -3
- data/ext/openssl/ossl_pkcs7.c +45 -78
- data/ext/openssl/ossl_pkcs7.h +16 -0
- data/ext/openssl/ossl_pkey.c +1255 -178
- data/ext/openssl/ossl_pkey.h +40 -77
- data/ext/openssl/ossl_pkey_dh.c +125 -335
- data/ext/openssl/ossl_pkey_dsa.c +93 -398
- data/ext/openssl/ossl_pkey_ec.c +155 -318
- data/ext/openssl/ossl_pkey_rsa.c +105 -484
- data/ext/openssl/ossl_rand.c +2 -40
- data/ext/openssl/ossl_ssl.c +395 -364
- data/ext/openssl/ossl_ssl_session.c +24 -29
- 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_x509cert.c +166 -10
- data/ext/openssl/ossl_x509crl.c +10 -7
- data/ext/openssl/ossl_x509ext.c +15 -2
- data/ext/openssl/ossl_x509name.c +16 -5
- data/ext/openssl/ossl_x509req.c +10 -7
- data/ext/openssl/ossl_x509store.c +193 -92
- data/lib/openssl/bn.rb +1 -1
- data/lib/openssl/buffering.rb +42 -17
- data/lib/openssl/cipher.rb +1 -1
- data/lib/openssl/digest.rb +10 -12
- 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 +435 -1
- data/lib/openssl/ssl.rb +53 -14
- data/lib/openssl/version.rb +5 -0
- data/lib/openssl/x509.rb +177 -1
- data/lib/openssl.rb +24 -9
- metadata +13 -69
- 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
@@ -13,6 +13,12 @@
|
|
13
13
|
|
14
14
|
#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
|
15
15
|
|
16
|
+
#if !defined(TLS1_3_VERSION) && \
|
17
|
+
defined(LIBRESSL_VERSION_NUMBER) && \
|
18
|
+
LIBRESSL_VERSION_NUMBER >= 0x3020000fL
|
19
|
+
# define TLS1_3_VERSION 0x0304
|
20
|
+
#endif
|
21
|
+
|
16
22
|
#ifdef _WIN32
|
17
23
|
# define TO_SOCKET(s) _get_osfhandle(s)
|
18
24
|
#else
|
@@ -32,14 +38,14 @@ VALUE cSSLSocket;
|
|
32
38
|
static VALUE eSSLErrorWaitReadable;
|
33
39
|
static VALUE eSSLErrorWaitWritable;
|
34
40
|
|
35
|
-
static ID id_call, ID_callback_state, id_tmp_dh_callback,
|
36
|
-
id_npn_protocols_encoded;
|
41
|
+
static ID id_call, ID_callback_state, id_tmp_dh_callback,
|
42
|
+
id_npn_protocols_encoded, id_each;
|
37
43
|
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
|
38
44
|
|
39
45
|
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
|
40
46
|
id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
|
41
47
|
id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
|
42
|
-
id_i_client_cert_cb,
|
48
|
+
id_i_client_cert_cb, id_i_timeout,
|
43
49
|
id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
|
44
50
|
id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
|
45
51
|
id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
|
@@ -49,25 +55,24 @@ static ID id_i_io, id_i_context, id_i_hostname;
|
|
49
55
|
static int ossl_ssl_ex_vcb_idx;
|
50
56
|
static int ossl_ssl_ex_ptr_idx;
|
51
57
|
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
58
|
|
56
59
|
static void
|
57
|
-
|
60
|
+
ossl_sslctx_mark(void *ptr)
|
58
61
|
{
|
59
62
|
SSL_CTX *ctx = ptr;
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
rb_gc_mark((VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx));
|
64
|
+
}
|
65
|
+
|
66
|
+
static void
|
67
|
+
ossl_sslctx_free(void *ptr)
|
68
|
+
{
|
69
|
+
SSL_CTX_free(ptr);
|
65
70
|
}
|
66
71
|
|
67
72
|
static const rb_data_type_t ossl_sslctx_type = {
|
68
73
|
"OpenSSL/SSL/CTX",
|
69
74
|
{
|
70
|
-
|
75
|
+
ossl_sslctx_mark, ossl_sslctx_free,
|
71
76
|
},
|
72
77
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
73
78
|
};
|
@@ -83,7 +88,7 @@ ossl_sslctx_s_alloc(VALUE klass)
|
|
83
88
|
VALUE obj;
|
84
89
|
|
85
90
|
obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
|
86
|
-
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
91
|
+
#if OPENSSL_VERSION_NUMBER >= 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
|
87
92
|
ctx = SSL_CTX_new(TLS_method());
|
88
93
|
#else
|
89
94
|
ctx = SSL_CTX_new(SSLv23_method());
|
@@ -95,14 +100,15 @@ ossl_sslctx_s_alloc(VALUE klass)
|
|
95
100
|
RTYPEDDATA_DATA(obj) = ctx;
|
96
101
|
SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj);
|
97
102
|
|
98
|
-
#if !defined(OPENSSL_NO_EC) &&
|
103
|
+
#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER < 0x10100000 && \
|
104
|
+
!defined(LIBRESSL_VERSION_NUMBER)
|
99
105
|
/* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
|
100
106
|
* allows to specify multiple curve names and OpenSSL will select
|
101
107
|
* 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=. */
|
108
|
+
* be enabled explicitly. OpenSSL 1.1.0 and LibreSSL 2.6.1 removed the knob
|
109
|
+
* and it is always enabled. To uniform the behavior, we enable the
|
110
|
+
* automatic selection also in 1.0.2. Users can still disable ECDH by
|
111
|
+
* removing ECDH cipher suites by SSLContext#ciphers=. */
|
106
112
|
if (!SSL_CTX_set_ecdh_auto(ctx, 1))
|
107
113
|
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
108
114
|
#endif
|
@@ -184,8 +190,10 @@ ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
|
|
184
190
|
|
185
191
|
for (i = 0; i < numberof(options_map); i++) {
|
186
192
|
sum |= options_map[i].opts;
|
187
|
-
|
193
|
+
if ((min && min > options_map[i].ver) ||
|
194
|
+
(max && max < options_map[i].ver)) {
|
188
195
|
opts |= options_map[i].opts;
|
196
|
+
}
|
189
197
|
}
|
190
198
|
SSL_CTX_clear_options(ctx, sum);
|
191
199
|
SSL_CTX_set_options(ctx, opts);
|
@@ -229,8 +237,7 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
|
229
237
|
return 1;
|
230
238
|
}
|
231
239
|
|
232
|
-
#if !defined(OPENSSL_NO_DH)
|
233
|
-
!defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
240
|
+
#if !defined(OPENSSL_NO_DH)
|
234
241
|
struct tmp_dh_callback_args {
|
235
242
|
VALUE ssl_obj;
|
236
243
|
ID id;
|
@@ -239,22 +246,23 @@ struct tmp_dh_callback_args {
|
|
239
246
|
int keylength;
|
240
247
|
};
|
241
248
|
|
242
|
-
static
|
243
|
-
ossl_call_tmp_dh_callback(
|
249
|
+
static VALUE
|
250
|
+
ossl_call_tmp_dh_callback(VALUE arg)
|
244
251
|
{
|
252
|
+
struct tmp_dh_callback_args *args = (struct tmp_dh_callback_args *)arg;
|
245
253
|
VALUE cb, dh;
|
246
254
|
EVP_PKEY *pkey;
|
247
255
|
|
248
256
|
cb = rb_funcall(args->ssl_obj, args->id, 0);
|
249
257
|
if (NIL_P(cb))
|
250
|
-
return NULL;
|
258
|
+
return (VALUE)NULL;
|
251
259
|
dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
|
252
260
|
INT2NUM(args->keylength));
|
253
261
|
pkey = GetPKeyPtr(dh);
|
254
262
|
if (EVP_PKEY_base_id(pkey) != args->type)
|
255
|
-
return NULL;
|
263
|
+
return (VALUE)NULL;
|
256
264
|
|
257
|
-
return pkey;
|
265
|
+
return (VALUE)pkey;
|
258
266
|
}
|
259
267
|
#endif
|
260
268
|
|
@@ -274,7 +282,7 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
|
274
282
|
args.keylength = keylength;
|
275
283
|
args.type = EVP_PKEY_DH;
|
276
284
|
|
277
|
-
pkey = (EVP_PKEY *)rb_protect(
|
285
|
+
pkey = (EVP_PKEY *)rb_protect(ossl_call_tmp_dh_callback,
|
278
286
|
(VALUE)&args, &state);
|
279
287
|
if (state) {
|
280
288
|
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
@@ -287,35 +295,6 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
|
287
295
|
}
|
288
296
|
#endif /* OPENSSL_NO_DH */
|
289
297
|
|
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
298
|
static VALUE
|
320
299
|
call_verify_certificate_identity(VALUE ctx_v)
|
321
300
|
{
|
@@ -357,7 +336,14 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|
357
336
|
rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
|
358
337
|
return 0;
|
359
338
|
}
|
360
|
-
|
339
|
+
if (ret != Qtrue) {
|
340
|
+
preverify_ok = 0;
|
341
|
+
#if defined(X509_V_ERR_HOSTNAME_MISMATCH)
|
342
|
+
X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
|
343
|
+
#else
|
344
|
+
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
|
345
|
+
#endif
|
346
|
+
}
|
361
347
|
}
|
362
348
|
|
363
349
|
return ossl_verify_cb_call(cb, preverify_ok, ctx);
|
@@ -378,7 +364,7 @@ ossl_call_session_get_cb(VALUE ary)
|
|
378
364
|
}
|
379
365
|
|
380
366
|
static SSL_SESSION *
|
381
|
-
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
367
|
+
#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
|
382
368
|
ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
|
383
369
|
#else
|
384
370
|
ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
|
@@ -587,10 +573,8 @@ ssl_renegotiation_cb(const SSL *ssl)
|
|
587
573
|
rb_funcallv(cb, id_call, 1, &ssl_obj);
|
588
574
|
}
|
589
575
|
|
590
|
-
#if !defined(OPENSSL_NO_NEXTPROTONEG) || \
|
591
|
-
defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
|
592
576
|
static VALUE
|
593
|
-
ssl_npn_encode_protocol_i(
|
577
|
+
ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
|
594
578
|
{
|
595
579
|
int len = RSTRING_LENINT(cur);
|
596
580
|
char len_byte;
|
@@ -607,7 +591,7 @@ static VALUE
|
|
607
591
|
ssl_encode_npn_protocols(VALUE protocols)
|
608
592
|
{
|
609
593
|
VALUE encoded = rb_str_new(NULL, 0);
|
610
|
-
|
594
|
+
rb_block_call(protocols, id_each, 0, 0, ssl_npn_encode_protocol_i, encoded);
|
611
595
|
return encoded;
|
612
596
|
}
|
613
597
|
|
@@ -670,14 +654,13 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
|
|
670
654
|
|
671
655
|
return SSL_TLSEXT_ERR_OK;
|
672
656
|
}
|
673
|
-
#endif
|
674
657
|
|
675
658
|
#ifndef OPENSSL_NO_NEXTPROTONEG
|
676
659
|
static int
|
677
660
|
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
|
678
661
|
void *arg)
|
679
662
|
{
|
680
|
-
VALUE protocols = (VALUE)arg;
|
663
|
+
VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded);
|
681
664
|
|
682
665
|
*out = (const unsigned char *) RSTRING_PTR(protocols);
|
683
666
|
*outlen = RSTRING_LENINT(protocols);
|
@@ -699,7 +682,6 @@ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
|
|
699
682
|
}
|
700
683
|
#endif
|
701
684
|
|
702
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
703
685
|
static int
|
704
686
|
ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
705
687
|
const unsigned char *in, unsigned int inlen, void *arg)
|
@@ -711,7 +693,6 @@ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
|
711
693
|
|
712
694
|
return ssl_npn_select_cb_common(ssl, cb, out, outlen, in, inlen);
|
713
695
|
}
|
714
|
-
#endif
|
715
696
|
|
716
697
|
/* This function may serve as the entry point to support further callbacks. */
|
717
698
|
static void
|
@@ -788,41 +769,15 @@ ossl_sslctx_setup(VALUE self)
|
|
788
769
|
SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
|
789
770
|
#endif
|
790
771
|
|
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 */
|
772
|
+
#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
|
773
|
+
SSL_CTX_set_post_handshake_auth(ctx, 1);
|
774
|
+
#endif
|
810
775
|
|
811
776
|
val = rb_attr_get(self, id_i_cert_store);
|
812
777
|
if (!NIL_P(val)) {
|
813
778
|
X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
|
814
779
|
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
780
|
X509_STORE_up_ref(store);
|
825
|
-
#endif
|
826
781
|
}
|
827
782
|
|
828
783
|
val = rb_attr_get(self, id_i_extra_chain_cert);
|
@@ -873,10 +828,17 @@ ossl_sslctx_setup(VALUE self)
|
|
873
828
|
ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
|
874
829
|
val = rb_attr_get(self, id_i_ca_path);
|
875
830
|
ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
|
831
|
+
#ifdef HAVE_SSL_CTX_LOAD_VERIFY_FILE
|
832
|
+
if (ca_file && !SSL_CTX_load_verify_file(ctx, ca_file))
|
833
|
+
ossl_raise(eSSLError, "SSL_CTX_load_verify_file");
|
834
|
+
if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path))
|
835
|
+
ossl_raise(eSSLError, "SSL_CTX_load_verify_dir");
|
836
|
+
#else
|
876
837
|
if(ca_file || ca_path){
|
877
838
|
if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
|
878
839
|
rb_warning("can't set verify locations");
|
879
840
|
}
|
841
|
+
#endif
|
880
842
|
|
881
843
|
val = rb_attr_get(self, id_i_verify_mode);
|
882
844
|
verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
|
@@ -895,7 +857,7 @@ ossl_sslctx_setup(VALUE self)
|
|
895
857
|
if (!NIL_P(val)) {
|
896
858
|
VALUE encoded = ssl_encode_npn_protocols(val);
|
897
859
|
rb_ivar_set(self, id_npn_protocols_encoded, encoded);
|
898
|
-
SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)
|
860
|
+
SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
|
899
861
|
OSSL_Debug("SSL NPN advertise callback added");
|
900
862
|
}
|
901
863
|
if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
|
@@ -904,7 +866,6 @@ ossl_sslctx_setup(VALUE self)
|
|
904
866
|
}
|
905
867
|
#endif
|
906
868
|
|
907
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
908
869
|
val = rb_attr_get(self, id_i_alpn_protocols);
|
909
870
|
if (!NIL_P(val)) {
|
910
871
|
VALUE rprotos = ssl_encode_npn_protocols(val);
|
@@ -919,7 +880,6 @@ ossl_sslctx_setup(VALUE self)
|
|
919
880
|
SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
|
920
881
|
OSSL_Debug("SSL ALPN select callback added");
|
921
882
|
}
|
922
|
-
#endif
|
923
883
|
|
924
884
|
rb_obj_freeze(self);
|
925
885
|
|
@@ -1041,6 +1001,52 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
|
1041
1001
|
return v;
|
1042
1002
|
}
|
1043
1003
|
|
1004
|
+
#ifndef OPENSSL_NO_DH
|
1005
|
+
/*
|
1006
|
+
* call-seq:
|
1007
|
+
* ctx.tmp_dh = pkey
|
1008
|
+
*
|
1009
|
+
* Sets DH parameters used for ephemeral DH key exchange. This is relevant for
|
1010
|
+
* servers only.
|
1011
|
+
*
|
1012
|
+
* +pkey+ is an instance of OpenSSL::PKey::DH. Note that key components
|
1013
|
+
* contained in the key object, if any, are ignored. The server will always
|
1014
|
+
* generate a new key pair for each handshake.
|
1015
|
+
*
|
1016
|
+
* Added in version 3.0. See also the man page SSL_set0_tmp_dh_pkey(3).
|
1017
|
+
*
|
1018
|
+
* Example:
|
1019
|
+
* ctx = OpenSSL::SSL::SSLContext.new
|
1020
|
+
* ctx.tmp_dh = OpenSSL::DH.generate(2048)
|
1021
|
+
* svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx)
|
1022
|
+
* Thread.new { svr.accept }
|
1023
|
+
*/
|
1024
|
+
static VALUE
|
1025
|
+
ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg)
|
1026
|
+
{
|
1027
|
+
SSL_CTX *ctx;
|
1028
|
+
EVP_PKEY *pkey;
|
1029
|
+
|
1030
|
+
rb_check_frozen(self);
|
1031
|
+
GetSSLCTX(self, ctx);
|
1032
|
+
pkey = GetPKeyPtr(arg);
|
1033
|
+
|
1034
|
+
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH)
|
1035
|
+
rb_raise(eSSLError, "invalid pkey type %s (expected DH)",
|
1036
|
+
OBJ_nid2sn(EVP_PKEY_base_id(pkey)));
|
1037
|
+
#ifdef HAVE_SSL_SET0_TMP_DH_PKEY
|
1038
|
+
if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkey))
|
1039
|
+
ossl_raise(eSSLError, "SSL_CTX_set0_tmp_dh_pkey");
|
1040
|
+
EVP_PKEY_up_ref(pkey);
|
1041
|
+
#else
|
1042
|
+
if (!SSL_CTX_set_tmp_dh(ctx, EVP_PKEY_get0_DH(pkey)))
|
1043
|
+
ossl_raise(eSSLError, "SSL_CTX_set_tmp_dh");
|
1044
|
+
#endif
|
1045
|
+
|
1046
|
+
return arg;
|
1047
|
+
}
|
1048
|
+
#endif
|
1049
|
+
|
1044
1050
|
#if !defined(OPENSSL_NO_EC)
|
1045
1051
|
/*
|
1046
1052
|
* call-seq:
|
@@ -1052,9 +1058,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
|
1052
1058
|
* Extension. For a server, the list is used by OpenSSL to determine the set of
|
1053
1059
|
* shared curves. OpenSSL will pick the most appropriate one from it.
|
1054
1060
|
*
|
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
1061
|
* === Example
|
1059
1062
|
* ctx1 = OpenSSL::SSL::SSLContext.new
|
1060
1063
|
* ctx1.ecdh_curves = "X25519:P-256:P-224"
|
@@ -1078,48 +1081,8 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
|
|
1078
1081
|
GetSSLCTX(self, ctx);
|
1079
1082
|
StringValueCStr(arg);
|
1080
1083
|
|
1081
|
-
#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
|
1082
1084
|
if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
|
1083
1085
|
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
1086
|
return arg;
|
1124
1087
|
}
|
1125
1088
|
#else
|
@@ -1210,7 +1173,7 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
|
|
1210
1173
|
|
1211
1174
|
/*
|
1212
1175
|
* call-seq:
|
1213
|
-
* ctx.add_certificate(
|
1176
|
+
* ctx.add_certificate(certificate, pkey [, extra_certs]) -> self
|
1214
1177
|
*
|
1215
1178
|
* Adds a certificate to the context. _pkey_ must be a corresponding private
|
1216
1179
|
* key with _certificate_.
|
@@ -1242,10 +1205,6 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
|
|
1242
1205
|
* ecdsa_pkey = ...
|
1243
1206
|
* another_ca_cert = ...
|
1244
1207
|
* 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
1208
|
*/
|
1250
1209
|
static VALUE
|
1251
1210
|
ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
@@ -1270,7 +1229,7 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
|
1270
1229
|
EVP_PKEY_free(pub_pkey);
|
1271
1230
|
if (!pub_pkey)
|
1272
1231
|
rb_raise(rb_eArgError, "certificate does not contain public key");
|
1273
|
-
if (
|
1232
|
+
if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
|
1274
1233
|
rb_raise(rb_eArgError, "public key mismatch");
|
1275
1234
|
|
1276
1235
|
if (argc >= 3)
|
@@ -1284,34 +1243,9 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
|
1284
1243
|
sk_X509_pop_free(extra_chain, X509_free);
|
1285
1244
|
ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
|
1286
1245
|
}
|
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
|
1246
|
+
if (extra_chain && !SSL_CTX_set0_chain(ctx, extra_chain)) {
|
1247
|
+
sk_X509_pop_free(extra_chain, X509_free);
|
1248
|
+
ossl_raise(eSSLError, "SSL_CTX_set0_chain");
|
1315
1249
|
}
|
1316
1250
|
return self;
|
1317
1251
|
}
|
@@ -1509,8 +1443,16 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
|
|
1509
1443
|
static inline int
|
1510
1444
|
ssl_started(SSL *ssl)
|
1511
1445
|
{
|
1512
|
-
/*
|
1513
|
-
return
|
1446
|
+
/* BIO is created through ossl_ssl_setup(), called by #connect or #accept */
|
1447
|
+
return SSL_get_rbio(ssl) != NULL;
|
1448
|
+
}
|
1449
|
+
|
1450
|
+
static void
|
1451
|
+
ossl_ssl_mark(void *ptr)
|
1452
|
+
{
|
1453
|
+
SSL *ssl = ptr;
|
1454
|
+
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
|
1455
|
+
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
|
1514
1456
|
}
|
1515
1457
|
|
1516
1458
|
static void
|
@@ -1522,7 +1464,7 @@ ossl_ssl_free(void *ssl)
|
|
1522
1464
|
const rb_data_type_t ossl_ssl_type = {
|
1523
1465
|
"OpenSSL/SSL",
|
1524
1466
|
{
|
1525
|
-
|
1467
|
+
ossl_ssl_mark, ossl_ssl_free,
|
1526
1468
|
},
|
1527
1469
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
1528
1470
|
};
|
@@ -1533,6 +1475,29 @@ ossl_ssl_s_alloc(VALUE klass)
|
|
1533
1475
|
return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
|
1534
1476
|
}
|
1535
1477
|
|
1478
|
+
static VALUE
|
1479
|
+
peer_ip_address(VALUE self)
|
1480
|
+
{
|
1481
|
+
VALUE remote_address = rb_funcall(rb_attr_get(self, id_i_io), rb_intern("remote_address"), 0);
|
1482
|
+
|
1483
|
+
return rb_funcall(remote_address, rb_intern("inspect_sockaddr"), 0);
|
1484
|
+
}
|
1485
|
+
|
1486
|
+
static VALUE
|
1487
|
+
fallback_peer_ip_address(VALUE self, VALUE args)
|
1488
|
+
{
|
1489
|
+
return rb_str_new_cstr("(null)");
|
1490
|
+
}
|
1491
|
+
|
1492
|
+
static VALUE
|
1493
|
+
peeraddr_ip_str(VALUE self)
|
1494
|
+
{
|
1495
|
+
VALUE rb_mErrno = rb_const_get(rb_cObject, rb_intern("Errno"));
|
1496
|
+
VALUE rb_eSystemCallError = rb_const_get(rb_mErrno, rb_intern("SystemCallError"));
|
1497
|
+
|
1498
|
+
return rb_rescue2(peer_ip_address, self, fallback_peer_ip_address, (VALUE)0, rb_eSystemCallError, NULL);
|
1499
|
+
}
|
1500
|
+
|
1536
1501
|
/*
|
1537
1502
|
* call-seq:
|
1538
1503
|
* SSLSocket.new(io) => aSSLSocket
|
@@ -1569,6 +1534,7 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
|
1569
1534
|
|
1570
1535
|
if (rb_respond_to(io, rb_intern("nonblock=")))
|
1571
1536
|
rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
|
1537
|
+
Check_Type(io, T_FILE);
|
1572
1538
|
rb_ivar_set(self, id_i_io, io);
|
1573
1539
|
|
1574
1540
|
ssl = SSL_new(ctx);
|
@@ -1636,6 +1602,26 @@ no_exception_p(VALUE opts)
|
|
1636
1602
|
return 0;
|
1637
1603
|
}
|
1638
1604
|
|
1605
|
+
static void
|
1606
|
+
io_wait_writable(rb_io_t *fptr)
|
1607
|
+
{
|
1608
|
+
#ifdef HAVE_RB_IO_MAYBE_WAIT
|
1609
|
+
rb_io_maybe_wait_writable(errno, fptr->self, Qnil);
|
1610
|
+
#else
|
1611
|
+
rb_io_wait_writable(fptr->fd);
|
1612
|
+
#endif
|
1613
|
+
}
|
1614
|
+
|
1615
|
+
static void
|
1616
|
+
io_wait_readable(rb_io_t *fptr)
|
1617
|
+
{
|
1618
|
+
#ifdef HAVE_RB_IO_MAYBE_WAIT
|
1619
|
+
rb_io_maybe_wait_readable(errno, fptr->self, Qnil);
|
1620
|
+
#else
|
1621
|
+
rb_io_wait_readable(fptr->fd);
|
1622
|
+
#endif
|
1623
|
+
}
|
1624
|
+
|
1639
1625
|
static VALUE
|
1640
1626
|
ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
1641
1627
|
{
|
@@ -1670,16 +1656,23 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|
1670
1656
|
case SSL_ERROR_WANT_WRITE:
|
1671
1657
|
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1672
1658
|
write_would_block(nonblock);
|
1673
|
-
|
1659
|
+
io_wait_writable(fptr);
|
1674
1660
|
continue;
|
1675
1661
|
case SSL_ERROR_WANT_READ:
|
1676
1662
|
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1677
1663
|
read_would_block(nonblock);
|
1678
|
-
|
1664
|
+
io_wait_readable(fptr);
|
1679
1665
|
continue;
|
1680
1666
|
case SSL_ERROR_SYSCALL:
|
1667
|
+
#ifdef __APPLE__
|
1668
|
+
/* See ossl_ssl_write_internal() */
|
1669
|
+
if (errno == EPROTOTYPE)
|
1670
|
+
continue;
|
1671
|
+
#endif
|
1681
1672
|
if (errno) rb_sys_fail(funcname);
|
1682
|
-
ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s",
|
1673
|
+
ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
|
1674
|
+
funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
|
1675
|
+
|
1683
1676
|
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
1684
1677
|
case SSL_ERROR_SSL:
|
1685
1678
|
err = ERR_peek_last_error();
|
@@ -1692,13 +1685,15 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|
1692
1685
|
if (!verify_msg)
|
1693
1686
|
verify_msg = "(null)";
|
1694
1687
|
ossl_clear_error(); /* let ossl_raise() not append message */
|
1695
|
-
ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s: %s (%s)",
|
1696
|
-
funcname, ret2, errno, SSL_state_string_long(ssl),
|
1688
|
+
ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s: %s (%s)",
|
1689
|
+
funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl),
|
1697
1690
|
err_msg, verify_msg);
|
1698
1691
|
}
|
1699
1692
|
#endif
|
1693
|
+
/* fallthrough */
|
1700
1694
|
default:
|
1701
|
-
ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s",
|
1695
|
+
ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
|
1696
|
+
funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
|
1702
1697
|
}
|
1703
1698
|
}
|
1704
1699
|
|
@@ -1709,8 +1704,7 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|
1709
1704
|
* call-seq:
|
1710
1705
|
* ssl.connect => self
|
1711
1706
|
*
|
1712
|
-
* Initiates an SSL/TLS handshake with a server.
|
1713
|
-
* after unencrypted data has been sent over the socket.
|
1707
|
+
* Initiates an SSL/TLS handshake with a server.
|
1714
1708
|
*/
|
1715
1709
|
static VALUE
|
1716
1710
|
ossl_ssl_connect(VALUE self)
|
@@ -1757,8 +1751,7 @@ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
|
|
1757
1751
|
* call-seq:
|
1758
1752
|
* ssl.accept => self
|
1759
1753
|
*
|
1760
|
-
* Waits for a SSL/TLS client to initiate a handshake.
|
1761
|
-
* started after unencrypted data has been sent over the socket.
|
1754
|
+
* Waits for a SSL/TLS client to initiate a handshake.
|
1762
1755
|
*/
|
1763
1756
|
static VALUE
|
1764
1757
|
ossl_ssl_accept(VALUE self)
|
@@ -1805,7 +1798,7 @@ static VALUE
|
|
1805
1798
|
ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
1806
1799
|
{
|
1807
1800
|
SSL *ssl;
|
1808
|
-
int ilen
|
1801
|
+
int ilen;
|
1809
1802
|
VALUE len, str;
|
1810
1803
|
rb_io_t *fptr;
|
1811
1804
|
VALUE io, opts = Qnil;
|
@@ -1815,6 +1808,9 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1815
1808
|
} else {
|
1816
1809
|
rb_scan_args(argc, argv, "11", &len, &str);
|
1817
1810
|
}
|
1811
|
+
GetSSL(self, ssl);
|
1812
|
+
if (!ssl_started(ssl))
|
1813
|
+
rb_raise(eSSLError, "SSL session is not started yet");
|
1818
1814
|
|
1819
1815
|
ilen = NUM2INT(len);
|
1820
1816
|
if (NIL_P(str))
|
@@ -1826,67 +1822,64 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1826
1822
|
else
|
1827
1823
|
rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
|
1828
1824
|
}
|
1829
|
-
OBJ_TAINT(str);
|
1830
1825
|
rb_str_set_len(str, 0);
|
1831
1826
|
if (ilen == 0)
|
1832
1827
|
return str;
|
1833
1828
|
|
1834
|
-
GetSSL(self, ssl);
|
1835
1829
|
io = rb_attr_get(self, id_i_io);
|
1836
1830
|
GetOpenFile(io, fptr);
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1831
|
+
|
1832
|
+
rb_str_locktmp(str);
|
1833
|
+
for (;;) {
|
1834
|
+
int nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
|
1835
|
+
switch (ssl_get_error(ssl, nread)) {
|
1836
|
+
case SSL_ERROR_NONE:
|
1837
|
+
rb_str_unlocktmp(str);
|
1838
|
+
rb_str_set_len(str, nread);
|
1839
|
+
return str;
|
1840
|
+
case SSL_ERROR_ZERO_RETURN:
|
1841
|
+
rb_str_unlocktmp(str);
|
1842
|
+
if (no_exception_p(opts)) { return Qnil; }
|
1843
|
+
rb_eof_error();
|
1844
|
+
case SSL_ERROR_WANT_WRITE:
|
1845
|
+
if (nonblock) {
|
1846
|
+
rb_str_unlocktmp(str);
|
1847
|
+
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1848
1848
|
write_would_block(nonblock);
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1849
|
+
}
|
1850
|
+
io_wait_writable(fptr);
|
1851
|
+
continue;
|
1852
|
+
case SSL_ERROR_WANT_READ:
|
1853
|
+
if (nonblock) {
|
1854
|
+
rb_str_unlocktmp(str);
|
1855
|
+
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1853
1856
|
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
|
-
|
1857
|
+
}
|
1858
|
+
io_wait_readable(fptr);
|
1859
|
+
continue;
|
1860
|
+
case SSL_ERROR_SYSCALL:
|
1861
|
+
if (!ERR_peek_error()) {
|
1862
|
+
rb_str_unlocktmp(str);
|
1863
|
+
if (errno)
|
1864
|
+
rb_sys_fail(0);
|
1865
|
+
else {
|
1866
|
+
/*
|
1867
|
+
* The underlying BIO returned 0. This is actually a
|
1868
|
+
* protocol error. But unfortunately, not all
|
1869
|
+
* implementations cleanly shutdown the TLS connection
|
1870
|
+
* but just shutdown/close the TCP connection. So report
|
1871
|
+
* EOF for now...
|
1872
|
+
*/
|
1873
|
+
if (no_exception_p(opts)) { return Qnil; }
|
1874
|
+
rb_eof_error();
|
1875
|
+
}
|
1876
|
+
}
|
1877
|
+
/* fall through */
|
1878
|
+
default:
|
1879
|
+
rb_str_unlocktmp(str);
|
1880
|
+
ossl_raise(eSSLError, "SSL_read");
|
1875
1881
|
}
|
1876
1882
|
}
|
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
1883
|
}
|
1891
1884
|
|
1892
1885
|
/*
|
@@ -1926,57 +1919,55 @@ static VALUE
|
|
1926
1919
|
ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
1927
1920
|
{
|
1928
1921
|
SSL *ssl;
|
1929
|
-
int nwrite = 0;
|
1930
1922
|
rb_io_t *fptr;
|
1931
|
-
int nonblock = opts != Qfalse;
|
1932
|
-
VALUE io;
|
1923
|
+
int num, nonblock = opts != Qfalse;
|
1924
|
+
VALUE tmp, io;
|
1933
1925
|
|
1934
|
-
StringValue(str);
|
1935
1926
|
GetSSL(self, ssl);
|
1927
|
+
if (!ssl_started(ssl))
|
1928
|
+
rb_raise(eSSLError, "SSL session is not started yet");
|
1929
|
+
|
1930
|
+
tmp = rb_str_new_frozen(StringValue(str));
|
1936
1931
|
io = rb_attr_get(self, id_i_io);
|
1937
1932
|
GetOpenFile(io, fptr);
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1933
|
+
|
1934
|
+
/* SSL_write(3ssl) manpage states num == 0 is undefined */
|
1935
|
+
num = RSTRING_LENINT(tmp);
|
1936
|
+
if (num == 0)
|
1937
|
+
return INT2FIX(0);
|
1938
|
+
|
1939
|
+
for (;;) {
|
1940
|
+
int nwritten = SSL_write(ssl, RSTRING_PTR(tmp), num);
|
1941
|
+
switch (ssl_get_error(ssl, nwritten)) {
|
1942
|
+
case SSL_ERROR_NONE:
|
1943
|
+
return INT2NUM(nwritten);
|
1944
|
+
case SSL_ERROR_WANT_WRITE:
|
1945
|
+
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1946
|
+
write_would_block(nonblock);
|
1947
|
+
io_wait_writable(fptr);
|
1948
|
+
continue;
|
1949
|
+
case SSL_ERROR_WANT_READ:
|
1950
|
+
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1951
|
+
read_would_block(nonblock);
|
1952
|
+
io_wait_readable(fptr);
|
1953
|
+
continue;
|
1954
|
+
case SSL_ERROR_SYSCALL:
|
1955
|
+
#ifdef __APPLE__
|
1956
|
+
/*
|
1957
|
+
* It appears that send syscall can return EPROTOTYPE if the
|
1958
|
+
* socket is being torn down. Retry to get a proper errno to
|
1959
|
+
* make the error handling in line with the socket library.
|
1960
|
+
* [Bug #14713] https://bugs.ruby-lang.org/issues/14713
|
1961
|
+
*/
|
1962
|
+
if (errno == EPROTOTYPE)
|
1959
1963
|
continue;
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1964
|
+
#endif
|
1965
|
+
if (errno) rb_sys_fail(0);
|
1966
|
+
/* fallthrough */
|
1967
|
+
default:
|
1968
|
+
ossl_raise(eSSLError, "SSL_write");
|
1965
1969
|
}
|
1966
1970
|
}
|
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
1971
|
}
|
1981
1972
|
|
1982
1973
|
/*
|
@@ -2275,7 +2266,57 @@ ossl_ssl_get_verify_result(VALUE self)
|
|
2275
2266
|
|
2276
2267
|
GetSSL(self, ssl);
|
2277
2268
|
|
2278
|
-
return
|
2269
|
+
return LONG2NUM(SSL_get_verify_result(ssl));
|
2270
|
+
}
|
2271
|
+
|
2272
|
+
/*
|
2273
|
+
* call-seq:
|
2274
|
+
* ssl.finished_message => "finished message"
|
2275
|
+
*
|
2276
|
+
* Returns the last *Finished* message sent
|
2277
|
+
*
|
2278
|
+
*/
|
2279
|
+
static VALUE
|
2280
|
+
ossl_ssl_get_finished(VALUE self)
|
2281
|
+
{
|
2282
|
+
SSL *ssl;
|
2283
|
+
char sizer[1], *buf;
|
2284
|
+
size_t len;
|
2285
|
+
|
2286
|
+
GetSSL(self, ssl);
|
2287
|
+
|
2288
|
+
len = SSL_get_finished(ssl, sizer, 0);
|
2289
|
+
if (len == 0)
|
2290
|
+
return Qnil;
|
2291
|
+
|
2292
|
+
buf = ALLOCA_N(char, len);
|
2293
|
+
SSL_get_finished(ssl, buf, len);
|
2294
|
+
return rb_str_new(buf, len);
|
2295
|
+
}
|
2296
|
+
|
2297
|
+
/*
|
2298
|
+
* call-seq:
|
2299
|
+
* ssl.peer_finished_message => "peer finished message"
|
2300
|
+
*
|
2301
|
+
* Returns the last *Finished* message received
|
2302
|
+
*
|
2303
|
+
*/
|
2304
|
+
static VALUE
|
2305
|
+
ossl_ssl_get_peer_finished(VALUE self)
|
2306
|
+
{
|
2307
|
+
SSL *ssl;
|
2308
|
+
char sizer[1], *buf;
|
2309
|
+
size_t len;
|
2310
|
+
|
2311
|
+
GetSSL(self, ssl);
|
2312
|
+
|
2313
|
+
len = SSL_get_peer_finished(ssl, sizer, 0);
|
2314
|
+
if (len == 0)
|
2315
|
+
return Qnil;
|
2316
|
+
|
2317
|
+
buf = ALLOCA_N(char, len);
|
2318
|
+
SSL_get_peer_finished(ssl, buf, len);
|
2319
|
+
return rb_str_new(buf, len);
|
2279
2320
|
}
|
2280
2321
|
|
2281
2322
|
/*
|
@@ -2326,7 +2367,6 @@ ossl_ssl_npn_protocol(VALUE self)
|
|
2326
2367
|
}
|
2327
2368
|
# endif
|
2328
2369
|
|
2329
|
-
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2330
2370
|
/*
|
2331
2371
|
* call-seq:
|
2332
2372
|
* ssl.alpn_protocol => String | nil
|
@@ -2349,9 +2389,7 @@ ossl_ssl_alpn_protocol(VALUE self)
|
|
2349
2389
|
else
|
2350
2390
|
return rb_str_new((const char *) out, outlen);
|
2351
2391
|
}
|
2352
|
-
# endif
|
2353
2392
|
|
2354
|
-
# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
|
2355
2393
|
/*
|
2356
2394
|
* call-seq:
|
2357
2395
|
* ssl.tmp_key => PKey or nil
|
@@ -2369,11 +2407,8 @@ ossl_ssl_tmp_key(VALUE self)
|
|
2369
2407
|
return Qnil;
|
2370
2408
|
return ossl_pkey_new(key);
|
2371
2409
|
}
|
2372
|
-
# endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */
|
2373
2410
|
#endif /* !defined(OPENSSL_NO_SOCK) */
|
2374
2411
|
|
2375
|
-
#undef rb_intern
|
2376
|
-
#define rb_intern(s) rb_intern_const(s)
|
2377
2412
|
void
|
2378
2413
|
Init_ossl_ssl(void)
|
2379
2414
|
{
|
@@ -2384,8 +2419,8 @@ Init_ossl_ssl(void)
|
|
2384
2419
|
rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
|
2385
2420
|
#endif
|
2386
2421
|
|
2387
|
-
id_call =
|
2388
|
-
ID_callback_state =
|
2422
|
+
id_call = rb_intern_const("call");
|
2423
|
+
ID_callback_state = rb_intern_const("callback_state");
|
2389
2424
|
|
2390
2425
|
ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0);
|
2391
2426
|
if (ossl_ssl_ex_vcb_idx < 0)
|
@@ -2396,11 +2431,6 @@ Init_ossl_ssl(void)
|
|
2396
2431
|
ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
|
2397
2432
|
if (ossl_sslctx_ex_ptr_idx < 0)
|
2398
2433
|
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
2434
|
|
2405
2435
|
/* Document-module: OpenSSL::SSL
|
2406
2436
|
*
|
@@ -2452,7 +2482,7 @@ Init_ossl_ssl(void)
|
|
2452
2482
|
* The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
|
2453
2483
|
* It is recommended to use #add_certificate instead.
|
2454
2484
|
*/
|
2455
|
-
rb_attr(cSSLContext,
|
2485
|
+
rb_attr(cSSLContext, rb_intern_const("cert"), 1, 1, Qfalse);
|
2456
2486
|
|
2457
2487
|
/*
|
2458
2488
|
* Context private key
|
@@ -2460,29 +2490,29 @@ Init_ossl_ssl(void)
|
|
2460
2490
|
* The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
|
2461
2491
|
* It is recommended to use #add_certificate instead.
|
2462
2492
|
*/
|
2463
|
-
rb_attr(cSSLContext,
|
2493
|
+
rb_attr(cSSLContext, rb_intern_const("key"), 1, 1, Qfalse);
|
2464
2494
|
|
2465
2495
|
/*
|
2466
2496
|
* A certificate or Array of certificates that will be sent to the client.
|
2467
2497
|
*/
|
2468
|
-
rb_attr(cSSLContext,
|
2498
|
+
rb_attr(cSSLContext, rb_intern_const("client_ca"), 1, 1, Qfalse);
|
2469
2499
|
|
2470
2500
|
/*
|
2471
2501
|
* The path to a file containing a PEM-format CA certificate
|
2472
2502
|
*/
|
2473
|
-
rb_attr(cSSLContext,
|
2503
|
+
rb_attr(cSSLContext, rb_intern_const("ca_file"), 1, 1, Qfalse);
|
2474
2504
|
|
2475
2505
|
/*
|
2476
2506
|
* The path to a directory containing CA certificates in PEM format.
|
2477
2507
|
*
|
2478
2508
|
* Files are looked up by subject's X509 name's hash value.
|
2479
2509
|
*/
|
2480
|
-
rb_attr(cSSLContext,
|
2510
|
+
rb_attr(cSSLContext, rb_intern_const("ca_path"), 1, 1, Qfalse);
|
2481
2511
|
|
2482
2512
|
/*
|
2483
2513
|
* Maximum session lifetime in seconds.
|
2484
2514
|
*/
|
2485
|
-
rb_attr(cSSLContext,
|
2515
|
+
rb_attr(cSSLContext, rb_intern_const("timeout"), 1, 1, Qfalse);
|
2486
2516
|
|
2487
2517
|
/*
|
2488
2518
|
* Session verification mode.
|
@@ -2495,12 +2525,12 @@ Init_ossl_ssl(void)
|
|
2495
2525
|
*
|
2496
2526
|
* See SSL_CTX_set_verify(3) for details.
|
2497
2527
|
*/
|
2498
|
-
rb_attr(cSSLContext,
|
2528
|
+
rb_attr(cSSLContext, rb_intern_const("verify_mode"), 1, 1, Qfalse);
|
2499
2529
|
|
2500
2530
|
/*
|
2501
2531
|
* Number of CA certificates to walk when verifying a certificate chain.
|
2502
2532
|
*/
|
2503
|
-
rb_attr(cSSLContext,
|
2533
|
+
rb_attr(cSSLContext, rb_intern_const("verify_depth"), 1, 1, Qfalse);
|
2504
2534
|
|
2505
2535
|
/*
|
2506
2536
|
* A callback for additional certificate verification. The callback is
|
@@ -2514,7 +2544,7 @@ Init_ossl_ssl(void)
|
|
2514
2544
|
* If the callback returns +false+, the chain verification is immediately
|
2515
2545
|
* stopped and a bad_certificate alert is then sent.
|
2516
2546
|
*/
|
2517
|
-
rb_attr(cSSLContext,
|
2547
|
+
rb_attr(cSSLContext, rb_intern_const("verify_callback"), 1, 1, Qfalse);
|
2518
2548
|
|
2519
2549
|
/*
|
2520
2550
|
* Whether to check the server certificate is valid for the hostname.
|
@@ -2522,12 +2552,12 @@ Init_ossl_ssl(void)
|
|
2522
2552
|
* In order to make this work, verify_mode must be set to VERIFY_PEER and
|
2523
2553
|
* the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=.
|
2524
2554
|
*/
|
2525
|
-
rb_attr(cSSLContext,
|
2555
|
+
rb_attr(cSSLContext, rb_intern_const("verify_hostname"), 1, 1, Qfalse);
|
2526
2556
|
|
2527
2557
|
/*
|
2528
2558
|
* An OpenSSL::X509::Store used for certificate verification.
|
2529
2559
|
*/
|
2530
|
-
rb_attr(cSSLContext,
|
2560
|
+
rb_attr(cSSLContext, rb_intern_const("cert_store"), 1, 1, Qfalse);
|
2531
2561
|
|
2532
2562
|
/*
|
2533
2563
|
* An Array of extra X509 certificates to be added to the certificate
|
@@ -2536,7 +2566,7 @@ Init_ossl_ssl(void)
|
|
2536
2566
|
* The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
|
2537
2567
|
* It is recommended to use #add_certificate instead.
|
2538
2568
|
*/
|
2539
|
-
rb_attr(cSSLContext,
|
2569
|
+
rb_attr(cSSLContext, rb_intern_const("extra_chain_cert"), 1, 1, Qfalse);
|
2540
2570
|
|
2541
2571
|
/*
|
2542
2572
|
* A callback invoked when a client certificate is requested by a server
|
@@ -2546,28 +2576,14 @@ Init_ossl_ssl(void)
|
|
2546
2576
|
* containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any
|
2547
2577
|
* other value is returned the handshake is suspended.
|
2548
2578
|
*/
|
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
|
2579
|
+
rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
|
2564
2580
|
|
2565
2581
|
/*
|
2566
2582
|
* Sets the context in which a session can be reused. This allows
|
2567
2583
|
* sessions for multiple applications to be distinguished, for example, by
|
2568
2584
|
* name.
|
2569
2585
|
*/
|
2570
|
-
rb_attr(cSSLContext,
|
2586
|
+
rb_attr(cSSLContext, rb_intern_const("session_id_context"), 1, 1, Qfalse);
|
2571
2587
|
|
2572
2588
|
/*
|
2573
2589
|
* A callback invoked on a server when a session is proposed by the client
|
@@ -2576,7 +2592,7 @@ Init_ossl_ssl(void)
|
|
2576
2592
|
* The callback is invoked with the SSLSocket and session id. The
|
2577
2593
|
* callback may return a Session from an external cache.
|
2578
2594
|
*/
|
2579
|
-
rb_attr(cSSLContext,
|
2595
|
+
rb_attr(cSSLContext, rb_intern_const("session_get_cb"), 1, 1, Qfalse);
|
2580
2596
|
|
2581
2597
|
/*
|
2582
2598
|
* A callback invoked when a new session was negotiated.
|
@@ -2584,7 +2600,7 @@ Init_ossl_ssl(void)
|
|
2584
2600
|
* The callback is invoked with an SSLSocket. If +false+ is returned the
|
2585
2601
|
* session will be removed from the internal cache.
|
2586
2602
|
*/
|
2587
|
-
rb_attr(cSSLContext,
|
2603
|
+
rb_attr(cSSLContext, rb_intern_const("session_new_cb"), 1, 1, Qfalse);
|
2588
2604
|
|
2589
2605
|
/*
|
2590
2606
|
* A callback invoked when a session is removed from the internal cache.
|
@@ -2595,18 +2611,18 @@ Init_ossl_ssl(void)
|
|
2595
2611
|
* multi-threaded application. The callback is called inside a global lock
|
2596
2612
|
* and it can randomly cause deadlock on Ruby thread switching.
|
2597
2613
|
*/
|
2598
|
-
rb_attr(cSSLContext,
|
2614
|
+
rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
|
2599
2615
|
|
2600
2616
|
rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
|
2601
2617
|
|
2602
2618
|
/*
|
2603
|
-
* A callback invoked whenever a new handshake is initiated
|
2604
|
-
* to disable renegotiation entirely.
|
2619
|
+
* A callback invoked whenever a new handshake is initiated on an
|
2620
|
+
* established connection. May be used to disable renegotiation entirely.
|
2605
2621
|
*
|
2606
2622
|
* The callback is invoked with the active SSLSocket. The callback's
|
2607
|
-
* return value is
|
2623
|
+
* return value is ignored. A normal return indicates "approval" of the
|
2608
2624
|
* renegotiation and will continue the process. To forbid renegotiation
|
2609
|
-
* and to cancel the process, an
|
2625
|
+
* and to cancel the process, raise an exception within the callback.
|
2610
2626
|
*
|
2611
2627
|
* === Disable client renegotiation
|
2612
2628
|
*
|
@@ -2614,13 +2630,11 @@ Init_ossl_ssl(void)
|
|
2614
2630
|
* renegotiation entirely. You may use a callback as follows to implement
|
2615
2631
|
* this feature:
|
2616
2632
|
*
|
2617
|
-
* num_handshakes = 0
|
2618
2633
|
* ctx.renegotiation_cb = lambda do |ssl|
|
2619
|
-
*
|
2620
|
-
* raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
|
2634
|
+
* raise RuntimeError, "Client renegotiation disabled"
|
2621
2635
|
* end
|
2622
2636
|
*/
|
2623
|
-
rb_attr(cSSLContext,
|
2637
|
+
rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
|
2624
2638
|
#ifndef OPENSSL_NO_NEXTPROTONEG
|
2625
2639
|
/*
|
2626
2640
|
* An Enumerable of Strings. Each String represents a protocol to be
|
@@ -2633,7 +2647,7 @@ Init_ossl_ssl(void)
|
|
2633
2647
|
*
|
2634
2648
|
* ctx.npn_protocols = ["http/1.1", "spdy/2"]
|
2635
2649
|
*/
|
2636
|
-
rb_attr(cSSLContext,
|
2650
|
+
rb_attr(cSSLContext, rb_intern_const("npn_protocols"), 1, 1, Qfalse);
|
2637
2651
|
/*
|
2638
2652
|
* A callback invoked on the client side when the client needs to select
|
2639
2653
|
* a protocol from the list sent by the server. Supported in OpenSSL 1.0.1
|
@@ -2650,10 +2664,9 @@ Init_ossl_ssl(void)
|
|
2650
2664
|
* protocols.first
|
2651
2665
|
* end
|
2652
2666
|
*/
|
2653
|
-
rb_attr(cSSLContext,
|
2667
|
+
rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse);
|
2654
2668
|
#endif
|
2655
2669
|
|
2656
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2657
2670
|
/*
|
2658
2671
|
* An Enumerable of Strings. Each String represents a protocol to be
|
2659
2672
|
* advertised as the list of supported protocols for Application-Layer
|
@@ -2665,7 +2678,7 @@ Init_ossl_ssl(void)
|
|
2665
2678
|
*
|
2666
2679
|
* ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"]
|
2667
2680
|
*/
|
2668
|
-
rb_attr(cSSLContext,
|
2681
|
+
rb_attr(cSSLContext, rb_intern_const("alpn_protocols"), 1, 1, Qfalse);
|
2669
2682
|
/*
|
2670
2683
|
* A callback invoked on the server side when the server needs to select
|
2671
2684
|
* a protocol from the list sent by the client. Supported in OpenSSL 1.0.2
|
@@ -2682,8 +2695,7 @@ Init_ossl_ssl(void)
|
|
2682
2695
|
* protocols.first
|
2683
2696
|
* end
|
2684
2697
|
*/
|
2685
|
-
rb_attr(cSSLContext,
|
2686
|
-
#endif
|
2698
|
+
rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
|
2687
2699
|
|
2688
2700
|
rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
|
2689
2701
|
rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
|
@@ -2691,6 +2703,9 @@ Init_ossl_ssl(void)
|
|
2691
2703
|
ossl_sslctx_set_minmax_proto_version, 2);
|
2692
2704
|
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
|
2693
2705
|
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
|
2706
|
+
#ifndef OPENSSL_NO_DH
|
2707
|
+
rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
|
2708
|
+
#endif
|
2694
2709
|
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
|
2695
2710
|
rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
|
2696
2711
|
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
|
@@ -2795,12 +2810,10 @@ Init_ossl_ssl(void)
|
|
2795
2810
|
rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
|
2796
2811
|
/* #hostname is defined in lib/openssl/ssl.rb */
|
2797
2812
|
rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
|
2798
|
-
|
2813
|
+
rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0);
|
2814
|
+
rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
|
2799
2815
|
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
|
2800
|
-
# endif
|
2801
|
-
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2802
2816
|
rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
|
2803
|
-
# endif
|
2804
2817
|
# ifndef OPENSSL_NO_NEXTPROTONEG
|
2805
2818
|
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
|
2806
2819
|
# endif
|
@@ -2812,12 +2825,23 @@ Init_ossl_ssl(void)
|
|
2812
2825
|
rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
|
2813
2826
|
|
2814
2827
|
rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL));
|
2828
|
+
#ifdef SSL_OP_CLEANSE_PLAINTEXT /* OpenSSL 3.0 */
|
2829
|
+
rb_define_const(mSSL, "OP_CLEANSE_PLAINTEXT", ULONG2NUM(SSL_OP_CLEANSE_PLAINTEXT));
|
2830
|
+
#endif
|
2815
2831
|
rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
|
2816
|
-
#ifdef
|
2817
|
-
rb_define_const(mSSL, "
|
2832
|
+
#ifdef SSL_OP_ENABLE_KTLS /* OpenSSL 3.0 */
|
2833
|
+
rb_define_const(mSSL, "OP_ENABLE_KTLS", ULONG2NUM(SSL_OP_ENABLE_KTLS));
|
2818
2834
|
#endif
|
2819
|
-
|
2835
|
+
rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
|
2820
2836
|
rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG));
|
2837
|
+
#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* OpenSSL 3.0 */
|
2838
|
+
rb_define_const(mSSL, "OP_IGNORE_UNEXPECTED_EOF", ULONG2NUM(SSL_OP_IGNORE_UNEXPECTED_EOF));
|
2839
|
+
#endif
|
2840
|
+
#ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION /* OpenSSL 3.0 */
|
2841
|
+
rb_define_const(mSSL, "OP_ALLOW_CLIENT_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_CLIENT_RENEGOTIATION));
|
2842
|
+
#endif
|
2843
|
+
#ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */
|
2844
|
+
rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES));
|
2821
2845
|
#endif
|
2822
2846
|
#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
|
2823
2847
|
rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
|
@@ -2830,13 +2854,15 @@ Init_ossl_ssl(void)
|
|
2830
2854
|
#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
|
2831
2855
|
rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
|
2832
2856
|
#endif
|
2833
|
-
|
2834
|
-
rb_define_const(mSSL, "
|
2835
|
-
#
|
2836
|
-
|
2857
|
+
#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */
|
2858
|
+
rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT));
|
2859
|
+
#endif
|
2860
|
+
#ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */
|
2861
|
+
rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA));
|
2862
|
+
#endif
|
2863
|
+
#ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */
|
2864
|
+
rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY));
|
2837
2865
|
#endif
|
2838
|
-
rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
|
2839
|
-
|
2840
2866
|
rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
|
2841
2867
|
rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
|
2842
2868
|
rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
|
@@ -2844,6 +2870,12 @@ Init_ossl_ssl(void)
|
|
2844
2870
|
#ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
|
2845
2871
|
rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
|
2846
2872
|
#endif
|
2873
|
+
rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
|
2874
|
+
rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
|
2875
|
+
#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
|
2876
|
+
rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
|
2877
|
+
#endif
|
2878
|
+
rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
|
2847
2879
|
|
2848
2880
|
/* SSL_OP_* flags for DTLS */
|
2849
2881
|
#if 0
|
@@ -2908,16 +2940,16 @@ Init_ossl_ssl(void)
|
|
2908
2940
|
#endif
|
2909
2941
|
|
2910
2942
|
|
2911
|
-
sym_exception = ID2SYM(
|
2912
|
-
sym_wait_readable = ID2SYM(
|
2913
|
-
sym_wait_writable = ID2SYM(
|
2943
|
+
sym_exception = ID2SYM(rb_intern_const("exception"));
|
2944
|
+
sym_wait_readable = ID2SYM(rb_intern_const("wait_readable"));
|
2945
|
+
sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
|
2914
2946
|
|
2915
|
-
id_tmp_dh_callback =
|
2916
|
-
|
2917
|
-
|
2947
|
+
id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
|
2948
|
+
id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
|
2949
|
+
id_each = rb_intern_const("each");
|
2918
2950
|
|
2919
2951
|
#define DefIVarID(name) do \
|
2920
|
-
id_i_##name =
|
2952
|
+
id_i_##name = rb_intern_const("@"#name); while (0)
|
2921
2953
|
|
2922
2954
|
DefIVarID(cert_store);
|
2923
2955
|
DefIVarID(ca_file);
|
@@ -2931,7 +2963,6 @@ Init_ossl_ssl(void)
|
|
2931
2963
|
DefIVarID(key);
|
2932
2964
|
DefIVarID(extra_chain_cert);
|
2933
2965
|
DefIVarID(client_cert_cb);
|
2934
|
-
DefIVarID(tmp_ecdh_callback);
|
2935
2966
|
DefIVarID(timeout);
|
2936
2967
|
DefIVarID(session_id_context);
|
2937
2968
|
DefIVarID(session_get_cb);
|