rubysl-openssl 2.10 → 2.11
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 +5 -5
- data/ext/rubysl/openssl/deprecation.rb +7 -3
- data/ext/rubysl/openssl/extconf.rb +148 -103
- data/ext/rubysl/openssl/openssl_missing.c +94 -275
- data/ext/rubysl/openssl/openssl_missing.h +167 -98
- data/ext/rubysl/openssl/ossl.c +266 -212
- data/ext/rubysl/openssl/ossl.h +27 -89
- data/ext/rubysl/openssl/ossl_asn1.c +157 -221
- data/ext/rubysl/openssl/ossl_asn1.h +11 -3
- data/ext/rubysl/openssl/ossl_bio.c +10 -40
- data/ext/rubysl/openssl/ossl_bio.h +1 -2
- data/ext/rubysl/openssl/ossl_bn.c +144 -100
- data/ext/rubysl/openssl/ossl_bn.h +3 -1
- data/ext/rubysl/openssl/ossl_cipher.c +270 -195
- data/ext/rubysl/openssl/ossl_config.c +7 -1
- data/ext/rubysl/openssl/ossl_config.h +0 -1
- data/ext/rubysl/openssl/ossl_digest.c +40 -29
- data/ext/rubysl/openssl/ossl_engine.c +23 -62
- data/ext/rubysl/openssl/ossl_hmac.c +82 -55
- data/ext/rubysl/openssl/ossl_ns_spki.c +22 -22
- data/ext/rubysl/openssl/ossl_ocsp.c +894 -144
- data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs12.c +47 -19
- data/ext/rubysl/openssl/ossl_pkcs5.c +7 -15
- data/ext/rubysl/openssl/ossl_pkcs7.c +38 -15
- data/ext/rubysl/openssl/ossl_pkey.c +151 -99
- data/ext/rubysl/openssl/ossl_pkey.h +123 -29
- data/ext/rubysl/openssl/ossl_pkey_dh.c +143 -92
- data/ext/rubysl/openssl/ossl_pkey_dsa.c +149 -104
- data/ext/rubysl/openssl/ossl_pkey_ec.c +646 -524
- data/ext/rubysl/openssl/ossl_pkey_rsa.c +180 -121
- data/ext/rubysl/openssl/ossl_rand.c +25 -21
- data/ext/rubysl/openssl/ossl_ssl.c +795 -413
- data/ext/rubysl/openssl/ossl_ssl.h +3 -0
- data/ext/rubysl/openssl/ossl_ssl_session.c +83 -77
- data/ext/rubysl/openssl/ossl_version.h +1 -1
- data/ext/rubysl/openssl/ossl_x509.c +92 -8
- data/ext/rubysl/openssl/ossl_x509.h +14 -5
- data/ext/rubysl/openssl/ossl_x509attr.c +77 -41
- data/ext/rubysl/openssl/ossl_x509cert.c +45 -46
- data/ext/rubysl/openssl/ossl_x509crl.c +51 -57
- data/ext/rubysl/openssl/ossl_x509ext.c +39 -33
- data/ext/rubysl/openssl/ossl_x509name.c +68 -45
- data/ext/rubysl/openssl/ossl_x509req.c +32 -38
- data/ext/rubysl/openssl/ossl_x509revoked.c +43 -9
- data/ext/rubysl/openssl/ossl_x509store.c +309 -104
- data/ext/rubysl/openssl/ruby_missing.h +8 -6
- data/lib/openssl/buffering.rb +11 -5
- data/lib/openssl/cipher.rb +23 -15
- data/lib/openssl/digest.rb +7 -10
- data/lib/openssl/pkey.rb +15 -8
- data/lib/openssl/ssl.rb +81 -105
- data/lib/rubysl/openssl.rb +1 -4
- data/lib/rubysl/openssl/version.rb +1 -1
- metadata +3 -4
@@ -41,13 +41,13 @@ ossl_rand_seed(VALUE self, VALUE str)
|
|
41
41
|
* The +entropy+ argument is (the lower bound of) an estimate of how much
|
42
42
|
* randomness is contained in +str+, measured in bytes.
|
43
43
|
*
|
44
|
-
*
|
44
|
+
* === Example
|
45
45
|
*
|
46
46
|
* pid = $$
|
47
47
|
* now = Time.now
|
48
48
|
* ary = [now.to_i, now.nsec, 1000, pid]
|
49
|
-
* OpenSSL::Random.add(ary.join
|
50
|
-
* OpenSSL::Random.seed(ary.join
|
49
|
+
* OpenSSL::Random.add(ary.join, 0.0)
|
50
|
+
* OpenSSL::Random.seed(ary.join)
|
51
51
|
*/
|
52
52
|
static VALUE
|
53
53
|
ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
|
@@ -67,9 +67,9 @@ ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
|
|
67
67
|
static VALUE
|
68
68
|
ossl_rand_load_file(VALUE self, VALUE filename)
|
69
69
|
{
|
70
|
-
|
70
|
+
rb_check_safe_obj(filename);
|
71
71
|
|
72
|
-
if(!RAND_load_file(
|
72
|
+
if(!RAND_load_file(StringValueCStr(filename), -1)) {
|
73
73
|
ossl_raise(eRandomError, NULL);
|
74
74
|
}
|
75
75
|
return Qtrue;
|
@@ -86,8 +86,9 @@ ossl_rand_load_file(VALUE self, VALUE filename)
|
|
86
86
|
static VALUE
|
87
87
|
ossl_rand_write_file(VALUE self, VALUE filename)
|
88
88
|
{
|
89
|
-
|
90
|
-
|
89
|
+
rb_check_safe_obj(filename);
|
90
|
+
|
91
|
+
if (RAND_write_file(StringValueCStr(filename)) == -1) {
|
91
92
|
ossl_raise(eRandomError, NULL);
|
92
93
|
}
|
93
94
|
return Qtrue;
|
@@ -100,10 +101,10 @@ ossl_rand_write_file(VALUE self, VALUE filename)
|
|
100
101
|
* Generates +string+ with +length+ number of cryptographically strong
|
101
102
|
* pseudo-random bytes.
|
102
103
|
*
|
103
|
-
*
|
104
|
+
* === Example
|
104
105
|
*
|
105
106
|
* OpenSSL::Random.random_bytes(12)
|
106
|
-
*
|
107
|
+
* #=> "..."
|
107
108
|
*/
|
108
109
|
static VALUE
|
109
110
|
ossl_rand_bytes(VALUE self, VALUE len)
|
@@ -114,10 +115,8 @@ ossl_rand_bytes(VALUE self, VALUE len)
|
|
114
115
|
|
115
116
|
str = rb_str_new(0, n);
|
116
117
|
ret = RAND_bytes((unsigned char *)RSTRING_PTR(str), n);
|
117
|
-
if (ret == 0){
|
118
|
-
|
119
|
-
ERR_error_string_n(ERR_get_error(), buf, 256);
|
120
|
-
ossl_raise(eRandomError, "RAND_bytes error: %s", buf);
|
118
|
+
if (ret == 0) {
|
119
|
+
ossl_raise(eRandomError, "RAND_bytes");
|
121
120
|
} else if (ret == -1) {
|
122
121
|
ossl_raise(eRandomError, "RAND_bytes is not supported");
|
123
122
|
}
|
@@ -125,6 +124,7 @@ ossl_rand_bytes(VALUE self, VALUE len)
|
|
125
124
|
return str;
|
126
125
|
}
|
127
126
|
|
127
|
+
#if defined(HAVE_RAND_PSEUDO_BYTES)
|
128
128
|
/*
|
129
129
|
* call-seq:
|
130
130
|
* pseudo_bytes(length) -> string
|
@@ -134,10 +134,10 @@ ossl_rand_bytes(VALUE self, VALUE len)
|
|
134
134
|
* Pseudo-random byte sequences generated by ::pseudo_bytes will be unique if
|
135
135
|
* they are of sufficient length, but are not necessarily unpredictable.
|
136
136
|
*
|
137
|
-
*
|
137
|
+
* === Example
|
138
138
|
*
|
139
139
|
* OpenSSL::Random.pseudo_bytes(12)
|
140
|
-
*
|
140
|
+
* #=> "..."
|
141
141
|
*/
|
142
142
|
static VALUE
|
143
143
|
ossl_rand_pseudo_bytes(VALUE self, VALUE len)
|
@@ -146,12 +146,13 @@ ossl_rand_pseudo_bytes(VALUE self, VALUE len)
|
|
146
146
|
int n = NUM2INT(len);
|
147
147
|
|
148
148
|
str = rb_str_new(0, n);
|
149
|
-
if (
|
149
|
+
if (RAND_pseudo_bytes((unsigned char *)RSTRING_PTR(str), n) < 1) {
|
150
150
|
ossl_raise(eRandomError, NULL);
|
151
151
|
}
|
152
152
|
|
153
153
|
return str;
|
154
154
|
}
|
155
|
+
#endif
|
155
156
|
|
156
157
|
#ifdef HAVE_RAND_EGD
|
157
158
|
/*
|
@@ -163,9 +164,9 @@ ossl_rand_pseudo_bytes(VALUE self, VALUE len)
|
|
163
164
|
static VALUE
|
164
165
|
ossl_rand_egd(VALUE self, VALUE filename)
|
165
166
|
{
|
166
|
-
|
167
|
+
rb_check_safe_obj(filename);
|
167
168
|
|
168
|
-
if(
|
169
|
+
if (RAND_egd(StringValueCStr(filename)) == -1) {
|
169
170
|
ossl_raise(eRandomError, NULL);
|
170
171
|
}
|
171
172
|
return Qtrue;
|
@@ -185,9 +186,9 @@ ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
|
|
185
186
|
{
|
186
187
|
int n = NUM2INT(len);
|
187
188
|
|
188
|
-
|
189
|
+
rb_check_safe_obj(filename);
|
189
190
|
|
190
|
-
if (
|
191
|
+
if (RAND_egd_bytes(StringValueCStr(filename), n) == -1) {
|
191
192
|
ossl_raise(eRandomError, NULL);
|
192
193
|
}
|
193
194
|
return Qtrue;
|
@@ -213,7 +214,8 @@ void
|
|
213
214
|
Init_ossl_rand(void)
|
214
215
|
{
|
215
216
|
#if 0
|
216
|
-
mOSSL = rb_define_module("OpenSSL");
|
217
|
+
mOSSL = rb_define_module("OpenSSL");
|
218
|
+
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
217
219
|
#endif
|
218
220
|
|
219
221
|
mRandom = rb_define_module_under(mOSSL, "Random");
|
@@ -225,7 +227,9 @@ Init_ossl_rand(void)
|
|
225
227
|
rb_define_module_function(mRandom, "load_random_file", ossl_rand_load_file, 1);
|
226
228
|
rb_define_module_function(mRandom, "write_random_file", ossl_rand_write_file, 1);
|
227
229
|
rb_define_module_function(mRandom, "random_bytes", ossl_rand_bytes, 1);
|
230
|
+
#if defined(HAVE_RAND_PSEUDO_BYTES)
|
228
231
|
rb_define_module_function(mRandom, "pseudo_bytes", ossl_rand_pseudo_bytes, 1);
|
232
|
+
#endif
|
229
233
|
#ifdef HAVE_RAND_EGD
|
230
234
|
rb_define_module_function(mRandom, "egd", ossl_rand_egd, 1);
|
231
235
|
rb_define_module_function(mRandom, "egd_bytes", ossl_rand_egd_bytes, 2);
|
@@ -11,10 +11,6 @@
|
|
11
11
|
*/
|
12
12
|
#include "ossl.h"
|
13
13
|
|
14
|
-
#if defined(HAVE_UNISTD_H)
|
15
|
-
# include <unistd.h> /* for read(), and write() */
|
16
|
-
#endif
|
17
|
-
|
18
14
|
#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
|
19
15
|
|
20
16
|
#ifdef _WIN32
|
@@ -36,87 +32,55 @@ VALUE cSSLSocket;
|
|
36
32
|
static VALUE eSSLErrorWaitReadable;
|
37
33
|
static VALUE eSSLErrorWaitWritable;
|
38
34
|
|
39
|
-
|
40
|
-
|
41
|
-
#define ossl_sslctx_set_client_ca(o,v) rb_iv_set((o),"@client_ca",(v))
|
42
|
-
#define ossl_sslctx_set_ca_file(o,v) rb_iv_set((o),"@ca_file",(v))
|
43
|
-
#define ossl_sslctx_set_ca_path(o,v) rb_iv_set((o),"@ca_path",(v))
|
44
|
-
#define ossl_sslctx_set_timeout(o,v) rb_iv_set((o),"@timeout",(v))
|
45
|
-
#define ossl_sslctx_set_verify_mode(o,v) rb_iv_set((o),"@verify_mode",(v))
|
46
|
-
#define ossl_sslctx_set_verify_dep(o,v) rb_iv_set((o),"@verify_depth",(v))
|
47
|
-
#define ossl_sslctx_set_verify_cb(o,v) rb_iv_set((o),"@verify_callback",(v))
|
48
|
-
#define ossl_sslctx_set_cert_store(o,v) rb_iv_set((o),"@cert_store",(v))
|
49
|
-
#define ossl_sslctx_set_extra_cert(o,v) rb_iv_set((o),"@extra_chain_cert",(v))
|
50
|
-
#define ossl_sslctx_set_client_cert_cb(o,v) rb_iv_set((o),"@client_cert_cb",(v))
|
51
|
-
#define ossl_sslctx_set_sess_id_ctx(o, v) rb_iv_set((o),"@session_id_context",(v))
|
52
|
-
|
53
|
-
#define ossl_sslctx_get_cert(o) rb_iv_get((o),"@cert")
|
54
|
-
#define ossl_sslctx_get_key(o) rb_iv_get((o),"@key")
|
55
|
-
#define ossl_sslctx_get_client_ca(o) rb_iv_get((o),"@client_ca")
|
56
|
-
#define ossl_sslctx_get_ca_file(o) rb_iv_get((o),"@ca_file")
|
57
|
-
#define ossl_sslctx_get_ca_path(o) rb_iv_get((o),"@ca_path")
|
58
|
-
#define ossl_sslctx_get_timeout(o) rb_iv_get((o),"@timeout")
|
59
|
-
#define ossl_sslctx_get_verify_mode(o) rb_iv_get((o),"@verify_mode")
|
60
|
-
#define ossl_sslctx_get_verify_dep(o) rb_iv_get((o),"@verify_depth")
|
61
|
-
#define ossl_sslctx_get_verify_cb(o) rb_iv_get((o),"@verify_callback")
|
62
|
-
#define ossl_sslctx_get_cert_store(o) rb_iv_get((o),"@cert_store")
|
63
|
-
#define ossl_sslctx_get_extra_cert(o) rb_iv_get((o),"@extra_chain_cert")
|
64
|
-
#define ossl_sslctx_get_client_cert_cb(o) rb_iv_get((o),"@client_cert_cb")
|
65
|
-
#define ossl_sslctx_get_tmp_ecdh_cb(o) rb_iv_get((o),"@tmp_ecdh_callback")
|
66
|
-
#define ossl_sslctx_get_sess_id_ctx(o) rb_iv_get((o),"@session_id_context")
|
67
|
-
|
68
|
-
#define ossl_ssl_get_io(o) rb_iv_get((o),"@io")
|
69
|
-
#define ossl_ssl_get_ctx(o) rb_iv_get((o),"@context")
|
70
|
-
#define ossl_ssl_get_x509(o) rb_iv_get((o),"@x509")
|
71
|
-
#define ossl_ssl_get_key(o) rb_iv_get((o),"@key")
|
72
|
-
|
73
|
-
#define ossl_ssl_set_x509(o,v) rb_iv_set((o),"@x509",(v))
|
74
|
-
#define ossl_ssl_set_key(o,v) rb_iv_set((o),"@key",(v))
|
75
|
-
#define ossl_ssl_set_tmp_dh(o,v) rb_iv_set((o),"@tmp_dh",(v))
|
76
|
-
#define ossl_ssl_set_tmp_ecdh(o,v) rb_iv_set((o),"@tmp_ecdh",(v))
|
77
|
-
|
78
|
-
static ID ID_callback_state;
|
79
|
-
|
35
|
+
static ID ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
|
36
|
+
id_npn_protocols_encoded;
|
80
37
|
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
|
81
38
|
|
39
|
+
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
|
40
|
+
id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
|
41
|
+
id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
|
42
|
+
id_i_client_cert_cb, id_i_tmp_ecdh_callback, id_i_timeout,
|
43
|
+
id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
|
44
|
+
id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
|
45
|
+
id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
|
46
|
+
id_i_verify_hostname;
|
47
|
+
static ID id_i_io, id_i_context, id_i_hostname;
|
48
|
+
|
82
49
|
/*
|
83
50
|
* SSLContext class
|
84
51
|
*/
|
85
52
|
static const struct {
|
86
53
|
const char *name;
|
87
|
-
SSL_METHOD *(*func)(void);
|
54
|
+
SSL_METHOD *(*func)(void); /* FIXME: constify when dropping 0.9.8 */
|
55
|
+
int version;
|
88
56
|
} ossl_ssl_method_tab[] = {
|
89
|
-
#
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
#
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
57
|
+
#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
|
58
|
+
#define OSSL_SSL_METHOD_ENTRY(name, version) \
|
59
|
+
{ #name, (SSL_METHOD *(*)(void))TLS_method, version }, \
|
60
|
+
{ #name"_server", (SSL_METHOD *(*)(void))TLS_server_method, version }, \
|
61
|
+
{ #name"_client", (SSL_METHOD *(*)(void))TLS_client_method, version }
|
62
|
+
#else
|
63
|
+
#define OSSL_SSL_METHOD_ENTRY(name, version) \
|
64
|
+
{ #name, (SSL_METHOD *(*)(void))name##_method, version }, \
|
65
|
+
{ #name"_server", (SSL_METHOD *(*)(void))name##_server_method, version }, \
|
66
|
+
{ #name"_client", (SSL_METHOD *(*)(void))name##_client_method, version }
|
98
67
|
#endif
|
99
|
-
#if defined(
|
100
|
-
|
101
|
-
OSSL_SSL_METHOD_ENTRY(TLSv1_1),
|
102
|
-
OSSL_SSL_METHOD_ENTRY(TLSv1_1_server),
|
103
|
-
OSSL_SSL_METHOD_ENTRY(TLSv1_1_client),
|
68
|
+
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL2_METHOD) && defined(HAVE_SSLV2_METHOD)
|
69
|
+
OSSL_SSL_METHOD_ENTRY(SSLv2, SSL2_VERSION),
|
104
70
|
#endif
|
105
|
-
#if defined(
|
106
|
-
|
107
|
-
OSSL_SSL_METHOD_ENTRY(SSLv2),
|
108
|
-
OSSL_SSL_METHOD_ENTRY(SSLv2_server),
|
109
|
-
OSSL_SSL_METHOD_ENTRY(SSLv2_client),
|
71
|
+
#if !defined(OPENSSL_NO_SSL3) && !defined(OPENSSL_NO_SSL3_METHOD) && defined(HAVE_SSLV3_METHOD)
|
72
|
+
OSSL_SSL_METHOD_ENTRY(SSLv3, SSL3_VERSION),
|
110
73
|
#endif
|
111
|
-
#if defined(
|
112
|
-
|
113
|
-
OSSL_SSL_METHOD_ENTRY(SSLv3),
|
114
|
-
OSSL_SSL_METHOD_ENTRY(SSLv3_server),
|
115
|
-
OSSL_SSL_METHOD_ENTRY(SSLv3_client),
|
74
|
+
#if !defined(OPENSSL_NO_TLS1) && !defined(OPENSSL_NO_TLS1_METHOD)
|
75
|
+
OSSL_SSL_METHOD_ENTRY(TLSv1, TLS1_VERSION),
|
116
76
|
#endif
|
117
|
-
|
118
|
-
OSSL_SSL_METHOD_ENTRY(
|
119
|
-
|
77
|
+
#if !defined(OPENSSL_NO_TLS1_1) && !defined(OPENSSL_NO_TLS1_1_METHOD) && defined(HAVE_TLSV1_1_METHOD)
|
78
|
+
OSSL_SSL_METHOD_ENTRY(TLSv1_1, TLS1_1_VERSION),
|
79
|
+
#endif
|
80
|
+
#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_TLS1_2_METHOD) && defined(HAVE_TLSV1_2_METHOD)
|
81
|
+
OSSL_SSL_METHOD_ENTRY(TLSv1_2, TLS1_2_VERSION),
|
82
|
+
#endif
|
83
|
+
OSSL_SSL_METHOD_ENTRY(SSLv23, 0),
|
120
84
|
#undef OSSL_SSL_METHOD_ENTRY
|
121
85
|
};
|
122
86
|
|
@@ -128,8 +92,10 @@ static void
|
|
128
92
|
ossl_sslctx_free(void *ptr)
|
129
93
|
{
|
130
94
|
SSL_CTX *ctx = ptr;
|
95
|
+
#if !defined(HAVE_X509_STORE_UP_REF)
|
131
96
|
if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1)
|
132
97
|
ctx->cert_store = NULL;
|
98
|
+
#endif
|
133
99
|
SSL_CTX_free(ctx);
|
134
100
|
}
|
135
101
|
|
@@ -145,7 +111,8 @@ static VALUE
|
|
145
111
|
ossl_sslctx_s_alloc(VALUE klass)
|
146
112
|
{
|
147
113
|
SSL_CTX *ctx;
|
148
|
-
long mode = SSL_MODE_ENABLE_PARTIAL_WRITE
|
114
|
+
long mode = SSL_MODE_ENABLE_PARTIAL_WRITE |
|
115
|
+
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
|
149
116
|
VALUE obj;
|
150
117
|
|
151
118
|
#ifdef SSL_MODE_RELEASE_BUFFERS
|
@@ -161,6 +128,18 @@ ossl_sslctx_s_alloc(VALUE klass)
|
|
161
128
|
RTYPEDDATA_DATA(obj) = ctx;
|
162
129
|
SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)obj);
|
163
130
|
|
131
|
+
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
|
132
|
+
/* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
|
133
|
+
* allows to specify multiple curve names and OpenSSL will select
|
134
|
+
* automatically from them. In OpenSSL 1.0.2, the automatic selection has to
|
135
|
+
* be enabled explicitly. But OpenSSL 1.1.0 removed the knob and it is
|
136
|
+
* always enabled. To uniform the behavior, we enable the automatic
|
137
|
+
* selection also in 1.0.2. Users can still disable ECDH by removing ECDH
|
138
|
+
* cipher suites by SSLContext#ciphers=. */
|
139
|
+
if (!SSL_CTX_set_ecdh_auto(ctx, 1))
|
140
|
+
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
141
|
+
#endif
|
142
|
+
|
164
143
|
return obj;
|
165
144
|
}
|
166
145
|
|
@@ -169,146 +148,212 @@ ossl_sslctx_s_alloc(VALUE klass)
|
|
169
148
|
* ctx.ssl_version = :TLSv1
|
170
149
|
* ctx.ssl_version = "SSLv23_client"
|
171
150
|
*
|
151
|
+
* Sets the SSL/TLS protocol version for the context. This forces connections to
|
152
|
+
* use only the specified protocol version.
|
153
|
+
*
|
172
154
|
* You can get a list of valid versions with OpenSSL::SSL::SSLContext::METHODS
|
173
155
|
*/
|
174
156
|
static VALUE
|
175
157
|
ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
|
176
158
|
{
|
177
|
-
|
159
|
+
SSL_CTX *ctx;
|
178
160
|
const char *s;
|
179
161
|
VALUE m = ssl_method;
|
180
162
|
int i;
|
181
163
|
|
182
|
-
|
164
|
+
GetSSLCTX(self, ctx);
|
183
165
|
if (RB_TYPE_P(ssl_method, T_SYMBOL))
|
184
166
|
m = rb_sym2str(ssl_method);
|
185
167
|
s = StringValueCStr(m);
|
186
168
|
for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
|
187
169
|
if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) {
|
188
|
-
|
189
|
-
|
170
|
+
#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
|
171
|
+
int version = ossl_ssl_method_tab[i].version;
|
172
|
+
#endif
|
173
|
+
SSL_METHOD *method = ossl_ssl_method_tab[i].func();
|
174
|
+
|
175
|
+
if (SSL_CTX_set_ssl_version(ctx, method) != 1)
|
176
|
+
ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");
|
177
|
+
|
178
|
+
#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
|
179
|
+
if (!SSL_CTX_set_min_proto_version(ctx, version))
|
180
|
+
ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
|
181
|
+
if (!SSL_CTX_set_max_proto_version(ctx, version))
|
182
|
+
ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
|
183
|
+
#endif
|
184
|
+
return ssl_method;
|
190
185
|
}
|
191
186
|
}
|
192
|
-
if (!method) {
|
193
|
-
ossl_raise(rb_eArgError, "unknown SSL method `%"PRIsVALUE"'.", m);
|
194
|
-
}
|
195
|
-
GetSSLCTX(self, ctx);
|
196
|
-
if (SSL_CTX_set_ssl_version(ctx, method) != 1) {
|
197
|
-
ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");
|
198
|
-
}
|
199
187
|
|
200
|
-
|
188
|
+
ossl_raise(rb_eArgError, "unknown SSL method `%"PRIsVALUE"'.", m);
|
201
189
|
}
|
202
190
|
|
203
191
|
static VALUE
|
204
192
|
ossl_call_client_cert_cb(VALUE obj)
|
205
193
|
{
|
206
|
-
VALUE cb, ary, cert, key;
|
194
|
+
VALUE ctx_obj, cb, ary, cert, key;
|
195
|
+
|
196
|
+
ctx_obj = rb_attr_get(obj, id_i_context);
|
197
|
+
cb = rb_attr_get(ctx_obj, id_i_client_cert_cb);
|
198
|
+
if (NIL_P(cb))
|
199
|
+
return Qnil;
|
207
200
|
|
208
|
-
cb = rb_funcall(obj, rb_intern("client_cert_cb"), 0);
|
209
|
-
if (NIL_P(cb)) return Qfalse;
|
210
201
|
ary = rb_funcall(cb, rb_intern("call"), 1, obj);
|
211
202
|
Check_Type(ary, T_ARRAY);
|
212
203
|
GetX509CertPtr(cert = rb_ary_entry(ary, 0));
|
213
|
-
|
214
|
-
ossl_ssl_set_x509(obj, cert);
|
215
|
-
ossl_ssl_set_key(obj, key);
|
204
|
+
GetPrivPKeyPtr(key = rb_ary_entry(ary, 1));
|
216
205
|
|
217
|
-
return
|
206
|
+
return rb_ary_new3(2, cert, key);
|
218
207
|
}
|
219
208
|
|
220
209
|
static int
|
221
210
|
ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
222
211
|
{
|
223
|
-
VALUE obj,
|
212
|
+
VALUE obj, ret;
|
224
213
|
|
225
214
|
obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
226
|
-
|
227
|
-
if (
|
228
|
-
|
229
|
-
|
215
|
+
ret = rb_protect(ossl_call_client_cert_cb, obj, NULL);
|
216
|
+
if (NIL_P(ret))
|
217
|
+
return 0;
|
218
|
+
|
219
|
+
*x509 = DupX509CertPtr(RARRAY_AREF(ret, 0));
|
220
|
+
*pkey = DupPKeyPtr(RARRAY_AREF(ret, 1));
|
230
221
|
|
231
222
|
return 1;
|
232
223
|
}
|
233
224
|
|
234
|
-
#if !defined(OPENSSL_NO_DH)
|
235
|
-
|
236
|
-
|
225
|
+
#if !defined(OPENSSL_NO_DH) || \
|
226
|
+
!defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
227
|
+
struct tmp_dh_callback_args {
|
228
|
+
VALUE ssl_obj;
|
229
|
+
ID id;
|
230
|
+
int type;
|
231
|
+
int is_export;
|
232
|
+
int keylength;
|
233
|
+
};
|
234
|
+
|
235
|
+
static EVP_PKEY *
|
236
|
+
ossl_call_tmp_dh_callback(struct tmp_dh_callback_args *args)
|
237
237
|
{
|
238
238
|
VALUE cb, dh;
|
239
239
|
EVP_PKEY *pkey;
|
240
240
|
|
241
|
-
cb = rb_funcall(
|
242
|
-
|
243
|
-
|
244
|
-
dh =
|
241
|
+
cb = rb_funcall(args->ssl_obj, args->id, 0);
|
242
|
+
if (NIL_P(cb))
|
243
|
+
return NULL;
|
244
|
+
dh = rb_funcall(cb, rb_intern("call"), 3,
|
245
|
+
args->ssl_obj, INT2NUM(args->is_export), INT2NUM(args->keylength));
|
245
246
|
pkey = GetPKeyPtr(dh);
|
246
|
-
if (
|
247
|
+
if (EVP_PKEY_base_id(pkey) != args->type)
|
248
|
+
return NULL;
|
247
249
|
|
248
|
-
return
|
250
|
+
return pkey;
|
249
251
|
}
|
252
|
+
#endif
|
250
253
|
|
251
|
-
|
254
|
+
#if !defined(OPENSSL_NO_DH)
|
255
|
+
static DH *
|
252
256
|
ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
253
257
|
{
|
254
|
-
VALUE
|
258
|
+
VALUE rb_ssl;
|
259
|
+
EVP_PKEY *pkey;
|
260
|
+
struct tmp_dh_callback_args args;
|
261
|
+
int state;
|
255
262
|
|
256
263
|
rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
264
|
+
args.ssl_obj = rb_ssl;
|
265
|
+
args.id = id_tmp_dh_callback;
|
266
|
+
args.is_export = is_export;
|
267
|
+
args.keylength = keylength;
|
268
|
+
args.type = EVP_PKEY_DH;
|
269
|
+
|
270
|
+
pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
|
271
|
+
(VALUE)&args, &state);
|
272
|
+
if (state) {
|
273
|
+
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
274
|
+
return NULL;
|
275
|
+
}
|
276
|
+
if (!pkey)
|
277
|
+
return NULL;
|
257
278
|
|
258
|
-
|
259
|
-
|
260
|
-
dh = rb_protect(ossl_call_tmp_dh_callback, args, NULL);
|
261
|
-
if (!RTEST(dh)) return NULL;
|
262
|
-
ossl_ssl_set_tmp_dh(rb_ssl, dh);
|
263
|
-
|
264
|
-
return GetPKeyPtr(dh)->pkey.dh;
|
279
|
+
return EVP_PKEY_get0_DH(pkey);
|
265
280
|
}
|
266
281
|
#endif /* OPENSSL_NO_DH */
|
267
282
|
|
268
|
-
#if !defined(OPENSSL_NO_EC)
|
269
|
-
static
|
270
|
-
|
283
|
+
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
284
|
+
static EC_KEY *
|
285
|
+
ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
|
271
286
|
{
|
272
|
-
VALUE
|
287
|
+
VALUE rb_ssl;
|
273
288
|
EVP_PKEY *pkey;
|
289
|
+
struct tmp_dh_callback_args args;
|
290
|
+
int state;
|
274
291
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
292
|
+
rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
293
|
+
args.ssl_obj = rb_ssl;
|
294
|
+
args.id = id_tmp_ecdh_callback;
|
295
|
+
args.is_export = is_export;
|
296
|
+
args.keylength = keylength;
|
297
|
+
args.type = EVP_PKEY_EC;
|
298
|
+
|
299
|
+
pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
|
300
|
+
(VALUE)&args, &state);
|
301
|
+
if (state) {
|
302
|
+
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
303
|
+
return NULL;
|
304
|
+
}
|
305
|
+
if (!pkey)
|
306
|
+
return NULL;
|
281
307
|
|
282
|
-
return
|
308
|
+
return EVP_PKEY_get0_EC_KEY(pkey);
|
283
309
|
}
|
310
|
+
#endif
|
284
311
|
|
285
|
-
static
|
286
|
-
|
312
|
+
static VALUE
|
313
|
+
call_verify_certificate_identity(VALUE ctx_v)
|
287
314
|
{
|
288
|
-
|
289
|
-
|
290
|
-
|
315
|
+
X509_STORE_CTX *ctx = (X509_STORE_CTX *)ctx_v;
|
316
|
+
SSL *ssl;
|
317
|
+
VALUE ssl_obj, hostname, cert_obj;
|
291
318
|
|
292
|
-
|
319
|
+
ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
|
320
|
+
ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
321
|
+
hostname = rb_attr_get(ssl_obj, id_i_hostname);
|
293
322
|
|
294
|
-
|
295
|
-
|
296
|
-
|
323
|
+
if (!RTEST(hostname)) {
|
324
|
+
rb_warning("verify_hostname requires hostname to be set");
|
325
|
+
return Qtrue;
|
326
|
+
}
|
297
327
|
|
298
|
-
|
328
|
+
cert_obj = ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx));
|
329
|
+
return rb_funcall(mSSL, rb_intern("verify_certificate_identity"), 2,
|
330
|
+
cert_obj, hostname);
|
299
331
|
}
|
300
|
-
#endif
|
301
332
|
|
302
333
|
static int
|
303
334
|
ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
304
335
|
{
|
305
|
-
VALUE cb;
|
336
|
+
VALUE cb, ssl_obj, sslctx_obj, verify_hostname, ret;
|
306
337
|
SSL *ssl;
|
338
|
+
int status;
|
307
339
|
|
308
340
|
ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
|
309
341
|
cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx);
|
310
|
-
|
311
|
-
|
342
|
+
ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
343
|
+
sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
|
344
|
+
verify_hostname = rb_attr_get(sslctx_obj, id_i_verify_hostname);
|
345
|
+
|
346
|
+
if (preverify_ok && RTEST(verify_hostname) && !SSL_is_server(ssl) &&
|
347
|
+
!X509_STORE_CTX_get_error_depth(ctx)) {
|
348
|
+
ret = rb_protect(call_verify_certificate_identity, (VALUE)ctx, &status);
|
349
|
+
if (status) {
|
350
|
+
rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
|
351
|
+
return 0;
|
352
|
+
}
|
353
|
+
preverify_ok = ret == Qtrue;
|
354
|
+
}
|
355
|
+
|
356
|
+
return ossl_verify_cb_call(cb, preverify_ok, ctx);
|
312
357
|
}
|
313
358
|
|
314
359
|
static VALUE
|
@@ -327,7 +372,11 @@ ossl_call_session_get_cb(VALUE ary)
|
|
327
372
|
|
328
373
|
/* this method is currently only called for servers (in OpenSSL <= 0.9.8e) */
|
329
374
|
static SSL_SESSION *
|
375
|
+
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
|
376
|
+
ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
|
377
|
+
#else
|
330
378
|
ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
|
379
|
+
#endif
|
331
380
|
{
|
332
381
|
VALUE ary, ssl_obj, ret_obj;
|
333
382
|
SSL_SESSION *sess;
|
@@ -384,7 +433,7 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
|
|
384
433
|
return 1;
|
385
434
|
ssl_obj = (VALUE)ptr;
|
386
435
|
sess_obj = rb_obj_alloc(cSSLSession);
|
387
|
-
|
436
|
+
SSL_SESSION_up_ref(sess);
|
388
437
|
DATA_PTR(sess_obj) = sess;
|
389
438
|
|
390
439
|
ary = rb_ary_new2(2);
|
@@ -414,7 +463,7 @@ ossl_call_session_remove_cb(VALUE ary)
|
|
414
463
|
Check_Type(ary, T_ARRAY);
|
415
464
|
sslctx_obj = rb_ary_entry(ary, 0);
|
416
465
|
|
417
|
-
cb =
|
466
|
+
cb = rb_attr_get(sslctx_obj, id_i_session_remove_cb);
|
418
467
|
if (NIL_P(cb)) return Qnil;
|
419
468
|
|
420
469
|
return rb_funcall(cb, rb_intern("call"), 1, ary);
|
@@ -427,20 +476,27 @@ ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
|
|
427
476
|
void *ptr;
|
428
477
|
int state = 0;
|
429
478
|
|
479
|
+
/*
|
480
|
+
* This callback is also called for all sessions in the internal store
|
481
|
+
* when SSL_CTX_free() is called.
|
482
|
+
*/
|
483
|
+
if (rb_during_gc())
|
484
|
+
return;
|
485
|
+
|
430
486
|
OSSL_Debug("SSL SESSION remove callback entered");
|
431
487
|
|
432
488
|
if ((ptr = SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx)) == NULL)
|
433
489
|
return;
|
434
490
|
sslctx_obj = (VALUE)ptr;
|
435
491
|
sess_obj = rb_obj_alloc(cSSLSession);
|
436
|
-
|
492
|
+
SSL_SESSION_up_ref(sess);
|
437
493
|
DATA_PTR(sess_obj) = sess;
|
438
494
|
|
439
495
|
ary = rb_ary_new2(2);
|
440
496
|
rb_ary_push(ary, sslctx_obj);
|
441
497
|
rb_ary_push(ary, sess_obj);
|
442
498
|
|
443
|
-
rb_protect(
|
499
|
+
rb_protect(ossl_call_session_remove_cb, ary, &state);
|
444
500
|
if (state) {
|
445
501
|
/*
|
446
502
|
the SSL_CTX is frozen, nowhere to save state.
|
@@ -476,9 +532,8 @@ ossl_call_servername_cb(VALUE ary)
|
|
476
532
|
Check_Type(ary, T_ARRAY);
|
477
533
|
ssl_obj = rb_ary_entry(ary, 0);
|
478
534
|
|
479
|
-
sslctx_obj =
|
480
|
-
|
481
|
-
cb = rb_iv_get(sslctx_obj, "@servername_cb");
|
535
|
+
sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
|
536
|
+
cb = rb_attr_get(sslctx_obj, id_i_servername_cb);
|
482
537
|
if (NIL_P(cb)) return Qnil;
|
483
538
|
|
484
539
|
ret_obj = rb_funcall(cb, rb_intern("call"), 1, ary);
|
@@ -490,9 +545,10 @@ ossl_call_servername_cb(VALUE ary)
|
|
490
545
|
GetSSL(ssl_obj, ssl);
|
491
546
|
GetSSLCTX(ret_obj, ctx2);
|
492
547
|
SSL_set_SSL_CTX(ssl, ctx2);
|
493
|
-
|
548
|
+
rb_ivar_set(ssl_obj, id_i_context, ret_obj);
|
494
549
|
} else if (!NIL_P(ret_obj)) {
|
495
|
-
|
550
|
+
ossl_raise(rb_eArgError, "servername_cb must return an "
|
551
|
+
"OpenSSL::SSL::SSLContext object or nil");
|
496
552
|
}
|
497
553
|
|
498
554
|
return ret_obj;
|
@@ -516,7 +572,7 @@ ssl_servername_cb(SSL *ssl, int *ad, void *arg)
|
|
516
572
|
rb_ary_push(ary, ssl_obj);
|
517
573
|
rb_ary_push(ary, rb_str_new2(servername));
|
518
574
|
|
519
|
-
rb_protect(
|
575
|
+
rb_protect(ossl_call_servername_cb, ary, &state);
|
520
576
|
if (state) {
|
521
577
|
rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
|
522
578
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
@@ -536,15 +592,15 @@ ssl_renegotiation_cb(const SSL *ssl)
|
|
536
592
|
ossl_raise(eSSLError, "SSL object could not be retrieved");
|
537
593
|
ssl_obj = (VALUE)ptr;
|
538
594
|
|
539
|
-
sslctx_obj =
|
540
|
-
|
541
|
-
cb = rb_iv_get(sslctx_obj, "@renegotiation_cb");
|
595
|
+
sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
|
596
|
+
cb = rb_attr_get(sslctx_obj, id_i_renegotiation_cb);
|
542
597
|
if (NIL_P(cb)) return;
|
543
598
|
|
544
599
|
(void) rb_funcall(cb, rb_intern("call"), 1, ssl_obj);
|
545
600
|
}
|
546
601
|
|
547
|
-
#if defined(HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB) ||
|
602
|
+
#if defined(HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB) || \
|
603
|
+
defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
|
548
604
|
static VALUE
|
549
605
|
ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
|
550
606
|
{
|
@@ -562,20 +618,25 @@ ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
|
|
562
618
|
static VALUE
|
563
619
|
ssl_encode_npn_protocols(VALUE protocols)
|
564
620
|
{
|
565
|
-
VALUE encoded =
|
621
|
+
VALUE encoded = rb_str_new(NULL, 0);
|
566
622
|
rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded);
|
567
|
-
StringValueCStr(encoded);
|
568
623
|
return encoded;
|
569
624
|
}
|
570
625
|
|
571
|
-
|
572
|
-
|
626
|
+
struct npn_select_cb_common_args {
|
627
|
+
VALUE cb;
|
628
|
+
const unsigned char *in;
|
629
|
+
unsigned inlen;
|
630
|
+
};
|
631
|
+
|
632
|
+
static VALUE
|
633
|
+
npn_select_cb_common_i(VALUE tmp)
|
573
634
|
{
|
574
|
-
|
575
|
-
|
576
|
-
VALUE protocols = rb_ary_new();
|
635
|
+
struct npn_select_cb_common_args *args = (void *)tmp;
|
636
|
+
const unsigned char *in = args->in, *in_end = in + args->inlen;
|
577
637
|
unsigned char l;
|
578
|
-
|
638
|
+
long len;
|
639
|
+
VALUE selected, protocols = rb_ary_new();
|
579
640
|
|
580
641
|
/* assume OpenSSL verifies this format */
|
581
642
|
/* The format is len_1|proto_1|...|len_n|proto_n */
|
@@ -585,24 +646,50 @@ ssl_npn_select_cb_common(VALUE cb, const unsigned char **out, unsigned char *out
|
|
585
646
|
in += l;
|
586
647
|
}
|
587
648
|
|
588
|
-
selected = rb_funcall(cb, rb_intern("call"), 1, protocols);
|
649
|
+
selected = rb_funcall(args->cb, rb_intern("call"), 1, protocols);
|
589
650
|
StringValue(selected);
|
590
651
|
len = RSTRING_LEN(selected);
|
591
652
|
if (len < 1 || len >= 256) {
|
592
653
|
ossl_raise(eSSLError, "Selected protocol name must have length 1..255");
|
593
654
|
}
|
655
|
+
|
656
|
+
return selected;
|
657
|
+
}
|
658
|
+
|
659
|
+
static int
|
660
|
+
ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
|
661
|
+
unsigned char *outlen, const unsigned char *in,
|
662
|
+
unsigned int inlen)
|
663
|
+
{
|
664
|
+
VALUE selected;
|
665
|
+
int status;
|
666
|
+
struct npn_select_cb_common_args args;
|
667
|
+
|
668
|
+
args.cb = cb;
|
669
|
+
args.in = in;
|
670
|
+
args.inlen = inlen;
|
671
|
+
|
672
|
+
selected = rb_protect(npn_select_cb_common_i, (VALUE)&args, &status);
|
673
|
+
if (status) {
|
674
|
+
VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
675
|
+
|
676
|
+
rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
|
677
|
+
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
678
|
+
}
|
679
|
+
|
594
680
|
*out = (unsigned char *)RSTRING_PTR(selected);
|
595
|
-
*outlen = (unsigned char)
|
681
|
+
*outlen = (unsigned char)RSTRING_LEN(selected);
|
596
682
|
|
597
683
|
return SSL_TLSEXT_ERR_OK;
|
598
684
|
}
|
685
|
+
#endif
|
599
686
|
|
600
687
|
#ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
|
601
688
|
static int
|
602
|
-
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
|
689
|
+
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
|
690
|
+
void *arg)
|
603
691
|
{
|
604
|
-
VALUE
|
605
|
-
VALUE protocols = rb_iv_get(sslctx_obj, "@_protocols");
|
692
|
+
VALUE protocols = (VALUE)arg;
|
606
693
|
|
607
694
|
*out = (const unsigned char *) RSTRING_PTR(protocols);
|
608
695
|
*outlen = RSTRING_LENINT(protocols);
|
@@ -611,40 +698,40 @@ ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
|
|
611
698
|
}
|
612
699
|
|
613
700
|
static int
|
614
|
-
ssl_npn_select_cb(SSL *
|
701
|
+
ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
|
702
|
+
const unsigned char *in, unsigned int inlen, void *arg)
|
615
703
|
{
|
616
704
|
VALUE sslctx_obj, cb;
|
617
705
|
|
618
706
|
sslctx_obj = (VALUE) arg;
|
619
|
-
cb =
|
707
|
+
cb = rb_attr_get(sslctx_obj, id_i_npn_select_cb);
|
620
708
|
|
621
|
-
return ssl_npn_select_cb_common(cb, (const unsigned char **)out,
|
709
|
+
return ssl_npn_select_cb_common(ssl, cb, (const unsigned char **)out,
|
710
|
+
outlen, in, inlen);
|
622
711
|
}
|
623
712
|
#endif
|
624
713
|
|
625
714
|
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
626
715
|
static int
|
627
|
-
ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
716
|
+
ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
717
|
+
const unsigned char *in, unsigned int inlen, void *arg)
|
628
718
|
{
|
629
719
|
VALUE sslctx_obj, cb;
|
630
720
|
|
631
721
|
sslctx_obj = (VALUE) arg;
|
632
|
-
cb =
|
722
|
+
cb = rb_attr_get(sslctx_obj, id_i_alpn_select_cb);
|
633
723
|
|
634
|
-
return ssl_npn_select_cb_common(cb, out, outlen, in, inlen);
|
724
|
+
return ssl_npn_select_cb_common(ssl, cb, out, outlen, in, inlen);
|
635
725
|
}
|
636
726
|
#endif
|
637
|
-
#endif /* HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB || HAVE_SSL_CTX_SET_ALPN_SELECT_CB */
|
638
727
|
|
639
|
-
/* This function may serve as the entry point to support further
|
640
|
-
* callbacks. */
|
728
|
+
/* This function may serve as the entry point to support further callbacks. */
|
641
729
|
static void
|
642
730
|
ssl_info_cb(const SSL *ssl, int where, int val)
|
643
731
|
{
|
644
|
-
int
|
732
|
+
int is_server = SSL_is_server((SSL *)ssl);
|
645
733
|
|
646
|
-
if (
|
647
|
-
(state & SSL_ST_ACCEPT)) {
|
734
|
+
if (is_server && where & SSL_CB_HANDSHAKE_START) {
|
648
735
|
ssl_renegotiation_cb(ssl);
|
649
736
|
}
|
650
737
|
}
|
@@ -696,7 +783,6 @@ ossl_sslctx_setup(VALUE self)
|
|
696
783
|
{
|
697
784
|
SSL_CTX *ctx;
|
698
785
|
X509 *cert = NULL, *client_ca = NULL;
|
699
|
-
X509_STORE *store;
|
700
786
|
EVP_PKEY *key = NULL;
|
701
787
|
char *ca_path = NULL, *ca_file = NULL;
|
702
788
|
int verify_mode;
|
@@ -711,34 +797,52 @@ ossl_sslctx_setup(VALUE self)
|
|
711
797
|
#endif
|
712
798
|
|
713
799
|
#if !defined(OPENSSL_NO_EC)
|
714
|
-
|
800
|
+
/* We added SSLContext#tmp_ecdh_callback= in Ruby 2.3.0,
|
801
|
+
* but SSL_CTX_set_tmp_ecdh_callback() was removed in OpenSSL 1.1.0. */
|
802
|
+
if (RTEST(rb_attr_get(self, id_i_tmp_ecdh_callback))) {
|
803
|
+
# if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
804
|
+
rb_warn("#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
|
715
805
|
SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
|
806
|
+
# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
|
807
|
+
/* tmp_ecdh_callback and ecdh_auto conflict; OpenSSL ignores
|
808
|
+
* tmp_ecdh_callback. So disable ecdh_auto. */
|
809
|
+
if (!SSL_CTX_set_ecdh_auto(ctx, 0))
|
810
|
+
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
811
|
+
# endif
|
812
|
+
# else
|
813
|
+
ossl_raise(eSSLError, "OpenSSL does not support tmp_ecdh_callback; "
|
814
|
+
"use #ecdh_curves= instead");
|
815
|
+
# endif
|
716
816
|
}
|
717
|
-
#endif
|
817
|
+
#endif /* OPENSSL_NO_EC */
|
718
818
|
|
719
|
-
val =
|
720
|
-
if(!NIL_P(val)){
|
819
|
+
val = rb_attr_get(self, id_i_cert_store);
|
820
|
+
if (!NIL_P(val)) {
|
821
|
+
X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
|
822
|
+
SSL_CTX_set_cert_store(ctx, store);
|
823
|
+
#if !defined(HAVE_X509_STORE_UP_REF)
|
721
824
|
/*
|
722
825
|
* WORKAROUND:
|
723
826
|
* X509_STORE can count references, but
|
724
827
|
* X509_STORE_free() doesn't care it.
|
725
828
|
* So we won't increment it but mark it by ex_data.
|
726
829
|
*/
|
727
|
-
|
728
|
-
|
729
|
-
|
830
|
+
SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void *)1);
|
831
|
+
#else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
|
832
|
+
X509_STORE_up_ref(store);
|
833
|
+
#endif
|
730
834
|
}
|
731
835
|
|
732
|
-
val =
|
836
|
+
val = rb_attr_get(self, id_i_extra_chain_cert);
|
733
837
|
if(!NIL_P(val)){
|
734
838
|
rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
|
735
839
|
}
|
736
840
|
|
737
841
|
/* private key may be bundled in certificate file. */
|
738
|
-
val =
|
842
|
+
val = rb_attr_get(self, id_i_cert);
|
739
843
|
cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
|
740
|
-
val =
|
741
|
-
key = NIL_P(val) ? NULL :
|
844
|
+
val = rb_attr_get(self, id_i_key);
|
845
|
+
key = NIL_P(val) ? NULL : GetPrivPKeyPtr(val); /* NO DUP NEEDED */
|
742
846
|
if (cert && key) {
|
743
847
|
if (!SSL_CTX_use_certificate(ctx, cert)) {
|
744
848
|
/* Adds a ref => Safe to FREE */
|
@@ -753,7 +857,7 @@ ossl_sslctx_setup(VALUE self)
|
|
753
857
|
}
|
754
858
|
}
|
755
859
|
|
756
|
-
val =
|
860
|
+
val = rb_attr_get(self, id_i_client_ca);
|
757
861
|
if(!NIL_P(val)){
|
758
862
|
if (RB_TYPE_P(val, T_ARRAY)) {
|
759
863
|
for(i = 0; i < RARRAY_LEN(val); i++){
|
@@ -773,48 +877,53 @@ ossl_sslctx_setup(VALUE self)
|
|
773
877
|
}
|
774
878
|
}
|
775
879
|
|
776
|
-
val =
|
777
|
-
ca_file = NIL_P(val) ? NULL :
|
778
|
-
val =
|
779
|
-
ca_path = NIL_P(val) ? NULL :
|
880
|
+
val = rb_attr_get(self, id_i_ca_file);
|
881
|
+
ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
|
882
|
+
val = rb_attr_get(self, id_i_ca_path);
|
883
|
+
ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
|
780
884
|
if(ca_file || ca_path){
|
781
885
|
if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
|
782
886
|
rb_warning("can't set verify locations");
|
783
887
|
}
|
784
888
|
|
785
|
-
val =
|
889
|
+
val = rb_attr_get(self, id_i_verify_mode);
|
786
890
|
verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
|
787
891
|
SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
|
788
|
-
if (RTEST(
|
892
|
+
if (RTEST(rb_attr_get(self, id_i_client_cert_cb)))
|
789
893
|
SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
|
790
894
|
|
791
|
-
val =
|
895
|
+
val = rb_attr_get(self, id_i_timeout);
|
792
896
|
if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));
|
793
897
|
|
794
|
-
val =
|
898
|
+
val = rb_attr_get(self, id_i_verify_depth);
|
795
899
|
if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
|
796
900
|
|
797
901
|
#ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
|
798
|
-
val =
|
902
|
+
val = rb_attr_get(self, id_i_npn_protocols);
|
799
903
|
if (!NIL_P(val)) {
|
800
|
-
|
801
|
-
|
904
|
+
VALUE encoded = ssl_encode_npn_protocols(val);
|
905
|
+
rb_ivar_set(self, id_npn_protocols_encoded, encoded);
|
906
|
+
SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)encoded);
|
802
907
|
OSSL_Debug("SSL NPN advertise callback added");
|
803
908
|
}
|
804
|
-
if (RTEST(
|
909
|
+
if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
|
805
910
|
SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
|
806
911
|
OSSL_Debug("SSL NPN select callback added");
|
807
912
|
}
|
808
913
|
#endif
|
809
914
|
|
810
915
|
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
811
|
-
val =
|
916
|
+
val = rb_attr_get(self, id_i_alpn_protocols);
|
812
917
|
if (!NIL_P(val)) {
|
813
918
|
VALUE rprotos = ssl_encode_npn_protocols(val);
|
814
|
-
|
919
|
+
|
920
|
+
/* returns 0 on success */
|
921
|
+
if (SSL_CTX_set_alpn_protos(ctx, (unsigned char *)RSTRING_PTR(rprotos),
|
922
|
+
RSTRING_LENINT(rprotos)))
|
923
|
+
ossl_raise(eSSLError, "SSL_CTX_set_alpn_protos");
|
815
924
|
OSSL_Debug("SSL ALPN values added");
|
816
925
|
}
|
817
|
-
if (RTEST(
|
926
|
+
if (RTEST(rb_attr_get(self, id_i_alpn_select_cb))) {
|
818
927
|
SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
|
819
928
|
OSSL_Debug("SSL ALPN select callback added");
|
820
929
|
}
|
@@ -822,7 +931,7 @@ ossl_sslctx_setup(VALUE self)
|
|
822
931
|
|
823
932
|
rb_obj_freeze(self);
|
824
933
|
|
825
|
-
val =
|
934
|
+
val = rb_attr_get(self, id_i_session_id_context);
|
826
935
|
if (!NIL_P(val)){
|
827
936
|
StringValue(val);
|
828
937
|
if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
|
@@ -831,21 +940,21 @@ ossl_sslctx_setup(VALUE self)
|
|
831
940
|
}
|
832
941
|
}
|
833
942
|
|
834
|
-
if (RTEST(
|
943
|
+
if (RTEST(rb_attr_get(self, id_i_session_get_cb))) {
|
835
944
|
SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
|
836
945
|
OSSL_Debug("SSL SESSION get callback added");
|
837
946
|
}
|
838
|
-
if (RTEST(
|
947
|
+
if (RTEST(rb_attr_get(self, id_i_session_new_cb))) {
|
839
948
|
SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
|
840
949
|
OSSL_Debug("SSL SESSION new callback added");
|
841
950
|
}
|
842
|
-
if (RTEST(
|
951
|
+
if (RTEST(rb_attr_get(self, id_i_session_remove_cb))) {
|
843
952
|
SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
|
844
953
|
OSSL_Debug("SSL SESSION remove callback added");
|
845
954
|
}
|
846
955
|
|
847
956
|
#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
|
848
|
-
val =
|
957
|
+
val = rb_attr_get(self, id_i_servername_cb);
|
849
958
|
if (!NIL_P(val)) {
|
850
959
|
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
|
851
960
|
OSSL_Debug("SSL TLSEXT servername callback added");
|
@@ -856,7 +965,7 @@ ossl_sslctx_setup(VALUE self)
|
|
856
965
|
}
|
857
966
|
|
858
967
|
static VALUE
|
859
|
-
ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher)
|
968
|
+
ossl_ssl_cipher_to_ary(const SSL_CIPHER *cipher)
|
860
969
|
{
|
861
970
|
VALUE ary;
|
862
971
|
int bits, alg_bits;
|
@@ -865,8 +974,8 @@ ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher)
|
|
865
974
|
rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_name(cipher)));
|
866
975
|
rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_version(cipher)));
|
867
976
|
bits = SSL_CIPHER_get_bits(cipher, &alg_bits);
|
868
|
-
rb_ary_push(ary,
|
869
|
-
rb_ary_push(ary,
|
977
|
+
rb_ary_push(ary, INT2NUM(bits));
|
978
|
+
rb_ary_push(ary, INT2NUM(alg_bits));
|
870
979
|
|
871
980
|
return ary;
|
872
981
|
}
|
@@ -875,24 +984,19 @@ ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher)
|
|
875
984
|
* call-seq:
|
876
985
|
* ctx.ciphers => [[name, version, bits, alg_bits], ...]
|
877
986
|
*
|
878
|
-
* The list of
|
987
|
+
* The list of cipher suites configured for this context.
|
879
988
|
*/
|
880
989
|
static VALUE
|
881
990
|
ossl_sslctx_get_ciphers(VALUE self)
|
882
991
|
{
|
883
992
|
SSL_CTX *ctx;
|
884
993
|
STACK_OF(SSL_CIPHER) *ciphers;
|
885
|
-
SSL_CIPHER *cipher;
|
994
|
+
const SSL_CIPHER *cipher;
|
886
995
|
VALUE ary;
|
887
996
|
int i, num;
|
888
997
|
|
889
998
|
GetSSLCTX(self, ctx);
|
890
|
-
|
891
|
-
rb_warning("SSL_CTX is not initialized.");
|
892
|
-
return Qnil;
|
893
|
-
}
|
894
|
-
ciphers = ctx->cipher_list;
|
895
|
-
|
999
|
+
ciphers = SSL_CTX_get_ciphers(ctx);
|
896
1000
|
if (!ciphers)
|
897
1001
|
return rb_ary_new();
|
898
1002
|
|
@@ -911,11 +1015,9 @@ ossl_sslctx_get_ciphers(VALUE self)
|
|
911
1015
|
* ctx.ciphers = [name, ...]
|
912
1016
|
* ctx.ciphers = [[name, version, bits, alg_bits], ...]
|
913
1017
|
*
|
914
|
-
* Sets the list of available
|
1018
|
+
* Sets the list of available cipher suites for this context. Note in a server
|
915
1019
|
* context some ciphers require the appropriate certificates. For example, an
|
916
|
-
* RSA cipher can only be chosen when an RSA certificate is available.
|
917
|
-
*
|
918
|
-
* See also OpenSSL::Cipher and OpenSSL::Cipher::ciphers
|
1020
|
+
* RSA cipher suite can only be chosen when an RSA certificate is available.
|
919
1021
|
*/
|
920
1022
|
static VALUE
|
921
1023
|
ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
@@ -942,22 +1044,165 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
|
|
942
1044
|
}
|
943
1045
|
|
944
1046
|
GetSSLCTX(self, ctx);
|
945
|
-
if(!ctx){
|
946
|
-
ossl_raise(eSSLError, "SSL_CTX is not initialized.");
|
947
|
-
return Qnil;
|
948
|
-
}
|
949
|
-
if (!SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(str))) {
|
1047
|
+
if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) {
|
950
1048
|
ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
|
951
1049
|
}
|
952
1050
|
|
953
1051
|
return v;
|
954
1052
|
}
|
955
1053
|
|
1054
|
+
#if !defined(OPENSSL_NO_EC)
|
1055
|
+
/*
|
1056
|
+
* call-seq:
|
1057
|
+
* ctx.ecdh_curves = curve_list -> curve_list
|
1058
|
+
*
|
1059
|
+
* Sets the list of "supported elliptic curves" for this context.
|
1060
|
+
*
|
1061
|
+
* For a TLS client, the list is directly used in the Supported Elliptic Curves
|
1062
|
+
* Extension. For a server, the list is used by OpenSSL to determine the set of
|
1063
|
+
* shared curves. OpenSSL will pick the most appropriate one from it.
|
1064
|
+
*
|
1065
|
+
* Note that this works differently with old OpenSSL (<= 1.0.1). Only one curve
|
1066
|
+
* can be set, and this has no effect for TLS clients.
|
1067
|
+
*
|
1068
|
+
* === Example
|
1069
|
+
* ctx1 = OpenSSL::SSL::SSLContext.new
|
1070
|
+
* ctx1.ecdh_curves = "X25519:P-256:P-224"
|
1071
|
+
* svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx1)
|
1072
|
+
* Thread.new { svr.accept }
|
1073
|
+
*
|
1074
|
+
* ctx2 = OpenSSL::SSL::SSLContext.new
|
1075
|
+
* ctx2.ecdh_curves = "P-256"
|
1076
|
+
* cli = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx2)
|
1077
|
+
* cli.connect
|
1078
|
+
*
|
1079
|
+
* p cli.tmp_key.group.curve_name
|
1080
|
+
* # => "prime256v1" (is an alias for NIST P-256)
|
1081
|
+
*/
|
1082
|
+
static VALUE
|
1083
|
+
ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
|
1084
|
+
{
|
1085
|
+
SSL_CTX *ctx;
|
1086
|
+
|
1087
|
+
rb_check_frozen(self);
|
1088
|
+
GetSSLCTX(self, ctx);
|
1089
|
+
StringValueCStr(arg);
|
1090
|
+
|
1091
|
+
#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
|
1092
|
+
if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
|
1093
|
+
ossl_raise(eSSLError, NULL);
|
1094
|
+
#else
|
1095
|
+
/* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to
|
1096
|
+
* SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */
|
1097
|
+
{
|
1098
|
+
VALUE curve, splitted;
|
1099
|
+
EC_KEY *ec;
|
1100
|
+
int nid;
|
1101
|
+
|
1102
|
+
splitted = rb_str_split(arg, ":");
|
1103
|
+
if (!RARRAY_LEN(splitted))
|
1104
|
+
ossl_raise(eSSLError, "invalid input format");
|
1105
|
+
curve = RARRAY_AREF(splitted, 0);
|
1106
|
+
StringValueCStr(curve);
|
1107
|
+
|
1108
|
+
/* SSL_CTX_set1_curves_list() accepts NIST names */
|
1109
|
+
nid = EC_curve_nist2nid(RSTRING_PTR(curve));
|
1110
|
+
if (nid == NID_undef)
|
1111
|
+
nid = OBJ_txt2nid(RSTRING_PTR(curve));
|
1112
|
+
if (nid == NID_undef)
|
1113
|
+
ossl_raise(eSSLError, "unknown curve name");
|
1114
|
+
|
1115
|
+
ec = EC_KEY_new_by_curve_name(nid);
|
1116
|
+
if (!ec)
|
1117
|
+
ossl_raise(eSSLError, NULL);
|
1118
|
+
EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
|
1119
|
+
if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
|
1120
|
+
EC_KEY_free(ec);
|
1121
|
+
ossl_raise(eSSLError, "SSL_CTX_set_tmp_ecdh");
|
1122
|
+
}
|
1123
|
+
EC_KEY_free(ec);
|
1124
|
+
# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
|
1125
|
+
/* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto
|
1126
|
+
* is enabled. So disable ecdh_auto. */
|
1127
|
+
if (!SSL_CTX_set_ecdh_auto(ctx, 0))
|
1128
|
+
ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
|
1129
|
+
# endif
|
1130
|
+
}
|
1131
|
+
#endif
|
1132
|
+
|
1133
|
+
return arg;
|
1134
|
+
}
|
1135
|
+
#else
|
1136
|
+
#define ossl_sslctx_set_ecdh_curves rb_f_notimplement
|
1137
|
+
#endif
|
1138
|
+
|
1139
|
+
/*
|
1140
|
+
* call-seq:
|
1141
|
+
* ctx.security_level -> Integer
|
1142
|
+
*
|
1143
|
+
* Returns the security level for the context.
|
1144
|
+
*
|
1145
|
+
* See also OpenSSL::SSL::SSLContext#security_level=.
|
1146
|
+
*/
|
1147
|
+
static VALUE
|
1148
|
+
ossl_sslctx_get_security_level(VALUE self)
|
1149
|
+
{
|
1150
|
+
SSL_CTX *ctx;
|
1151
|
+
|
1152
|
+
GetSSLCTX(self, ctx);
|
1153
|
+
|
1154
|
+
#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
|
1155
|
+
return INT2NUM(SSL_CTX_get_security_level(ctx));
|
1156
|
+
#else
|
1157
|
+
(void)ctx;
|
1158
|
+
return INT2FIX(0);
|
1159
|
+
#endif
|
1160
|
+
}
|
1161
|
+
|
1162
|
+
/*
|
1163
|
+
* call-seq:
|
1164
|
+
* ctx.security_level = integer
|
1165
|
+
*
|
1166
|
+
* Sets the security level for the context. OpenSSL limits parameters according
|
1167
|
+
* to the level. The "parameters" include: ciphersuites, curves, key sizes,
|
1168
|
+
* certificate signature algorithms, protocol version and so on. For example,
|
1169
|
+
* level 1 rejects parameters offering below 80 bits of security, such as
|
1170
|
+
* ciphersuites using MD5 for the MAC or RSA keys shorter than 1024 bits.
|
1171
|
+
*
|
1172
|
+
* Note that attempts to set such parameters with insufficient security are
|
1173
|
+
* also blocked. You need to lower the level first.
|
1174
|
+
*
|
1175
|
+
* This feature is not supported in OpenSSL < 1.1.0, and setting the level to
|
1176
|
+
* other than 0 will raise NotImplementedError. Level 0 means everything is
|
1177
|
+
* permitted, the same behavior as previous versions of OpenSSL.
|
1178
|
+
*
|
1179
|
+
* See the manpage of SSL_CTX_set_security_level(3) for details.
|
1180
|
+
*/
|
1181
|
+
static VALUE
|
1182
|
+
ossl_sslctx_set_security_level(VALUE self, VALUE value)
|
1183
|
+
{
|
1184
|
+
SSL_CTX *ctx;
|
1185
|
+
|
1186
|
+
rb_check_frozen(self);
|
1187
|
+
GetSSLCTX(self, ctx);
|
1188
|
+
|
1189
|
+
#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
|
1190
|
+
SSL_CTX_set_security_level(ctx, NUM2INT(value));
|
1191
|
+
#else
|
1192
|
+
(void)ctx;
|
1193
|
+
if (NUM2INT(value) != 0)
|
1194
|
+
ossl_raise(rb_eNotImpError, "setting security level to other than 0 is "
|
1195
|
+
"not supported in this version of OpenSSL");
|
1196
|
+
#endif
|
1197
|
+
|
1198
|
+
return value;
|
1199
|
+
}
|
1200
|
+
|
956
1201
|
/*
|
957
1202
|
* call-seq:
|
958
1203
|
* ctx.session_add(session) -> true | false
|
959
1204
|
*
|
960
|
-
* Adds +session+ to the session cache
|
1205
|
+
* Adds +session+ to the session cache.
|
961
1206
|
*/
|
962
1207
|
static VALUE
|
963
1208
|
ossl_sslctx_session_add(VALUE self, VALUE arg)
|
@@ -975,7 +1220,7 @@ ossl_sslctx_session_add(VALUE self, VALUE arg)
|
|
975
1220
|
* call-seq:
|
976
1221
|
* ctx.session_remove(session) -> true | false
|
977
1222
|
*
|
978
|
-
* Removes +session+ from the session cache
|
1223
|
+
* Removes +session+ from the session cache.
|
979
1224
|
*/
|
980
1225
|
static VALUE
|
981
1226
|
ossl_sslctx_session_remove(VALUE self, VALUE arg)
|
@@ -1143,25 +1388,11 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
|
|
1143
1388
|
* SSLSocket class
|
1144
1389
|
*/
|
1145
1390
|
#ifndef OPENSSL_NO_SOCK
|
1146
|
-
static
|
1147
|
-
|
1148
|
-
{
|
1149
|
-
|
1150
|
-
|
1151
|
-
if (ssl) {
|
1152
|
-
/* 4 is from SSL_smart_shutdown() of mod_ssl.c (v2.2.19) */
|
1153
|
-
/* It says max 2x pending + 2x data = 4 */
|
1154
|
-
for (i = 0; i < 4; ++i) {
|
1155
|
-
/*
|
1156
|
-
* Ignore the case SSL_shutdown returns -1. Empty handshake_func
|
1157
|
-
* must not happen.
|
1158
|
-
*/
|
1159
|
-
if ((rc = SSL_shutdown(ssl)) != 0)
|
1160
|
-
break;
|
1161
|
-
}
|
1162
|
-
SSL_clear(ssl);
|
1163
|
-
ERR_clear_error();
|
1164
|
-
}
|
1391
|
+
static inline int
|
1392
|
+
ssl_started(SSL *ssl)
|
1393
|
+
{
|
1394
|
+
/* the FD is set in ossl_ssl_setup(), called by #connect or #accept */
|
1395
|
+
return SSL_get_fd(ssl) >= 0;
|
1165
1396
|
}
|
1166
1397
|
|
1167
1398
|
static void
|
@@ -1184,45 +1415,76 @@ ossl_ssl_s_alloc(VALUE klass)
|
|
1184
1415
|
return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
|
1185
1416
|
}
|
1186
1417
|
|
1418
|
+
/*
|
1419
|
+
* call-seq:
|
1420
|
+
* SSLSocket.new(io) => aSSLSocket
|
1421
|
+
* SSLSocket.new(io, ctx) => aSSLSocket
|
1422
|
+
*
|
1423
|
+
* Creates a new SSL socket from +io+ which must be a real IO object (not an
|
1424
|
+
* IO-like object that responds to read/write).
|
1425
|
+
*
|
1426
|
+
* If +ctx+ is provided the SSL Sockets initial params will be taken from
|
1427
|
+
* the context.
|
1428
|
+
*
|
1429
|
+
* The OpenSSL::Buffering module provides additional IO methods.
|
1430
|
+
*
|
1431
|
+
* This method will freeze the SSLContext if one is provided;
|
1432
|
+
* however, session management is still allowed in the frozen SSLContext.
|
1433
|
+
*/
|
1187
1434
|
static VALUE
|
1188
|
-
|
1435
|
+
ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
1189
1436
|
{
|
1190
|
-
VALUE io, v_ctx,
|
1437
|
+
VALUE io, v_ctx, verify_cb;
|
1438
|
+
SSL *ssl;
|
1191
1439
|
SSL_CTX *ctx;
|
1440
|
+
|
1441
|
+
TypedData_Get_Struct(self, SSL, &ossl_ssl_type, ssl);
|
1442
|
+
if (ssl)
|
1443
|
+
ossl_raise(eSSLError, "SSL already initialized");
|
1444
|
+
|
1445
|
+
if (rb_scan_args(argc, argv, "11", &io, &v_ctx) == 1)
|
1446
|
+
v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
|
1447
|
+
|
1448
|
+
GetSSLCTX(v_ctx, ctx);
|
1449
|
+
rb_ivar_set(self, id_i_context, v_ctx);
|
1450
|
+
ossl_sslctx_setup(v_ctx);
|
1451
|
+
|
1452
|
+
if (rb_respond_to(io, rb_intern("nonblock=")))
|
1453
|
+
rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
|
1454
|
+
rb_ivar_set(self, id_i_io, io);
|
1455
|
+
|
1456
|
+
ssl = SSL_new(ctx);
|
1457
|
+
if (!ssl)
|
1458
|
+
ossl_raise(eSSLError, NULL);
|
1459
|
+
RTYPEDDATA_DATA(self) = ssl;
|
1460
|
+
|
1461
|
+
SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
|
1462
|
+
SSL_set_info_callback(ssl, ssl_info_cb);
|
1463
|
+
verify_cb = rb_attr_get(v_ctx, id_i_verify_callback);
|
1464
|
+
SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
|
1465
|
+
|
1466
|
+
rb_call_super(0, NULL);
|
1467
|
+
|
1468
|
+
return self;
|
1469
|
+
}
|
1470
|
+
|
1471
|
+
static VALUE
|
1472
|
+
ossl_ssl_setup(VALUE self)
|
1473
|
+
{
|
1474
|
+
VALUE io;
|
1192
1475
|
SSL *ssl;
|
1193
1476
|
rb_io_t *fptr;
|
1194
1477
|
|
1195
1478
|
GetSSL(self, ssl);
|
1196
|
-
if(
|
1197
|
-
|
1198
|
-
VALUE hostname = rb_iv_get(self, "@hostname");
|
1199
|
-
#endif
|
1479
|
+
if (ssl_started(ssl))
|
1480
|
+
return Qtrue;
|
1200
1481
|
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
}
|
1208
|
-
DATA_PTR(self) = ssl;
|
1209
|
-
|
1210
|
-
#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
|
1211
|
-
if (!NIL_P(hostname)) {
|
1212
|
-
if (SSL_set_tlsext_host_name(ssl, StringValuePtr(hostname)) != 1)
|
1213
|
-
ossl_raise(eSSLError, "SSL_set_tlsext_host_name");
|
1214
|
-
}
|
1215
|
-
#endif
|
1216
|
-
io = ossl_ssl_get_io(self);
|
1217
|
-
GetOpenFile(io, fptr);
|
1218
|
-
rb_io_check_readable(fptr);
|
1219
|
-
rb_io_check_writable(fptr);
|
1220
|
-
SSL_set_fd(ssl, TO_SOCKET(FPTR_TO_FD(fptr)));
|
1221
|
-
SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void*)self);
|
1222
|
-
cb = ossl_sslctx_get_verify_cb(v_ctx);
|
1223
|
-
SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void*)cb);
|
1224
|
-
SSL_set_info_callback(ssl, ssl_info_cb);
|
1225
|
-
}
|
1482
|
+
io = rb_attr_get(self, id_i_io);
|
1483
|
+
GetOpenFile(io, fptr);
|
1484
|
+
rb_io_check_readable(fptr);
|
1485
|
+
rb_io_check_writable(fptr);
|
1486
|
+
if (!SSL_set_fd(ssl, TO_SOCKET(FPTR_TO_FD(fptr))))
|
1487
|
+
ossl_raise(eSSLError, "SSL_set_fd");
|
1226
1488
|
|
1227
1489
|
return Qtrue;
|
1228
1490
|
}
|
@@ -1233,31 +1495,18 @@ ossl_ssl_setup(VALUE self)
|
|
1233
1495
|
#define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret))
|
1234
1496
|
#endif
|
1235
1497
|
|
1236
|
-
#define ossl_ssl_data_get_struct(v, ssl) \
|
1237
|
-
do { \
|
1238
|
-
GetSSL((v), (ssl)); \
|
1239
|
-
if (!(ssl)) { \
|
1240
|
-
rb_warning("SSL session is not started yet."); \
|
1241
|
-
return Qnil; \
|
1242
|
-
} \
|
1243
|
-
} while (0)
|
1244
|
-
|
1245
1498
|
static void
|
1246
1499
|
write_would_block(int nonblock)
|
1247
1500
|
{
|
1248
|
-
if (nonblock)
|
1249
|
-
|
1250
|
-
rb_exc_raise(exc);
|
1251
|
-
}
|
1501
|
+
if (nonblock)
|
1502
|
+
ossl_raise(eSSLErrorWaitWritable, "write would block");
|
1252
1503
|
}
|
1253
1504
|
|
1254
1505
|
static void
|
1255
1506
|
read_would_block(int nonblock)
|
1256
1507
|
{
|
1257
|
-
if (nonblock)
|
1258
|
-
|
1259
|
-
rb_exc_raise(exc);
|
1260
|
-
}
|
1508
|
+
if (nonblock)
|
1509
|
+
ossl_raise(eSSLErrorWaitReadable, "read would block");
|
1261
1510
|
}
|
1262
1511
|
|
1263
1512
|
static int
|
@@ -1280,15 +1529,18 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
|
1280
1529
|
|
1281
1530
|
rb_ivar_set(self, ID_callback_state, Qnil);
|
1282
1531
|
|
1283
|
-
|
1532
|
+
GetSSL(self, ssl);
|
1284
1533
|
|
1285
|
-
GetOpenFile(
|
1534
|
+
GetOpenFile(rb_attr_get(self, id_i_io), fptr);
|
1286
1535
|
for(;;){
|
1287
1536
|
ret = func(ssl);
|
1288
1537
|
|
1289
|
-
|
1290
|
-
if (!NIL_P(cb_state))
|
1291
|
-
|
1538
|
+
cb_state = rb_attr_get(self, ID_callback_state);
|
1539
|
+
if (!NIL_P(cb_state)) {
|
1540
|
+
/* must cleanup OpenSSL error stack before re-raising */
|
1541
|
+
ossl_clear_error();
|
1542
|
+
rb_jump_tag(NUM2INT(cb_state));
|
1543
|
+
}
|
1292
1544
|
|
1293
1545
|
if (ret > 0)
|
1294
1546
|
break;
|
@@ -1418,7 +1670,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1418
1670
|
int ilen, nread = 0;
|
1419
1671
|
VALUE len, str;
|
1420
1672
|
rb_io_t *fptr;
|
1421
|
-
VALUE opts = Qnil;
|
1673
|
+
VALUE io, opts = Qnil;
|
1422
1674
|
|
1423
1675
|
if (nonblock) {
|
1424
1676
|
rb_scan_args(argc, argv, "11:", &len, &str, &opts);
|
@@ -1427,21 +1679,26 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1427
1679
|
}
|
1428
1680
|
|
1429
1681
|
ilen = NUM2INT(len);
|
1430
|
-
if(NIL_P(str))
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1682
|
+
if (NIL_P(str))
|
1683
|
+
str = rb_str_new(0, ilen);
|
1684
|
+
else {
|
1685
|
+
StringValue(str);
|
1686
|
+
if (RSTRING_LEN(str) >= ilen)
|
1687
|
+
rb_str_modify(str);
|
1688
|
+
else
|
1689
|
+
rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
|
1435
1690
|
}
|
1436
|
-
|
1691
|
+
OBJ_TAINT(str);
|
1692
|
+
rb_str_set_len(str, 0);
|
1693
|
+
if (ilen == 0)
|
1694
|
+
return str;
|
1437
1695
|
|
1438
1696
|
GetSSL(self, ssl);
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
rb_thread_wait_fd(FPTR_TO_FD(fptr));
|
1697
|
+
io = rb_attr_get(self, id_i_io);
|
1698
|
+
GetOpenFile(io, fptr);
|
1699
|
+
if (ssl_started(ssl)) {
|
1443
1700
|
for (;;){
|
1444
|
-
nread = SSL_read(ssl, RSTRING_PTR(str),
|
1701
|
+
nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
|
1445
1702
|
switch(ssl_get_error(ssl, nread)){
|
1446
1703
|
case SSL_ERROR_NONE:
|
1447
1704
|
goto end;
|
@@ -1459,30 +1716,38 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
1459
1716
|
rb_io_wait_readable(FPTR_TO_FD(fptr));
|
1460
1717
|
continue;
|
1461
1718
|
case SSL_ERROR_SYSCALL:
|
1462
|
-
if(ERR_peek_error()
|
1463
|
-
if (
|
1464
|
-
|
1719
|
+
if (!ERR_peek_error()) {
|
1720
|
+
if (errno)
|
1721
|
+
rb_sys_fail(0);
|
1722
|
+
else {
|
1723
|
+
/*
|
1724
|
+
* The underlying BIO returned 0. This is actually a
|
1725
|
+
* protocol error. But unfortunately, not all
|
1726
|
+
* implementations cleanly shutdown the TLS connection
|
1727
|
+
* but just shutdown/close the TCP connection. So report
|
1728
|
+
* EOF for now...
|
1729
|
+
*/
|
1730
|
+
if (no_exception_p(opts)) { return Qnil; }
|
1731
|
+
rb_eof_error();
|
1732
|
+
}
|
1465
1733
|
}
|
1466
|
-
rb_sys_fail(0);
|
1467
1734
|
default:
|
1468
1735
|
ossl_raise(eSSLError, "SSL_read");
|
1469
1736
|
}
|
1470
1737
|
}
|
1471
1738
|
}
|
1472
1739
|
else {
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1740
|
+
ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
|
1741
|
+
|
1742
|
+
rb_warning("SSL session is not started yet.");
|
1743
|
+
if (nonblock)
|
1744
|
+
return rb_funcall(io, meth, 3, len, str, opts);
|
1745
|
+
else
|
1746
|
+
return rb_funcall(io, meth, 2, len, str);
|
1480
1747
|
}
|
1481
1748
|
|
1482
1749
|
end:
|
1483
1750
|
rb_str_set_len(str, nread);
|
1484
|
-
OBJ_TAINT(str);
|
1485
|
-
|
1486
1751
|
return str;
|
1487
1752
|
}
|
1488
1753
|
|
@@ -1526,12 +1791,13 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|
1526
1791
|
int nwrite = 0;
|
1527
1792
|
rb_io_t *fptr;
|
1528
1793
|
int nonblock = opts != Qfalse;
|
1794
|
+
VALUE io;
|
1529
1795
|
|
1530
1796
|
StringValue(str);
|
1531
1797
|
GetSSL(self, ssl);
|
1532
|
-
|
1533
|
-
|
1534
|
-
if (ssl) {
|
1798
|
+
io = rb_attr_get(self, id_i_io);
|
1799
|
+
GetOpenFile(io, fptr);
|
1800
|
+
if (ssl_started(ssl)) {
|
1535
1801
|
for (;;){
|
1536
1802
|
int num = RSTRING_LENINT(str);
|
1537
1803
|
|
@@ -1561,9 +1827,14 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|
1561
1827
|
}
|
1562
1828
|
}
|
1563
1829
|
else {
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1830
|
+
ID meth = nonblock ?
|
1831
|
+
rb_intern("write_nonblock") : rb_intern("syswrite");
|
1832
|
+
|
1833
|
+
rb_warning("SSL session is not started yet.");
|
1834
|
+
if (nonblock)
|
1835
|
+
return rb_funcall(io, meth, 2, str, opts);
|
1836
|
+
else
|
1837
|
+
return rb_funcall(io, meth, 1, str);
|
1567
1838
|
}
|
1568
1839
|
|
1569
1840
|
end:
|
@@ -1610,11 +1881,24 @@ static VALUE
|
|
1610
1881
|
ossl_ssl_stop(VALUE self)
|
1611
1882
|
{
|
1612
1883
|
SSL *ssl;
|
1884
|
+
int ret;
|
1613
1885
|
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1886
|
+
GetSSL(self, ssl);
|
1887
|
+
if (!ssl_started(ssl))
|
1888
|
+
return Qnil;
|
1889
|
+
ret = SSL_shutdown(ssl);
|
1890
|
+
if (ret == 1) /* Have already received close_notify */
|
1891
|
+
return Qnil;
|
1892
|
+
if (ret == 0) /* Sent close_notify, but we don't wait for reply */
|
1893
|
+
return Qnil;
|
1617
1894
|
|
1895
|
+
/*
|
1896
|
+
* XXX: Something happened. Possibly it failed because the underlying socket
|
1897
|
+
* is not writable/readable, since it is in non-blocking mode. We should do
|
1898
|
+
* some proper error handling using SSL_get_error() and maybe retry, but we
|
1899
|
+
* can't block here. Give up for now.
|
1900
|
+
*/
|
1901
|
+
ossl_clear_error();
|
1618
1902
|
return Qnil;
|
1619
1903
|
}
|
1620
1904
|
|
@@ -1630,7 +1914,7 @@ ossl_ssl_get_cert(VALUE self)
|
|
1630
1914
|
SSL *ssl;
|
1631
1915
|
X509 *cert = NULL;
|
1632
1916
|
|
1633
|
-
|
1917
|
+
GetSSL(self, ssl);
|
1634
1918
|
|
1635
1919
|
/*
|
1636
1920
|
* Is this OpenSSL bug? Should add a ref?
|
@@ -1657,7 +1941,7 @@ ossl_ssl_get_peer_cert(VALUE self)
|
|
1657
1941
|
X509 *cert = NULL;
|
1658
1942
|
VALUE obj;
|
1659
1943
|
|
1660
|
-
|
1944
|
+
GetSSL(self, ssl);
|
1661
1945
|
|
1662
1946
|
cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */
|
1663
1947
|
|
@@ -1685,7 +1969,7 @@ ossl_ssl_get_peer_cert_chain(VALUE self)
|
|
1685
1969
|
VALUE ary;
|
1686
1970
|
int i, num;
|
1687
1971
|
|
1688
|
-
|
1972
|
+
GetSSL(self, ssl);
|
1689
1973
|
|
1690
1974
|
chain = SSL_get_peer_cert_chain(ssl);
|
1691
1975
|
if(!chain) return Qnil;
|
@@ -1711,7 +1995,7 @@ ossl_ssl_get_version(VALUE self)
|
|
1711
1995
|
{
|
1712
1996
|
SSL *ssl;
|
1713
1997
|
|
1714
|
-
|
1998
|
+
GetSSL(self, ssl);
|
1715
1999
|
|
1716
2000
|
return rb_str_new2(SSL_get_version(ssl));
|
1717
2001
|
}
|
@@ -1728,7 +2012,7 @@ ossl_ssl_get_cipher(VALUE self)
|
|
1728
2012
|
SSL *ssl;
|
1729
2013
|
SSL_CIPHER *cipher;
|
1730
2014
|
|
1731
|
-
|
2015
|
+
GetSSL(self, ssl);
|
1732
2016
|
|
1733
2017
|
cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl);
|
1734
2018
|
|
@@ -1739,7 +2023,8 @@ ossl_ssl_get_cipher(VALUE self)
|
|
1739
2023
|
* call-seq:
|
1740
2024
|
* ssl.state => string
|
1741
2025
|
*
|
1742
|
-
* A description of the current connection state.
|
2026
|
+
* A description of the current connection state. This is for diagnostic
|
2027
|
+
* purposes only.
|
1743
2028
|
*/
|
1744
2029
|
static VALUE
|
1745
2030
|
ossl_ssl_get_state(VALUE self)
|
@@ -1747,7 +2032,7 @@ ossl_ssl_get_state(VALUE self)
|
|
1747
2032
|
SSL *ssl;
|
1748
2033
|
VALUE ret;
|
1749
2034
|
|
1750
|
-
|
2035
|
+
GetSSL(self, ssl);
|
1751
2036
|
|
1752
2037
|
ret = rb_str_new2(SSL_state_string(ssl));
|
1753
2038
|
if (ruby_verbose) {
|
@@ -1761,14 +2046,14 @@ ossl_ssl_get_state(VALUE self)
|
|
1761
2046
|
* call-seq:
|
1762
2047
|
* ssl.pending => Integer
|
1763
2048
|
*
|
1764
|
-
* The number of bytes that are immediately available for reading
|
2049
|
+
* The number of bytes that are immediately available for reading.
|
1765
2050
|
*/
|
1766
2051
|
static VALUE
|
1767
2052
|
ossl_ssl_pending(VALUE self)
|
1768
2053
|
{
|
1769
2054
|
SSL *ssl;
|
1770
2055
|
|
1771
|
-
|
2056
|
+
GetSSL(self, ssl);
|
1772
2057
|
|
1773
2058
|
return INT2NUM(SSL_pending(ssl));
|
1774
2059
|
}
|
@@ -1784,15 +2069,9 @@ ossl_ssl_session_reused(VALUE self)
|
|
1784
2069
|
{
|
1785
2070
|
SSL *ssl;
|
1786
2071
|
|
1787
|
-
|
1788
|
-
|
1789
|
-
switch(SSL_session_reused(ssl)) {
|
1790
|
-
case 1: return Qtrue;
|
1791
|
-
case 0: return Qfalse;
|
1792
|
-
default: ossl_raise(eSSLError, "SSL_session_reused");
|
1793
|
-
}
|
2072
|
+
GetSSL(self, ssl);
|
1794
2073
|
|
1795
|
-
|
2074
|
+
return SSL_session_reused(ssl) ? Qtrue : Qfalse;
|
1796
2075
|
}
|
1797
2076
|
|
1798
2077
|
/*
|
@@ -1807,11 +2086,7 @@ ossl_ssl_set_session(VALUE self, VALUE arg1)
|
|
1807
2086
|
SSL *ssl;
|
1808
2087
|
SSL_SESSION *sess;
|
1809
2088
|
|
1810
|
-
|
1811
|
-
ossl_ssl_setup(self);
|
1812
|
-
|
1813
|
-
ossl_ssl_data_get_struct(self, ssl);
|
1814
|
-
|
2089
|
+
GetSSL(self, ssl);
|
1815
2090
|
SafeGetSSLSession(arg1, sess);
|
1816
2091
|
|
1817
2092
|
if (SSL_set_session(ssl, sess) != 1)
|
@@ -1820,6 +2095,35 @@ ossl_ssl_set_session(VALUE self, VALUE arg1)
|
|
1820
2095
|
return arg1;
|
1821
2096
|
}
|
1822
2097
|
|
2098
|
+
#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
|
2099
|
+
/*
|
2100
|
+
* call-seq:
|
2101
|
+
* ssl.hostname = hostname -> hostname
|
2102
|
+
*
|
2103
|
+
* Sets the server hostname used for SNI. This needs to be set before
|
2104
|
+
* SSLSocket#connect.
|
2105
|
+
*/
|
2106
|
+
static VALUE
|
2107
|
+
ossl_ssl_set_hostname(VALUE self, VALUE arg)
|
2108
|
+
{
|
2109
|
+
SSL *ssl;
|
2110
|
+
char *hostname = NULL;
|
2111
|
+
|
2112
|
+
GetSSL(self, ssl);
|
2113
|
+
|
2114
|
+
if (!NIL_P(arg))
|
2115
|
+
hostname = StringValueCStr(arg);
|
2116
|
+
|
2117
|
+
if (!SSL_set_tlsext_host_name(ssl, hostname))
|
2118
|
+
ossl_raise(eSSLError, NULL);
|
2119
|
+
|
2120
|
+
/* for SSLSocket#hostname */
|
2121
|
+
rb_ivar_set(self, id_i_hostname, arg);
|
2122
|
+
|
2123
|
+
return arg;
|
2124
|
+
}
|
2125
|
+
#endif
|
2126
|
+
|
1823
2127
|
/*
|
1824
2128
|
* call-seq:
|
1825
2129
|
* ssl.verify_result => Integer
|
@@ -1834,9 +2138,9 @@ ossl_ssl_get_verify_result(VALUE self)
|
|
1834
2138
|
{
|
1835
2139
|
SSL *ssl;
|
1836
2140
|
|
1837
|
-
|
2141
|
+
GetSSL(self, ssl);
|
1838
2142
|
|
1839
|
-
return
|
2143
|
+
return INT2NUM(SSL_get_verify_result(ssl));
|
1840
2144
|
}
|
1841
2145
|
|
1842
2146
|
/*
|
@@ -1856,7 +2160,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
|
|
1856
2160
|
SSL *ssl;
|
1857
2161
|
STACK_OF(X509_NAME) *ca;
|
1858
2162
|
|
1859
|
-
|
2163
|
+
GetSSL(self, ssl);
|
1860
2164
|
|
1861
2165
|
ca = SSL_get_client_CA_list(ssl);
|
1862
2166
|
return ossl_x509name_sk2ary(ca);
|
@@ -1865,7 +2169,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
|
|
1865
2169
|
# ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
|
1866
2170
|
/*
|
1867
2171
|
* call-seq:
|
1868
|
-
* ssl.npn_protocol => String
|
2172
|
+
* ssl.npn_protocol => String | nil
|
1869
2173
|
*
|
1870
2174
|
* Returns the protocol string that was finally selected by the client
|
1871
2175
|
* during the handshake.
|
@@ -1877,7 +2181,7 @@ ossl_ssl_npn_protocol(VALUE self)
|
|
1877
2181
|
const unsigned char *out;
|
1878
2182
|
unsigned int outlen;
|
1879
2183
|
|
1880
|
-
|
2184
|
+
GetSSL(self, ssl);
|
1881
2185
|
|
1882
2186
|
SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
|
1883
2187
|
if (!outlen)
|
@@ -1890,9 +2194,9 @@ ossl_ssl_npn_protocol(VALUE self)
|
|
1890
2194
|
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
1891
2195
|
/*
|
1892
2196
|
* call-seq:
|
1893
|
-
* ssl.alpn_protocol => String
|
2197
|
+
* ssl.alpn_protocol => String | nil
|
1894
2198
|
*
|
1895
|
-
* Returns the ALPN protocol string that was finally selected by the
|
2199
|
+
* Returns the ALPN protocol string that was finally selected by the server
|
1896
2200
|
* during the handshake.
|
1897
2201
|
*/
|
1898
2202
|
static VALUE
|
@@ -1902,7 +2206,7 @@ ossl_ssl_alpn_protocol(VALUE self)
|
|
1902
2206
|
const unsigned char *out;
|
1903
2207
|
unsigned int outlen;
|
1904
2208
|
|
1905
|
-
|
2209
|
+
GetSSL(self, ssl);
|
1906
2210
|
|
1907
2211
|
SSL_get0_alpn_selected(ssl, &out, &outlen);
|
1908
2212
|
if (!outlen)
|
@@ -1911,8 +2215,30 @@ ossl_ssl_alpn_protocol(VALUE self)
|
|
1911
2215
|
return rb_str_new((const char *) out, outlen);
|
1912
2216
|
}
|
1913
2217
|
# endif
|
2218
|
+
|
2219
|
+
# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
|
2220
|
+
/*
|
2221
|
+
* call-seq:
|
2222
|
+
* ssl.tmp_key => PKey or nil
|
2223
|
+
*
|
2224
|
+
* Returns the ephemeral key used in case of forward secrecy cipher.
|
2225
|
+
*/
|
2226
|
+
static VALUE
|
2227
|
+
ossl_ssl_tmp_key(VALUE self)
|
2228
|
+
{
|
2229
|
+
SSL *ssl;
|
2230
|
+
EVP_PKEY *key;
|
2231
|
+
|
2232
|
+
GetSSL(self, ssl);
|
2233
|
+
if (!SSL_get_server_tmp_key(ssl, &key))
|
2234
|
+
return Qnil;
|
2235
|
+
return ossl_pkey_new(key);
|
2236
|
+
}
|
2237
|
+
# endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */
|
1914
2238
|
#endif /* !defined(OPENSSL_NO_SOCK) */
|
1915
2239
|
|
2240
|
+
#undef rb_intern
|
2241
|
+
#define rb_intern(s) rb_intern_const(s)
|
1916
2242
|
void
|
1917
2243
|
Init_ossl_ssl(void)
|
1918
2244
|
{
|
@@ -1920,10 +2246,13 @@ Init_ossl_ssl(void)
|
|
1920
2246
|
VALUE ary;
|
1921
2247
|
|
1922
2248
|
#if 0
|
1923
|
-
mOSSL = rb_define_module("OpenSSL");
|
2249
|
+
mOSSL = rb_define_module("OpenSSL");
|
2250
|
+
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
2251
|
+
rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
|
2252
|
+
rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
|
1924
2253
|
#endif
|
1925
2254
|
|
1926
|
-
ID_callback_state = rb_intern("
|
2255
|
+
ID_callback_state = rb_intern("callback_state");
|
1927
2256
|
|
1928
2257
|
ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0);
|
1929
2258
|
ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0);
|
@@ -1968,14 +2297,10 @@ Init_ossl_ssl(void)
|
|
1968
2297
|
*
|
1969
2298
|
* All attributes must be set before creating an SSLSocket as the
|
1970
2299
|
* SSLContext will be frozen afterward.
|
1971
|
-
*
|
1972
|
-
* The following attributes are available but don't show up in rdoc:
|
1973
|
-
* * ssl_version, cert, key, client_ca, ca_file, ca_path, timeout,
|
1974
|
-
* * verify_mode, verify_depth client_cert_cb, tmp_dh_callback,
|
1975
|
-
* * session_id_context, session_add_cb, session_new_cb, session_remove_cb
|
1976
2300
|
*/
|
1977
2301
|
cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject);
|
1978
2302
|
rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc);
|
2303
|
+
rb_undef_method(cSSLContext, "initialize_copy");
|
1979
2304
|
|
1980
2305
|
/*
|
1981
2306
|
* Context certificate
|
@@ -2005,7 +2330,7 @@ Init_ossl_ssl(void)
|
|
2005
2330
|
rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse);
|
2006
2331
|
|
2007
2332
|
/*
|
2008
|
-
* Maximum session lifetime.
|
2333
|
+
* Maximum session lifetime in seconds.
|
2009
2334
|
*/
|
2010
2335
|
rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse);
|
2011
2336
|
|
@@ -2014,6 +2339,11 @@ Init_ossl_ssl(void)
|
|
2014
2339
|
*
|
2015
2340
|
* Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE,
|
2016
2341
|
* VERIFY_FAIL_IF_NO_PEER_CERT and defined on OpenSSL::SSL
|
2342
|
+
*
|
2343
|
+
* The default mode is VERIFY_NONE, which does not perform any verification
|
2344
|
+
* at all.
|
2345
|
+
*
|
2346
|
+
* See SSL_CTX_set_verify(3) for details.
|
2017
2347
|
*/
|
2018
2348
|
rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse);
|
2019
2349
|
|
@@ -2031,12 +2361,21 @@ Init_ossl_ssl(void)
|
|
2031
2361
|
* +store_context+ is an OpenSSL::X509::StoreContext containing the
|
2032
2362
|
* context used for certificate verification.
|
2033
2363
|
*
|
2034
|
-
* If the callback returns false verification is
|
2364
|
+
* If the callback returns false, the chain verification is immediately
|
2365
|
+
* stopped and a bad_certificate alert is then sent.
|
2035
2366
|
*/
|
2036
2367
|
rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
|
2037
2368
|
|
2038
2369
|
/*
|
2039
|
-
*
|
2370
|
+
* Whether to check the server certificate is valid for the hostname.
|
2371
|
+
*
|
2372
|
+
* In order to make this work, verify_mode must be set to VERIFY_PEER and
|
2373
|
+
* the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=.
|
2374
|
+
*/
|
2375
|
+
rb_attr(cSSLContext, rb_intern("verify_hostname"), 1, 1, Qfalse);
|
2376
|
+
|
2377
|
+
/*
|
2378
|
+
* An OpenSSL::X509::Store used for certificate verification.
|
2040
2379
|
*/
|
2041
2380
|
rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse);
|
2042
2381
|
|
@@ -2056,6 +2395,7 @@ Init_ossl_ssl(void)
|
|
2056
2395
|
*/
|
2057
2396
|
rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
|
2058
2397
|
|
2398
|
+
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
|
2059
2399
|
/*
|
2060
2400
|
* A callback invoked when ECDH parameters are required.
|
2061
2401
|
*
|
@@ -2063,10 +2403,11 @@ Init_ossl_ssl(void)
|
|
2063
2403
|
* flag indicating the use of an export cipher and the keylength
|
2064
2404
|
* required.
|
2065
2405
|
*
|
2066
|
-
* The callback
|
2067
|
-
*
|
2406
|
+
* The callback is deprecated. This does not work with recent versions of
|
2407
|
+
* OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead.
|
2068
2408
|
*/
|
2069
2409
|
rb_attr(cSSLContext, rb_intern("tmp_ecdh_callback"), 1, 1, Qfalse);
|
2410
|
+
#endif
|
2070
2411
|
|
2071
2412
|
/*
|
2072
2413
|
* Sets the context in which a session can be reused. This allows
|
@@ -2096,6 +2437,10 @@ Init_ossl_ssl(void)
|
|
2096
2437
|
* A callback invoked when a session is removed from the internal cache.
|
2097
2438
|
*
|
2098
2439
|
* The callback is invoked with an SSLContext and a Session.
|
2440
|
+
*
|
2441
|
+
* IMPORTANT NOTE: It is currently not possible to use this safely in a
|
2442
|
+
* multi-threaded application. The callback is called inside a global lock
|
2443
|
+
* and it can randomly cause deadlock on Ruby thread switching.
|
2099
2444
|
*/
|
2100
2445
|
rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
|
2101
2446
|
|
@@ -2158,7 +2503,7 @@ Init_ossl_ssl(void)
|
|
2158
2503
|
* === Example
|
2159
2504
|
*
|
2160
2505
|
* ctx.npn_select_cb = lambda do |protocols|
|
2161
|
-
* #inspect the protocols and select one
|
2506
|
+
* # inspect the protocols and select one
|
2162
2507
|
* protocols.first
|
2163
2508
|
* end
|
2164
2509
|
*/
|
@@ -2168,10 +2513,10 @@ Init_ossl_ssl(void)
|
|
2168
2513
|
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2169
2514
|
/*
|
2170
2515
|
* An Enumerable of Strings. Each String represents a protocol to be
|
2171
|
-
* advertised as the list of supported protocols for Application-Layer
|
2172
|
-
* Negotiation. Supported in OpenSSL 1.0.
|
2173
|
-
* on the
|
2174
|
-
* not be
|
2516
|
+
* advertised as the list of supported protocols for Application-Layer
|
2517
|
+
* Protocol Negotiation. Supported in OpenSSL 1.0.2 and higher. Has no
|
2518
|
+
* effect on the server side. If not set explicitly, the ALPN extension will
|
2519
|
+
* not be included in the handshake.
|
2175
2520
|
*
|
2176
2521
|
* === Example
|
2177
2522
|
*
|
@@ -2181,16 +2526,16 @@ Init_ossl_ssl(void)
|
|
2181
2526
|
/*
|
2182
2527
|
* A callback invoked on the server side when the server needs to select
|
2183
2528
|
* a protocol from the list sent by the client. Supported in OpenSSL 1.0.2
|
2184
|
-
* and higher. The
|
2529
|
+
* and higher. The callback must return a protocol of those advertised by
|
2185
2530
|
* the client. If none is acceptable, raising an error in the callback
|
2186
2531
|
* will cause the handshake to fail. Not setting this callback explicitly
|
2187
|
-
* means not supporting the ALPN extension on the
|
2188
|
-
* advertised by the
|
2532
|
+
* means not supporting the ALPN extension on the server - any protocols
|
2533
|
+
* advertised by the client will be ignored.
|
2189
2534
|
*
|
2190
2535
|
* === Example
|
2191
2536
|
*
|
2192
2537
|
* ctx.alpn_select_cb = lambda do |protocols|
|
2193
|
-
* #inspect the protocols and select one
|
2538
|
+
* # inspect the protocols and select one
|
2194
2539
|
* protocols.first
|
2195
2540
|
* end
|
2196
2541
|
*/
|
@@ -2202,28 +2547,32 @@ Init_ossl_ssl(void)
|
|
2202
2547
|
rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1);
|
2203
2548
|
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
|
2204
2549
|
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
|
2550
|
+
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
|
2551
|
+
rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
|
2552
|
+
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
|
2205
2553
|
|
2206
2554
|
rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
|
2555
|
+
rb_define_alias(cSSLContext, "freeze", "setup");
|
2207
2556
|
|
2208
2557
|
/*
|
2209
2558
|
* No session caching for client or server
|
2210
2559
|
*/
|
2211
|
-
rb_define_const(cSSLContext, "SESSION_CACHE_OFF",
|
2560
|
+
rb_define_const(cSSLContext, "SESSION_CACHE_OFF", LONG2NUM(SSL_SESS_CACHE_OFF));
|
2212
2561
|
|
2213
2562
|
/*
|
2214
2563
|
* Client sessions are added to the session cache
|
2215
2564
|
*/
|
2216
|
-
rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT",
|
2565
|
+
rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT", LONG2NUM(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */
|
2217
2566
|
|
2218
2567
|
/*
|
2219
2568
|
* Server sessions are added to the session cache
|
2220
2569
|
*/
|
2221
|
-
rb_define_const(cSSLContext, "SESSION_CACHE_SERVER",
|
2570
|
+
rb_define_const(cSSLContext, "SESSION_CACHE_SERVER", LONG2NUM(SSL_SESS_CACHE_SERVER));
|
2222
2571
|
|
2223
2572
|
/*
|
2224
2573
|
* Both client and server sessions are added to the session cache
|
2225
2574
|
*/
|
2226
|
-
rb_define_const(cSSLContext, "SESSION_CACHE_BOTH",
|
2575
|
+
rb_define_const(cSSLContext, "SESSION_CACHE_BOTH", LONG2NUM(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */
|
2227
2576
|
|
2228
2577
|
/*
|
2229
2578
|
* Normally the session cache is checked for expired sessions every 255
|
@@ -2231,7 +2580,7 @@ Init_ossl_ssl(void)
|
|
2231
2580
|
* the automatic flushing may be disabled and #flush_sessions can be
|
2232
2581
|
* called explicitly.
|
2233
2582
|
*/
|
2234
|
-
rb_define_const(cSSLContext, "SESSION_CACHE_NO_AUTO_CLEAR",
|
2583
|
+
rb_define_const(cSSLContext, "SESSION_CACHE_NO_AUTO_CLEAR", LONG2NUM(SSL_SESS_CACHE_NO_AUTO_CLEAR));
|
2235
2584
|
|
2236
2585
|
/*
|
2237
2586
|
* Always perform external lookups of sessions even if they are in the
|
@@ -2239,18 +2588,18 @@ Init_ossl_ssl(void)
|
|
2239
2588
|
*
|
2240
2589
|
* This flag has no effect on clients
|
2241
2590
|
*/
|
2242
|
-
rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_LOOKUP",
|
2591
|
+
rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_LOOKUP", LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP));
|
2243
2592
|
|
2244
2593
|
/*
|
2245
2594
|
* Never automatically store sessions in the internal store.
|
2246
2595
|
*/
|
2247
|
-
rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_STORE",
|
2596
|
+
rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_STORE", LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL_STORE));
|
2248
2597
|
|
2249
2598
|
/*
|
2250
2599
|
* Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and
|
2251
2600
|
* SESSION_CACHE_NO_INTERNAL_STORE.
|
2252
2601
|
*/
|
2253
|
-
rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL",
|
2602
|
+
rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL", LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL));
|
2254
2603
|
|
2255
2604
|
rb_define_method(cSSLContext, "session_add", ossl_sslctx_session_add, 1);
|
2256
2605
|
rb_define_method(cSSLContext, "session_remove", ossl_sslctx_session_remove, 1);
|
@@ -2273,17 +2622,16 @@ Init_ossl_ssl(void)
|
|
2273
2622
|
|
2274
2623
|
/*
|
2275
2624
|
* Document-class: OpenSSL::SSL::SSLSocket
|
2276
|
-
*
|
2277
|
-
* The following attributes are available but don't show up in rdoc.
|
2278
|
-
* * io, context, sync_close
|
2279
|
-
*
|
2280
2625
|
*/
|
2281
2626
|
cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
|
2282
2627
|
#ifdef OPENSSL_NO_SOCK
|
2283
2628
|
rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue);
|
2629
|
+
rb_define_method(cSSLSocket, "initialize", rb_f_notimplement, -1);
|
2284
2630
|
#else
|
2285
2631
|
rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse);
|
2286
2632
|
rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
|
2633
|
+
rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
|
2634
|
+
rb_undef_method(cSSLSocket, "initialize_copy");
|
2287
2635
|
rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0);
|
2288
2636
|
rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, -1);
|
2289
2637
|
rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0);
|
@@ -2305,6 +2653,13 @@ Init_ossl_ssl(void)
|
|
2305
2653
|
rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1);
|
2306
2654
|
rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
|
2307
2655
|
rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
|
2656
|
+
#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
|
2657
|
+
/* #hostname is defined in lib/openssl/ssl.rb */
|
2658
|
+
rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
|
2659
|
+
#endif
|
2660
|
+
# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
|
2661
|
+
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
|
2662
|
+
# endif
|
2308
2663
|
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
2309
2664
|
rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
|
2310
2665
|
# endif
|
@@ -2328,25 +2683,17 @@ Init_ossl_ssl(void)
|
|
2328
2683
|
ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
|
2329
2684
|
ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG);
|
2330
2685
|
ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER);
|
2331
|
-
#if defined(SSL_OP_MSIE_SSLV2_RSA_PADDING)
|
2332
2686
|
ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING);
|
2333
|
-
#endif
|
2334
2687
|
ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG);
|
2335
2688
|
ossl_ssl_def_const(OP_TLS_D5_BUG);
|
2336
2689
|
ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG);
|
2337
2690
|
ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS);
|
2338
2691
|
ossl_ssl_def_const(OP_ALL);
|
2339
|
-
#if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
|
2340
2692
|
ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
2341
|
-
#endif
|
2342
|
-
#if defined(SSL_OP_SINGLE_ECDH_USE)
|
2343
2693
|
ossl_ssl_def_const(OP_SINGLE_ECDH_USE);
|
2344
|
-
#endif
|
2345
2694
|
ossl_ssl_def_const(OP_SINGLE_DH_USE);
|
2346
2695
|
ossl_ssl_def_const(OP_EPHEMERAL_RSA);
|
2347
|
-
#if defined(SSL_OP_CIPHER_SERVER_PREFERENCE)
|
2348
2696
|
ossl_ssl_def_const(OP_CIPHER_SERVER_PREFERENCE);
|
2349
|
-
#endif
|
2350
2697
|
ossl_ssl_def_const(OP_TLS_ROLLBACK_BUG);
|
2351
2698
|
ossl_ssl_def_const(OP_NO_SSLv2);
|
2352
2699
|
ossl_ssl_def_const(OP_NO_SSLv3);
|
@@ -2368,8 +2715,43 @@ Init_ossl_ssl(void)
|
|
2368
2715
|
ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG);
|
2369
2716
|
ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
|
2370
2717
|
|
2371
|
-
#undef rb_intern
|
2372
2718
|
sym_exception = ID2SYM(rb_intern("exception"));
|
2373
2719
|
sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
|
2374
2720
|
sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
|
2721
|
+
|
2722
|
+
id_tmp_dh_callback = rb_intern("tmp_dh_callback");
|
2723
|
+
id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
|
2724
|
+
id_npn_protocols_encoded = rb_intern("npn_protocols_encoded");
|
2725
|
+
|
2726
|
+
#define DefIVarID(name) do \
|
2727
|
+
id_i_##name = rb_intern("@"#name); while (0)
|
2728
|
+
|
2729
|
+
DefIVarID(cert_store);
|
2730
|
+
DefIVarID(ca_file);
|
2731
|
+
DefIVarID(ca_path);
|
2732
|
+
DefIVarID(verify_mode);
|
2733
|
+
DefIVarID(verify_depth);
|
2734
|
+
DefIVarID(verify_callback);
|
2735
|
+
DefIVarID(client_ca);
|
2736
|
+
DefIVarID(renegotiation_cb);
|
2737
|
+
DefIVarID(cert);
|
2738
|
+
DefIVarID(key);
|
2739
|
+
DefIVarID(extra_chain_cert);
|
2740
|
+
DefIVarID(client_cert_cb);
|
2741
|
+
DefIVarID(tmp_ecdh_callback);
|
2742
|
+
DefIVarID(timeout);
|
2743
|
+
DefIVarID(session_id_context);
|
2744
|
+
DefIVarID(session_get_cb);
|
2745
|
+
DefIVarID(session_new_cb);
|
2746
|
+
DefIVarID(session_remove_cb);
|
2747
|
+
DefIVarID(npn_select_cb);
|
2748
|
+
DefIVarID(npn_protocols);
|
2749
|
+
DefIVarID(alpn_protocols);
|
2750
|
+
DefIVarID(alpn_select_cb);
|
2751
|
+
DefIVarID(servername_cb);
|
2752
|
+
DefIVarID(verify_hostname);
|
2753
|
+
|
2754
|
+
DefIVarID(io);
|
2755
|
+
DefIVarID(context);
|
2756
|
+
DefIVarID(hostname);
|
2375
2757
|
}
|