openssl 2.2.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 +32 -44
- data/History.md +99 -13
- data/ext/openssl/extconf.rb +26 -28
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +26 -45
- data/ext/openssl/ossl.c +59 -46
- data/ext/openssl/ossl.h +20 -6
- data/ext/openssl/ossl_asn1.c +16 -4
- data/ext/openssl/ossl_bn.c +188 -126
- data/ext/openssl/ossl_cipher.c +11 -11
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +9 -9
- data/ext/openssl/ossl_engine.c +16 -15
- data/ext/openssl/ossl_hmac.c +48 -135
- data/ext/openssl/ossl_kdf.c +8 -0
- data/ext/openssl/ossl_ocsp.c +3 -51
- data/ext/openssl/ossl_pkcs12.c +21 -3
- data/ext/openssl/ossl_pkcs7.c +42 -59
- data/ext/openssl/ossl_pkey.c +1102 -191
- data/ext/openssl/ossl_pkey.h +35 -72
- data/ext/openssl/ossl_pkey_dh.c +124 -334
- data/ext/openssl/ossl_pkey_dsa.c +93 -398
- data/ext/openssl/ossl_pkey_ec.c +126 -318
- data/ext/openssl/ossl_pkey_rsa.c +100 -487
- data/ext/openssl/ossl_ssl.c +256 -355
- data/ext/openssl/ossl_ssl_session.c +24 -29
- data/ext/openssl/ossl_ts.c +35 -20
- data/ext/openssl/ossl_x509.c +0 -6
- data/ext/openssl/ossl_x509cert.c +164 -8
- data/ext/openssl/ossl_x509crl.c +10 -7
- data/ext/openssl/ossl_x509ext.c +1 -2
- data/ext/openssl/ossl_x509name.c +9 -2
- data/ext/openssl/ossl_x509req.c +10 -7
- data/ext/openssl/ossl_x509store.c +154 -70
- data/lib/openssl/buffering.rb +9 -0
- data/lib/openssl/hmac.rb +65 -0
- data/lib/openssl/pkey.rb +417 -0
- data/lib/openssl/ssl.rb +7 -7
- data/lib/openssl/version.rb +1 -1
- data/lib/openssl/x509.rb +22 -0
- data/lib/openssl.rb +0 -1
- metadata +5 -77
- data/ext/openssl/ruby_missing.h +0 -24
- data/lib/openssl/config.rb +0 -501
data/ext/openssl/ossl_ssl.c
CHANGED
@@ -38,14 +38,14 @@ VALUE cSSLSocket;
|
|
38
38
|
static VALUE eSSLErrorWaitReadable;
|
39
39
|
static VALUE eSSLErrorWaitWritable;
|
40
40
|
|
41
|
-
static ID id_call, ID_callback_state, id_tmp_dh_callback,
|
41
|
+
static ID id_call, ID_callback_state, id_tmp_dh_callback,
|
42
42
|
id_npn_protocols_encoded, id_each;
|
43
43
|
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
|
44
44
|
|
45
45
|
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
|
46
46
|
id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
|
47
47
|
id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
|
48
|
-
id_i_client_cert_cb,
|
48
|
+
id_i_client_cert_cb, id_i_timeout,
|
49
49
|
id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
|
50
50
|
id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
|
51
51
|
id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
|
@@ -55,9 +55,6 @@ static ID id_i_io, id_i_context, id_i_hostname;
|
|
55
55
|
static int ossl_ssl_ex_vcb_idx;
|
56
56
|
static int ossl_ssl_ex_ptr_idx;
|
57
57
|
static int ossl_sslctx_ex_ptr_idx;
|
58
|
-
#if !defined(HAVE_X509_STORE_UP_REF)
|
59
|
-
static int ossl_sslctx_ex_store_p;
|
60
|
-
#endif
|
61
58
|
|
62
59
|
static void
|
63
60
|
ossl_sslctx_mark(void *ptr)
|
@@ -69,12 +66,7 @@ ossl_sslctx_mark(void *ptr)
|
|
69
66
|
static void
|
70
67
|
ossl_sslctx_free(void *ptr)
|
71
68
|
{
|
72
|
-
|
73
|
-
#if !defined(HAVE_X509_STORE_UP_REF)
|
74
|
-
if (ctx && SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_store_p))
|
75
|
-
ctx->cert_store = NULL;
|
76
|
-
#endif
|
77
|
-
SSL_CTX_free(ctx);
|
69
|
+
SSL_CTX_free(ptr);
|
78
70
|
}
|
79
71
|
|
80
72
|
static const rb_data_type_t ossl_sslctx_type = {
|
@@ -96,7 +88,7 @@ ossl_sslctx_s_alloc(VALUE klass)
|
|
96
88
|
VALUE obj;
|
97
89
|
|
98
90
|
obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
|
99
|
-
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
91
|
+
#if OPENSSL_VERSION_NUMBER >= 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
|
100
92
|
ctx = SSL_CTX_new(TLS_method());
|
101
93
|
#else
|
102
94
|
ctx = SSL_CTX_new(SSLv23_method());
|
@@ -108,14 +100,15 @@ ossl_sslctx_s_alloc(VALUE klass)
|
|
108
100
|
RTYPEDDATA_DATA(obj) = ctx;
|
109
101
|
SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj);
|
110
102
|
|
111
|
-
#if !defined(OPENSSL_NO_EC) &&
|
103
|
+
#if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER < 0x10100000 && \
|
104
|
+
!defined(LIBRESSL_VERSION_NUMBER)
|
112
105
|
/* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
|
113
106
|
* allows to specify multiple curve names and OpenSSL will select
|
114
107
|
* automatically from them. In OpenSSL 1.0.2, the automatic selection has to
|
115
|
-
* be enabled explicitly.
|
116
|
-
* always enabled. To uniform the behavior, we enable the
|
117
|
-
* selection also in 1.0.2. Users can still disable ECDH by
|
118
|
-
* cipher suites by SSLContext#ciphers=. */
|
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=. */
|
119
112
|
if (!SSL_CTX_set_ecdh_auto(ctx, 1))
|
120
113
|
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
121
114
|
#endif
|
@@ -244,8 +237,7 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
|
244
237
|
return 1;
|
245
238
|
}
|
246
239
|
|
247
|
-
#if !defined(OPENSSL_NO_DH)
|
248
|
-
!defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
240
|
+
#if !defined(OPENSSL_NO_DH)
|
249
241
|
struct tmp_dh_callback_args {
|
250
242
|
VALUE ssl_obj;
|
251
243
|
ID id;
|
@@ -254,22 +246,23 @@ struct tmp_dh_callback_args {
|
|
254
246
|
int keylength;
|
255
247
|
};
|
256
248
|
|
257
|
-
static
|
258
|
-
ossl_call_tmp_dh_callback(
|
249
|
+
static VALUE
|
250
|
+
ossl_call_tmp_dh_callback(VALUE arg)
|
259
251
|
{
|
252
|
+
struct tmp_dh_callback_args *args = (struct tmp_dh_callback_args *)arg;
|
260
253
|
VALUE cb, dh;
|
261
254
|
EVP_PKEY *pkey;
|
262
255
|
|
263
256
|
cb = rb_funcall(args->ssl_obj, args->id, 0);
|
264
257
|
if (NIL_P(cb))
|
265
|
-
return NULL;
|
258
|
+
return (VALUE)NULL;
|
266
259
|
dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
|
267
260
|
INT2NUM(args->keylength));
|
268
261
|
pkey = GetPKeyPtr(dh);
|
269
262
|
if (EVP_PKEY_base_id(pkey) != args->type)
|
270
|
-
return NULL;
|
263
|
+
return (VALUE)NULL;
|
271
264
|
|
272
|
-
return pkey;
|
265
|
+
return (VALUE)pkey;
|
273
266
|
}
|
274
267
|
#endif
|
275
268
|
|
@@ -289,7 +282,7 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
|
289
282
|
args.keylength = keylength;
|
290
283
|
args.type = EVP_PKEY_DH;
|
291
284
|
|
292
|
-
pkey = (EVP_PKEY *)rb_protect(
|
285
|
+
pkey = (EVP_PKEY *)rb_protect(ossl_call_tmp_dh_callback,
|
293
286
|
(VALUE)&args, &state);
|
294
287
|
if (state) {
|
295
288
|
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
@@ -302,35 +295,6 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
|
302
295
|
}
|
303
296
|
#endif /* OPENSSL_NO_DH */
|
304
297
|
|
305
|
-
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
306
|
-
static EC_KEY *
|
307
|
-
ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
|
308
|
-
{
|
309
|
-
VALUE rb_ssl;
|
310
|
-
EVP_PKEY *pkey;
|
311
|
-
struct tmp_dh_callback_args args;
|
312
|
-
int state;
|
313
|
-
|
314
|
-
rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
315
|
-
args.ssl_obj = rb_ssl;
|
316
|
-
args.id = id_tmp_ecdh_callback;
|
317
|
-
args.is_export = is_export;
|
318
|
-
args.keylength = keylength;
|
319
|
-
args.type = EVP_PKEY_EC;
|
320
|
-
|
321
|
-
pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
|
322
|
-
(VALUE)&args, &state);
|
323
|
-
if (state) {
|
324
|
-
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
325
|
-
return NULL;
|
326
|
-
}
|
327
|
-
if (!pkey)
|
328
|
-
return NULL;
|
329
|
-
|
330
|
-
return EVP_PKEY_get0_EC_KEY(pkey);
|
331
|
-
}
|
332
|
-
#endif
|
333
|
-
|
334
298
|
static VALUE
|
335
299
|
call_verify_certificate_identity(VALUE ctx_v)
|
336
300
|
{
|
@@ -400,7 +364,7 @@ ossl_call_session_get_cb(VALUE ary)
|
|
400
364
|
}
|
401
365
|
|
402
366
|
static SSL_SESSION *
|
403
|
-
#if
|
367
|
+
#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
|
404
368
|
ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
|
405
369
|
#else
|
406
370
|
ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
|
@@ -609,8 +573,6 @@ ssl_renegotiation_cb(const SSL *ssl)
|
|
609
573
|
rb_funcallv(cb, id_call, 1, &ssl_obj);
|
610
574
|
}
|
611
575
|
|
612
|
-
#if !defined(OPENSSL_NO_NEXTPROTONEG) || \
|
613
|
-
defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
|
614
576
|
static VALUE
|
615
577
|
ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
|
616
578
|
{
|
@@ -692,7 +654,6 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
|
|
692
654
|
|
693
655
|
return SSL_TLSEXT_ERR_OK;
|
694
656
|
}
|
695
|
-
#endif
|
696
657
|
|
697
658
|
#ifndef OPENSSL_NO_NEXTPROTONEG
|
698
659
|
static int
|
@@ -721,7 +682,6 @@ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
|
|
721
682
|
}
|
722
683
|
#endif
|
723
684
|
|
724
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
725
685
|
static int
|
726
686
|
ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
727
687
|
const unsigned char *in, unsigned int inlen, void *arg)
|
@@ -733,7 +693,6 @@ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
|
733
693
|
|
734
694
|
return ssl_npn_select_cb_common(ssl, cb, out, outlen, in, inlen);
|
735
695
|
}
|
736
|
-
#endif
|
737
696
|
|
738
697
|
/* This function may serve as the entry point to support further callbacks. */
|
739
698
|
static void
|
@@ -810,26 +769,6 @@ ossl_sslctx_setup(VALUE self)
|
|
810
769
|
SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
|
811
770
|
#endif
|
812
771
|
|
813
|
-
#if !defined(OPENSSL_NO_EC)
|
814
|
-
/* We added SSLContext#tmp_ecdh_callback= in Ruby 2.3.0,
|
815
|
-
* but SSL_CTX_set_tmp_ecdh_callback() was removed in OpenSSL 1.1.0. */
|
816
|
-
if (RTEST(rb_attr_get(self, id_i_tmp_ecdh_callback))) {
|
817
|
-
# if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
818
|
-
rb_warn("#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
|
819
|
-
SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
|
820
|
-
# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
|
821
|
-
/* tmp_ecdh_callback and ecdh_auto conflict; OpenSSL ignores
|
822
|
-
* tmp_ecdh_callback. So disable ecdh_auto. */
|
823
|
-
if (!SSL_CTX_set_ecdh_auto(ctx, 0))
|
824
|
-
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
825
|
-
# endif
|
826
|
-
# else
|
827
|
-
ossl_raise(eSSLError, "OpenSSL does not support tmp_ecdh_callback; "
|
828
|
-
"use #ecdh_curves= instead");
|
829
|
-
# endif
|
830
|
-
}
|
831
|
-
#endif /* OPENSSL_NO_EC */
|
832
|
-
|
833
772
|
#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
|
834
773
|
SSL_CTX_set_post_handshake_auth(ctx, 1);
|
835
774
|
#endif
|
@@ -838,17 +777,7 @@ ossl_sslctx_setup(VALUE self)
|
|
838
777
|
if (!NIL_P(val)) {
|
839
778
|
X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
|
840
779
|
SSL_CTX_set_cert_store(ctx, store);
|
841
|
-
#if !defined(HAVE_X509_STORE_UP_REF)
|
842
|
-
/*
|
843
|
-
* WORKAROUND:
|
844
|
-
* X509_STORE can count references, but
|
845
|
-
* X509_STORE_free() doesn't care it.
|
846
|
-
* So we won't increment it but mark it by ex_data.
|
847
|
-
*/
|
848
|
-
SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
|
849
|
-
#else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
|
850
780
|
X509_STORE_up_ref(store);
|
851
|
-
#endif
|
852
781
|
}
|
853
782
|
|
854
783
|
val = rb_attr_get(self, id_i_extra_chain_cert);
|
@@ -899,10 +828,17 @@ ossl_sslctx_setup(VALUE self)
|
|
899
828
|
ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
|
900
829
|
val = rb_attr_get(self, id_i_ca_path);
|
901
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
|
902
837
|
if(ca_file || ca_path){
|
903
838
|
if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
|
904
839
|
rb_warning("can't set verify locations");
|
905
840
|
}
|
841
|
+
#endif
|
906
842
|
|
907
843
|
val = rb_attr_get(self, id_i_verify_mode);
|
908
844
|
verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
|
@@ -930,7 +866,6 @@ ossl_sslctx_setup(VALUE self)
|
|
930
866
|
}
|
931
867
|
#endif
|
932
868
|
|
933
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
934
869
|
val = rb_attr_get(self, id_i_alpn_protocols);
|
935
870
|
if (!NIL_P(val)) {
|
936
871
|
VALUE rprotos = ssl_encode_npn_protocols(val);
|
@@ -945,7 +880,6 @@ ossl_sslctx_setup(VALUE self)
|
|
945
880
|
SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
|
946
881
|
OSSL_Debug("SSL ALPN select callback added");
|
947
882
|
}
|
948
|
-
#endif
|
949
883
|
|
950
884
|
rb_obj_freeze(self);
|
951
885
|
|
@@ -1067,6 +1001,52 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
|
1067
1001
|
return v;
|
1068
1002
|
}
|
1069
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
|
+
|
1070
1050
|
#if !defined(OPENSSL_NO_EC)
|
1071
1051
|
/*
|
1072
1052
|
* call-seq:
|
@@ -1078,9 +1058,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
|
1078
1058
|
* Extension. For a server, the list is used by OpenSSL to determine the set of
|
1079
1059
|
* shared curves. OpenSSL will pick the most appropriate one from it.
|
1080
1060
|
*
|
1081
|
-
* Note that this works differently with old OpenSSL (<= 1.0.1). Only one curve
|
1082
|
-
* can be set, and this has no effect for TLS clients.
|
1083
|
-
*
|
1084
1061
|
* === Example
|
1085
1062
|
* ctx1 = OpenSSL::SSL::SSLContext.new
|
1086
1063
|
* ctx1.ecdh_curves = "X25519:P-256:P-224"
|
@@ -1104,48 +1081,8 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
|
|
1104
1081
|
GetSSLCTX(self, ctx);
|
1105
1082
|
StringValueCStr(arg);
|
1106
1083
|
|
1107
|
-
#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
|
1108
1084
|
if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
|
1109
1085
|
ossl_raise(eSSLError, NULL);
|
1110
|
-
#else
|
1111
|
-
/* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to
|
1112
|
-
* SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */
|
1113
|
-
{
|
1114
|
-
VALUE curve, splitted;
|
1115
|
-
EC_KEY *ec;
|
1116
|
-
int nid;
|
1117
|
-
|
1118
|
-
splitted = rb_str_split(arg, ":");
|
1119
|
-
if (!RARRAY_LEN(splitted))
|
1120
|
-
ossl_raise(eSSLError, "invalid input format");
|
1121
|
-
curve = RARRAY_AREF(splitted, 0);
|
1122
|
-
StringValueCStr(curve);
|
1123
|
-
|
1124
|
-
/* SSL_CTX_set1_curves_list() accepts NIST names */
|
1125
|
-
nid = EC_curve_nist2nid(RSTRING_PTR(curve));
|
1126
|
-
if (nid == NID_undef)
|
1127
|
-
nid = OBJ_txt2nid(RSTRING_PTR(curve));
|
1128
|
-
if (nid == NID_undef)
|
1129
|
-
ossl_raise(eSSLError, "unknown curve name");
|
1130
|
-
|
1131
|
-
ec = EC_KEY_new_by_curve_name(nid);
|
1132
|
-
if (!ec)
|
1133
|
-
ossl_raise(eSSLError, NULL);
|
1134
|
-
EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
|
1135
|
-
if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
|
1136
|
-
EC_KEY_free(ec);
|
1137
|
-
ossl_raise(eSSLError, "SSL_CTX_set_tmp_ecdh");
|
1138
|
-
}
|
1139
|
-
EC_KEY_free(ec);
|
1140
|
-
# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
|
1141
|
-
/* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto
|
1142
|
-
* is enabled. So disable ecdh_auto. */
|
1143
|
-
if (!SSL_CTX_set_ecdh_auto(ctx, 0))
|
1144
|
-
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
1145
|
-
# endif
|
1146
|
-
}
|
1147
|
-
#endif
|
1148
|
-
|
1149
1086
|
return arg;
|
1150
1087
|
}
|
1151
1088
|
#else
|
@@ -1236,7 +1173,7 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
|
|
1236
1173
|
|
1237
1174
|
/*
|
1238
1175
|
* call-seq:
|
1239
|
-
* ctx.add_certificate(
|
1176
|
+
* ctx.add_certificate(certificate, pkey [, extra_certs]) -> self
|
1240
1177
|
*
|
1241
1178
|
* Adds a certificate to the context. _pkey_ must be a corresponding private
|
1242
1179
|
* key with _certificate_.
|
@@ -1268,10 +1205,6 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
|
|
1268
1205
|
* ecdsa_pkey = ...
|
1269
1206
|
* another_ca_cert = ...
|
1270
1207
|
* ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])
|
1271
|
-
*
|
1272
|
-
* === Note
|
1273
|
-
* OpenSSL before the version 1.0.2 could handle only one extra chain across
|
1274
|
-
* all key types. Calling this method discards the chain set previously.
|
1275
1208
|
*/
|
1276
1209
|
static VALUE
|
1277
1210
|
ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
@@ -1296,7 +1229,7 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
|
1296
1229
|
EVP_PKEY_free(pub_pkey);
|
1297
1230
|
if (!pub_pkey)
|
1298
1231
|
rb_raise(rb_eArgError, "certificate does not contain public key");
|
1299
|
-
if (
|
1232
|
+
if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
|
1300
1233
|
rb_raise(rb_eArgError, "public key mismatch");
|
1301
1234
|
|
1302
1235
|
if (argc >= 3)
|
@@ -1310,34 +1243,9 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
|
|
1310
1243
|
sk_X509_pop_free(extra_chain, X509_free);
|
1311
1244
|
ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
|
1312
1245
|
}
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
|
1317
|
-
sk_X509_pop_free(extra_chain, X509_free);
|
1318
|
-
ossl_raise(eSSLError, "SSL_CTX_set0_chain");
|
1319
|
-
}
|
1320
|
-
#else
|
1321
|
-
STACK_OF(X509) *orig_extra_chain;
|
1322
|
-
X509 *x509_tmp;
|
1323
|
-
|
1324
|
-
/* First, clear the existing chain */
|
1325
|
-
SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
|
1326
|
-
if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
|
1327
|
-
rb_warning("SSL_CTX_set0_chain() is not available; " \
|
1328
|
-
"clearing previously set certificate chain");
|
1329
|
-
SSL_CTX_clear_extra_chain_certs(ctx);
|
1330
|
-
}
|
1331
|
-
while ((x509_tmp = sk_X509_shift(extra_chain))) {
|
1332
|
-
/* Transfers ownership */
|
1333
|
-
if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
|
1334
|
-
X509_free(x509_tmp);
|
1335
|
-
sk_X509_pop_free(extra_chain, X509_free);
|
1336
|
-
ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert");
|
1337
|
-
}
|
1338
|
-
}
|
1339
|
-
sk_X509_free(extra_chain);
|
1340
|
-
#endif
|
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");
|
1341
1249
|
}
|
1342
1250
|
return self;
|
1343
1251
|
}
|
@@ -1535,8 +1443,8 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
|
|
1535
1443
|
static inline int
|
1536
1444
|
ssl_started(SSL *ssl)
|
1537
1445
|
{
|
1538
|
-
/*
|
1539
|
-
return
|
1446
|
+
/* BIO is created through ossl_ssl_setup(), called by #connect or #accept */
|
1447
|
+
return SSL_get_rbio(ssl) != NULL;
|
1540
1448
|
}
|
1541
1449
|
|
1542
1450
|
static void
|
@@ -1567,6 +1475,29 @@ ossl_ssl_s_alloc(VALUE klass)
|
|
1567
1475
|
return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
|
1568
1476
|
}
|
1569
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
|
+
|
1570
1501
|
/*
|
1571
1502
|
* call-seq:
|
1572
1503
|
* SSLSocket.new(io) => aSSLSocket
|
@@ -1603,6 +1534,7 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
|
1603
1534
|
|
1604
1535
|
if (rb_respond_to(io, rb_intern("nonblock=")))
|
1605
1536
|
rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
|
1537
|
+
Check_Type(io, T_FILE);
|
1606
1538
|
rb_ivar_set(self, id_i_io, io);
|
1607
1539
|
|
1608
1540
|
ssl = SSL_new(ctx);
|
@@ -1670,6 +1602,26 @@ no_exception_p(VALUE opts)
|
|
1670
1602
|
return 0;
|
1671
1603
|
}
|
1672
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
|
+
|
1673
1625
|
static VALUE
|
1674
1626
|
ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
1675
1627
|
{
|
@@ -1704,12 +1656,12 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|
1704
1656
|
case SSL_ERROR_WANT_WRITE:
|
1705
1657
|
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1706
1658
|
write_would_block(nonblock);
|
1707
|
-
|
1659
|
+
io_wait_writable(fptr);
|
1708
1660
|
continue;
|
1709
1661
|
case SSL_ERROR_WANT_READ:
|
1710
1662
|
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1711
1663
|
read_would_block(nonblock);
|
1712
|
-
|
1664
|
+
io_wait_readable(fptr);
|
1713
1665
|
continue;
|
1714
1666
|
case SSL_ERROR_SYSCALL:
|
1715
1667
|
#ifdef __APPLE__
|
@@ -1718,7 +1670,9 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|
1718
1670
|
continue;
|
1719
1671
|
#endif
|
1720
1672
|
if (errno) rb_sys_fail(funcname);
|
1721
|
-
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
|
+
|
1722
1676
|
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
1723
1677
|
case SSL_ERROR_SSL:
|
1724
1678
|
err = ERR_peek_last_error();
|
@@ -1731,13 +1685,15 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|
1731
1685
|
if (!verify_msg)
|
1732
1686
|
verify_msg = "(null)";
|
1733
1687
|
ossl_clear_error(); /* let ossl_raise() not append message */
|
1734
|
-
ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s: %s (%s)",
|
1735
|
-
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),
|
1736
1690
|
err_msg, verify_msg);
|
1737
1691
|
}
|
1738
1692
|
#endif
|
1693
|
+
/* fallthrough */
|
1739
1694
|
default:
|
1740
|
-
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));
|
1741
1697
|
}
|
1742
1698
|
}
|
1743
1699
|
|
@@ -1748,8 +1704,7 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|
1748
1704
|
* call-seq:
|
1749
1705
|
* ssl.connect => self
|
1750
1706
|
*
|
1751
|
-
* Initiates an SSL/TLS handshake with a server.
|
1752
|
-
* after unencrypted data has been sent over the socket.
|
1707
|
+
* Initiates an SSL/TLS handshake with a server.
|
1753
1708
|
*/
|
1754
1709
|
static VALUE
|
1755
1710
|
ossl_ssl_connect(VALUE self)
|
@@ -1796,8 +1751,7 @@ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
|
|
1796
1751
|
* call-seq:
|
1797
1752
|
* ssl.accept => self
|
1798
1753
|
*
|
1799
|
-
* Waits for a SSL/TLS client to initiate a handshake.
|
1800
|
-
* started after unencrypted data has been sent over the socket.
|
1754
|
+
* Waits for a SSL/TLS client to initiate a handshake.
|
1801
1755
|
*/
|
1802
1756
|
static VALUE
|
1803
1757
|
ossl_ssl_accept(VALUE self)
|
@@ -1844,7 +1798,7 @@ static VALUE
|
|
1844
1798
|
ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
1845
1799
|
{
|
1846
1800
|
SSL *ssl;
|
1847
|
-
int ilen
|
1801
|
+
int ilen;
|
1848
1802
|
VALUE len, str;
|
1849
1803
|
rb_io_t *fptr;
|
1850
1804
|
VALUE io, opts = Qnil;
|
@@ -1854,6 +1808,9 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1854
1808
|
} else {
|
1855
1809
|
rb_scan_args(argc, argv, "11", &len, &str);
|
1856
1810
|
}
|
1811
|
+
GetSSL(self, ssl);
|
1812
|
+
if (!ssl_started(ssl))
|
1813
|
+
rb_raise(eSSLError, "SSL session is not started yet");
|
1857
1814
|
|
1858
1815
|
ilen = NUM2INT(len);
|
1859
1816
|
if (NIL_P(str))
|
@@ -1869,85 +1826,60 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1869
1826
|
if (ilen == 0)
|
1870
1827
|
return str;
|
1871
1828
|
|
1872
|
-
GetSSL(self, ssl);
|
1873
1829
|
io = rb_attr_get(self, id_i_io);
|
1874
1830
|
GetOpenFile(io, fptr);
|
1875
|
-
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
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) {
|
1881
1846
|
rb_str_unlocktmp(str);
|
1882
|
-
|
1883
|
-
|
1847
|
+
if (no_exception_p(opts)) { return sym_wait_writable; }
|
1848
|
+
write_would_block(nonblock);
|
1849
|
+
}
|
1850
|
+
io_wait_writable(fptr);
|
1851
|
+
continue;
|
1852
|
+
case SSL_ERROR_WANT_READ:
|
1853
|
+
if (nonblock) {
|
1884
1854
|
rb_str_unlocktmp(str);
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
}
|
1893
|
-
rb_io_wait_writable(fptr->fd);
|
1894
|
-
continue;
|
1895
|
-
case SSL_ERROR_WANT_READ:
|
1896
|
-
if (nonblock) {
|
1897
|
-
rb_str_unlocktmp(str);
|
1898
|
-
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1899
|
-
read_would_block(nonblock);
|
1900
|
-
}
|
1901
|
-
rb_io_wait_readable(fptr->fd);
|
1902
|
-
continue;
|
1903
|
-
case SSL_ERROR_SYSCALL:
|
1904
|
-
if (!ERR_peek_error()) {
|
1905
|
-
rb_str_unlocktmp(str);
|
1906
|
-
if (errno)
|
1907
|
-
rb_sys_fail(0);
|
1908
|
-
else {
|
1909
|
-
/*
|
1910
|
-
* The underlying BIO returned 0. This is actually a
|
1911
|
-
* protocol error. But unfortunately, not all
|
1912
|
-
* implementations cleanly shutdown the TLS connection
|
1913
|
-
* but just shutdown/close the TCP connection. So report
|
1914
|
-
* EOF for now...
|
1915
|
-
*/
|
1916
|
-
if (no_exception_p(opts)) { return Qnil; }
|
1917
|
-
rb_eof_error();
|
1918
|
-
}
|
1919
|
-
}
|
1920
|
-
/* fall through */
|
1921
|
-
default:
|
1855
|
+
if (no_exception_p(opts)) { return sym_wait_readable; }
|
1856
|
+
read_would_block(nonblock);
|
1857
|
+
}
|
1858
|
+
io_wait_readable(fptr);
|
1859
|
+
continue;
|
1860
|
+
case SSL_ERROR_SYSCALL:
|
1861
|
+
if (!ERR_peek_error()) {
|
1922
1862
|
rb_str_unlocktmp(str);
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
return rb_funcall(io, meth, 3, len, str, opts);
|
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");
|
1942
1881
|
}
|
1943
|
-
#endif
|
1944
|
-
else
|
1945
|
-
return rb_funcall(io, meth, 2, len, str);
|
1946
1882
|
}
|
1947
|
-
|
1948
|
-
end:
|
1949
|
-
rb_str_set_len(str, nread);
|
1950
|
-
return str;
|
1951
1883
|
}
|
1952
1884
|
|
1953
1885
|
/*
|
@@ -1987,77 +1919,55 @@ static VALUE
|
|
1987
1919
|
ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
1988
1920
|
{
|
1989
1921
|
SSL *ssl;
|
1990
|
-
int nwrite = 0;
|
1991
1922
|
rb_io_t *fptr;
|
1992
|
-
int nonblock = opts != Qfalse;
|
1923
|
+
int num, nonblock = opts != Qfalse;
|
1993
1924
|
VALUE tmp, io;
|
1994
1925
|
|
1995
|
-
tmp = rb_str_new_frozen(StringValue(str));
|
1996
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));
|
1997
1931
|
io = rb_attr_get(self, id_i_io);
|
1998
1932
|
GetOpenFile(io, fptr);
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2021
|
-
case SSL_ERROR_SYSCALL:
|
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:
|
2022
1955
|
#ifdef __APPLE__
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
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)
|
1963
|
+
continue;
|
2031
1964
|
#endif
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
1965
|
+
if (errno) rb_sys_fail(0);
|
1966
|
+
/* fallthrough */
|
1967
|
+
default:
|
1968
|
+
ossl_raise(eSSLError, "SSL_write");
|
2036
1969
|
}
|
2037
1970
|
}
|
2038
|
-
else {
|
2039
|
-
ID meth = nonblock ?
|
2040
|
-
rb_intern("write_nonblock") : rb_intern("syswrite");
|
2041
|
-
|
2042
|
-
rb_warning("SSL session is not started yet.");
|
2043
|
-
#if defined(RB_PASS_KEYWORDS)
|
2044
|
-
if (nonblock) {
|
2045
|
-
VALUE argv[2];
|
2046
|
-
argv[0] = str;
|
2047
|
-
argv[1] = opts;
|
2048
|
-
return rb_funcallv_kw(io, meth, 2, argv, RB_PASS_KEYWORDS);
|
2049
|
-
}
|
2050
|
-
#else
|
2051
|
-
if (nonblock) {
|
2052
|
-
return rb_funcall(io, meth, 2, str, opts);
|
2053
|
-
}
|
2054
|
-
#endif
|
2055
|
-
else
|
2056
|
-
return rb_funcall(io, meth, 1, str);
|
2057
|
-
}
|
2058
|
-
|
2059
|
-
end:
|
2060
|
-
return INT2NUM(nwrite);
|
2061
1971
|
}
|
2062
1972
|
|
2063
1973
|
/*
|
@@ -2457,7 +2367,6 @@ ossl_ssl_npn_protocol(VALUE self)
|
|
2457
2367
|
}
|
2458
2368
|
# endif
|
2459
2369
|
|
2460
|
-
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2461
2370
|
/*
|
2462
2371
|
* call-seq:
|
2463
2372
|
* ssl.alpn_protocol => String | nil
|
@@ -2480,9 +2389,7 @@ ossl_ssl_alpn_protocol(VALUE self)
|
|
2480
2389
|
else
|
2481
2390
|
return rb_str_new((const char *) out, outlen);
|
2482
2391
|
}
|
2483
|
-
# endif
|
2484
2392
|
|
2485
|
-
# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
|
2486
2393
|
/*
|
2487
2394
|
* call-seq:
|
2488
2395
|
* ssl.tmp_key => PKey or nil
|
@@ -2500,7 +2407,6 @@ ossl_ssl_tmp_key(VALUE self)
|
|
2500
2407
|
return Qnil;
|
2501
2408
|
return ossl_pkey_new(key);
|
2502
2409
|
}
|
2503
|
-
# endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */
|
2504
2410
|
#endif /* !defined(OPENSSL_NO_SOCK) */
|
2505
2411
|
|
2506
2412
|
void
|
@@ -2525,11 +2431,6 @@ Init_ossl_ssl(void)
|
|
2525
2431
|
ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
|
2526
2432
|
if (ossl_sslctx_ex_ptr_idx < 0)
|
2527
2433
|
ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
|
2528
|
-
#if !defined(HAVE_X509_STORE_UP_REF)
|
2529
|
-
ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_store_p", 0, 0, 0);
|
2530
|
-
if (ossl_sslctx_ex_store_p < 0)
|
2531
|
-
ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
|
2532
|
-
#endif
|
2533
2434
|
|
2534
2435
|
/* Document-module: OpenSSL::SSL
|
2535
2436
|
*
|
@@ -2677,20 +2578,6 @@ Init_ossl_ssl(void)
|
|
2677
2578
|
*/
|
2678
2579
|
rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
|
2679
2580
|
|
2680
|
-
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
2681
|
-
/*
|
2682
|
-
* A callback invoked when ECDH parameters are required.
|
2683
|
-
*
|
2684
|
-
* The callback is invoked with the Session for the key exchange, an
|
2685
|
-
* flag indicating the use of an export cipher and the keylength
|
2686
|
-
* required.
|
2687
|
-
*
|
2688
|
-
* The callback is deprecated. This does not work with recent versions of
|
2689
|
-
* OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead.
|
2690
|
-
*/
|
2691
|
-
rb_attr(cSSLContext, rb_intern_const("tmp_ecdh_callback"), 1, 1, Qfalse);
|
2692
|
-
#endif
|
2693
|
-
|
2694
2581
|
/*
|
2695
2582
|
* Sets the context in which a session can be reused. This allows
|
2696
2583
|
* sessions for multiple applications to be distinguished, for example, by
|
@@ -2780,7 +2667,6 @@ Init_ossl_ssl(void)
|
|
2780
2667
|
rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse);
|
2781
2668
|
#endif
|
2782
2669
|
|
2783
|
-
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2784
2670
|
/*
|
2785
2671
|
* An Enumerable of Strings. Each String represents a protocol to be
|
2786
2672
|
* advertised as the list of supported protocols for Application-Layer
|
@@ -2810,7 +2696,6 @@ Init_ossl_ssl(void)
|
|
2810
2696
|
* end
|
2811
2697
|
*/
|
2812
2698
|
rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
|
2813
|
-
#endif
|
2814
2699
|
|
2815
2700
|
rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
|
2816
2701
|
rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
|
@@ -2818,6 +2703,9 @@ Init_ossl_ssl(void)
|
|
2818
2703
|
ossl_sslctx_set_minmax_proto_version, 2);
|
2819
2704
|
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
|
2820
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
|
2821
2709
|
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
|
2822
2710
|
rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
|
2823
2711
|
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
|
@@ -2924,12 +2812,8 @@ Init_ossl_ssl(void)
|
|
2924
2812
|
rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
|
2925
2813
|
rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0);
|
2926
2814
|
rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
|
2927
|
-
# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
|
2928
2815
|
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
|
2929
|
-
# endif
|
2930
|
-
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2931
2816
|
rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
|
2932
|
-
# endif
|
2933
2817
|
# ifndef OPENSSL_NO_NEXTPROTONEG
|
2934
2818
|
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
|
2935
2819
|
# endif
|
@@ -2941,12 +2825,23 @@ Init_ossl_ssl(void)
|
|
2941
2825
|
rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
|
2942
2826
|
|
2943
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
|
2944
2831
|
rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
|
2945
|
-
#ifdef
|
2946
|
-
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));
|
2947
2834
|
#endif
|
2948
|
-
|
2835
|
+
rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
|
2949
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));
|
2950
2845
|
#endif
|
2951
2846
|
#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
|
2952
2847
|
rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
|
@@ -2959,13 +2854,15 @@ Init_ossl_ssl(void)
|
|
2959
2854
|
#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
|
2960
2855
|
rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
|
2961
2856
|
#endif
|
2962
|
-
|
2963
|
-
rb_define_const(mSSL, "
|
2964
|
-
#
|
2965
|
-
|
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));
|
2966
2865
|
#endif
|
2967
|
-
rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
|
2968
|
-
|
2969
2866
|
rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
|
2970
2867
|
rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
|
2971
2868
|
rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
|
@@ -2973,6 +2870,12 @@ Init_ossl_ssl(void)
|
|
2973
2870
|
#ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
|
2974
2871
|
rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
|
2975
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));
|
2976
2879
|
|
2977
2880
|
/* SSL_OP_* flags for DTLS */
|
2978
2881
|
#if 0
|
@@ -3042,7 +2945,6 @@ Init_ossl_ssl(void)
|
|
3042
2945
|
sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
|
3043
2946
|
|
3044
2947
|
id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
|
3045
|
-
id_tmp_ecdh_callback = rb_intern_const("tmp_ecdh_callback");
|
3046
2948
|
id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
|
3047
2949
|
id_each = rb_intern_const("each");
|
3048
2950
|
|
@@ -3061,7 +2963,6 @@ Init_ossl_ssl(void)
|
|
3061
2963
|
DefIVarID(key);
|
3062
2964
|
DefIVarID(extra_chain_cert);
|
3063
2965
|
DefIVarID(client_cert_cb);
|
3064
|
-
DefIVarID(tmp_ecdh_callback);
|
3065
2966
|
DefIVarID(timeout);
|
3066
2967
|
DefIVarID(session_id_context);
|
3067
2968
|
DefIVarID(session_get_cb);
|