rubysl-openssl 2.10 → 2.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|