rubysl-openssl 2.10 → 2.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +5 -5
  2. data/ext/rubysl/openssl/deprecation.rb +7 -3
  3. data/ext/rubysl/openssl/extconf.rb +148 -103
  4. data/ext/rubysl/openssl/openssl_missing.c +94 -275
  5. data/ext/rubysl/openssl/openssl_missing.h +167 -98
  6. data/ext/rubysl/openssl/ossl.c +266 -212
  7. data/ext/rubysl/openssl/ossl.h +27 -89
  8. data/ext/rubysl/openssl/ossl_asn1.c +157 -221
  9. data/ext/rubysl/openssl/ossl_asn1.h +11 -3
  10. data/ext/rubysl/openssl/ossl_bio.c +10 -40
  11. data/ext/rubysl/openssl/ossl_bio.h +1 -2
  12. data/ext/rubysl/openssl/ossl_bn.c +144 -100
  13. data/ext/rubysl/openssl/ossl_bn.h +3 -1
  14. data/ext/rubysl/openssl/ossl_cipher.c +270 -195
  15. data/ext/rubysl/openssl/ossl_config.c +7 -1
  16. data/ext/rubysl/openssl/ossl_config.h +0 -1
  17. data/ext/rubysl/openssl/ossl_digest.c +40 -29
  18. data/ext/rubysl/openssl/ossl_engine.c +23 -62
  19. data/ext/rubysl/openssl/ossl_hmac.c +82 -55
  20. data/ext/rubysl/openssl/ossl_ns_spki.c +22 -22
  21. data/ext/rubysl/openssl/ossl_ocsp.c +894 -144
  22. data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
  23. data/ext/rubysl/openssl/ossl_pkcs12.c +47 -19
  24. data/ext/rubysl/openssl/ossl_pkcs5.c +7 -15
  25. data/ext/rubysl/openssl/ossl_pkcs7.c +38 -15
  26. data/ext/rubysl/openssl/ossl_pkey.c +151 -99
  27. data/ext/rubysl/openssl/ossl_pkey.h +123 -29
  28. data/ext/rubysl/openssl/ossl_pkey_dh.c +143 -92
  29. data/ext/rubysl/openssl/ossl_pkey_dsa.c +149 -104
  30. data/ext/rubysl/openssl/ossl_pkey_ec.c +646 -524
  31. data/ext/rubysl/openssl/ossl_pkey_rsa.c +180 -121
  32. data/ext/rubysl/openssl/ossl_rand.c +25 -21
  33. data/ext/rubysl/openssl/ossl_ssl.c +795 -413
  34. data/ext/rubysl/openssl/ossl_ssl.h +3 -0
  35. data/ext/rubysl/openssl/ossl_ssl_session.c +83 -77
  36. data/ext/rubysl/openssl/ossl_version.h +1 -1
  37. data/ext/rubysl/openssl/ossl_x509.c +92 -8
  38. data/ext/rubysl/openssl/ossl_x509.h +14 -5
  39. data/ext/rubysl/openssl/ossl_x509attr.c +77 -41
  40. data/ext/rubysl/openssl/ossl_x509cert.c +45 -46
  41. data/ext/rubysl/openssl/ossl_x509crl.c +51 -57
  42. data/ext/rubysl/openssl/ossl_x509ext.c +39 -33
  43. data/ext/rubysl/openssl/ossl_x509name.c +68 -45
  44. data/ext/rubysl/openssl/ossl_x509req.c +32 -38
  45. data/ext/rubysl/openssl/ossl_x509revoked.c +43 -9
  46. data/ext/rubysl/openssl/ossl_x509store.c +309 -104
  47. data/ext/rubysl/openssl/ruby_missing.h +8 -6
  48. data/lib/openssl/buffering.rb +11 -5
  49. data/lib/openssl/cipher.rb +23 -15
  50. data/lib/openssl/digest.rb +7 -10
  51. data/lib/openssl/pkey.rb +15 -8
  52. data/lib/openssl/ssl.rb +81 -105
  53. data/lib/rubysl/openssl.rb +1 -4
  54. data/lib/rubysl/openssl/version.rb +1 -1
  55. 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
- * Example:
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("").to_s, 0.0)
50
- * OpenSSL::Random.seed(ary.join("").to_s)
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
- SafeStringValue(filename);
70
+ rb_check_safe_obj(filename);
71
71
 
72
- if(!RAND_load_file(RSTRING_PTR(filename), -1)) {
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
- SafeStringValue(filename);
90
- if (RAND_write_file(RSTRING_PTR(filename)) == -1) {
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
- * Example:
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
- char buf[256];
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
- * Example:
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 (!RAND_pseudo_bytes((unsigned char *)RSTRING_PTR(str), n)) {
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
- SafeStringValue(filename);
167
+ rb_check_safe_obj(filename);
167
168
 
168
- if(!RAND_egd(RSTRING_PTR(filename))) {
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
- SafeStringValue(filename);
189
+ rb_check_safe_obj(filename);
189
190
 
190
- if (!RAND_egd_bytes(RSTRING_PTR(filename), n)) {
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"); /* let rdoc know about mOSSL */
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
- #define ossl_sslctx_set_cert(o,v) rb_iv_set((o),"@cert",(v))
40
- #define ossl_sslctx_set_key(o,v) rb_iv_set((o),"@key",(v))
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
- #define OSSL_SSL_METHOD_ENTRY(name) { #name, (SSL_METHOD *(*)(void))name##_method }
90
- OSSL_SSL_METHOD_ENTRY(TLSv1),
91
- OSSL_SSL_METHOD_ENTRY(TLSv1_server),
92
- OSSL_SSL_METHOD_ENTRY(TLSv1_client),
93
- #if defined(HAVE_TLSV1_2_METHOD) && defined(HAVE_TLSV1_2_SERVER_METHOD) && \
94
- defined(HAVE_TLSV1_2_CLIENT_METHOD)
95
- OSSL_SSL_METHOD_ENTRY(TLSv1_2),
96
- OSSL_SSL_METHOD_ENTRY(TLSv1_2_server),
97
- OSSL_SSL_METHOD_ENTRY(TLSv1_2_client),
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(HAVE_TLSV1_1_METHOD) && defined(HAVE_TLSV1_1_SERVER_METHOD) && \
100
- defined(HAVE_TLSV1_1_CLIENT_METHOD)
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(HAVE_SSLV2_METHOD) && defined(HAVE_SSLV2_SERVER_METHOD) && \
106
- defined(HAVE_SSLV2_CLIENT_METHOD)
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(HAVE_SSLV3_METHOD) && defined(HAVE_SSLV3_SERVER_METHOD) && \
112
- defined(HAVE_SSLV3_CLIENT_METHOD)
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
- OSSL_SSL_METHOD_ENTRY(SSLv23),
118
- OSSL_SSL_METHOD_ENTRY(SSLv23_server),
119
- OSSL_SSL_METHOD_ENTRY(SSLv23_client),
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
- SSL_METHOD *method = NULL;
159
+ SSL_CTX *ctx;
178
160
  const char *s;
179
161
  VALUE m = ssl_method;
180
162
  int i;
181
163
 
182
- SSL_CTX *ctx;
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
- method = ossl_ssl_method_tab[i].func();
189
- break;
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
- return ssl_method;
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
- GetPKeyPtr(key = rb_ary_entry(ary, 1));
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 Qtrue;
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, success;
212
+ VALUE obj, ret;
224
213
 
225
214
  obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
226
- success = rb_protect(ossl_call_client_cert_cb, obj, NULL);
227
- if (!RTEST(success)) return 0;
228
- *x509 = DupX509CertPtr(ossl_ssl_get_x509(obj));
229
- *pkey = DupPKeyPtr(ossl_ssl_get_key(obj));
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
- static VALUE
236
- ossl_call_tmp_dh_callback(VALUE args)
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(rb_ary_entry(args, 0), rb_intern("tmp_dh_callback"), 0);
242
-
243
- if (NIL_P(cb)) return Qfalse;
244
- dh = rb_apply(cb, rb_intern("call"), args);
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 (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) return Qfalse;
247
+ if (EVP_PKEY_base_id(pkey) != args->type)
248
+ return NULL;
247
249
 
248
- return dh;
250
+ return pkey;
249
251
  }
252
+ #endif
250
253
 
251
- static DH*
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 args, dh, rb_ssl;
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
- args = rb_ary_new_from_args(3, rb_ssl, INT2FIX(is_export), INT2FIX(keylength));
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 VALUE
270
- ossl_call_tmp_ecdh_callback(VALUE args)
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 cb, ecdh;
287
+ VALUE rb_ssl;
273
288
  EVP_PKEY *pkey;
289
+ struct tmp_dh_callback_args args;
290
+ int state;
274
291
 
275
- cb = rb_funcall(rb_ary_entry(args, 0), rb_intern("tmp_ecdh_callback"), 0);
276
-
277
- if (NIL_P(cb)) return Qfalse;
278
- ecdh = rb_apply(cb, rb_intern("call"), args);
279
- pkey = GetPKeyPtr(ecdh);
280
- if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) return Qfalse;
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 ecdh;
308
+ return EVP_PKEY_get0_EC_KEY(pkey);
283
309
  }
310
+ #endif
284
311
 
285
- static EC_KEY*
286
- ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
312
+ static VALUE
313
+ call_verify_certificate_identity(VALUE ctx_v)
287
314
  {
288
- VALUE args, ecdh, rb_ssl;
289
-
290
- rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
315
+ X509_STORE_CTX *ctx = (X509_STORE_CTX *)ctx_v;
316
+ SSL *ssl;
317
+ VALUE ssl_obj, hostname, cert_obj;
291
318
 
292
- args = rb_ary_new_from_args(3, rb_ssl, INT2FIX(is_export), INT2FIX(keylength));
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
- ecdh = rb_protect(ossl_call_tmp_ecdh_callback, args, NULL);
295
- if (!RTEST(ecdh)) return NULL;
296
- ossl_ssl_set_tmp_ecdh(rb_ssl, ecdh);
323
+ if (!RTEST(hostname)) {
324
+ rb_warning("verify_hostname requires hostname to be set");
325
+ return Qtrue;
326
+ }
297
327
 
298
- return GetPKeyPtr(ecdh)->pkey.ec;
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
- X509_STORE_CTX_set_ex_data(ctx, ossl_verify_cb_idx, (void*)cb);
311
- return ossl_verify_cb(preverify_ok, ctx);
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
- CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION);
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 = rb_iv_get(sslctx_obj, "@session_remove_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
- CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION);
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((VALUE(*)_((VALUE)))ossl_call_session_remove_cb, ary, &state);
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 = rb_iv_get(ssl_obj, "@context");
480
- if (NIL_P(sslctx_obj)) return Qnil;
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
- rb_iv_set(ssl_obj, "@context", ret_obj);
548
+ rb_ivar_set(ssl_obj, id_i_context, ret_obj);
494
549
  } else if (!NIL_P(ret_obj)) {
495
- ossl_raise(rb_eArgError, "servername_cb must return an OpenSSL::SSL::SSLContext object or nil");
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((VALUE(*)_((VALUE)))ossl_call_servername_cb, ary, &state);
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 = rb_iv_get(ssl_obj, "@context");
540
- if (NIL_P(sslctx_obj)) return;
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) || defined(HAVE_SSL_CTX_SET_ALPN_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 = rb_str_new2("");
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
- static int
572
- ssl_npn_select_cb_common(VALUE cb, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen)
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
- VALUE selected;
575
- long len;
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
- const unsigned char *in_end = in + inlen;
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)len;
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, void *arg)
689
+ ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
690
+ void *arg)
603
691
  {
604
- VALUE sslctx_obj = (VALUE) arg;
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 *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
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 = rb_iv_get(sslctx_obj, "@npn_select_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, outlen, in, inlen);
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, const unsigned char *in, unsigned int inlen, void *arg)
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 = rb_iv_get(sslctx_obj, "@alpn_select_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 state = SSL_state(ssl);
732
+ int is_server = SSL_is_server((SSL *)ssl);
645
733
 
646
- if ((where & SSL_CB_HANDSHAKE_START) &&
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
- if (RTEST(ossl_sslctx_get_tmp_ecdh_cb(self))){
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 = ossl_sslctx_get_cert_store(self);
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
- store = GetX509StorePtr(val); /* NO NEED TO DUP */
728
- SSL_CTX_set_cert_store(ctx, store);
729
- SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1);
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 = ossl_sslctx_get_extra_cert(self);
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 = ossl_sslctx_get_cert(self);
842
+ val = rb_attr_get(self, id_i_cert);
739
843
  cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
740
- val = ossl_sslctx_get_key(self);
741
- key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */
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 = ossl_sslctx_get_client_ca(self);
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 = ossl_sslctx_get_ca_file(self);
777
- ca_file = NIL_P(val) ? NULL : StringValuePtr(val);
778
- val = ossl_sslctx_get_ca_path(self);
779
- ca_path = NIL_P(val) ? NULL : StringValuePtr(val);
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 = ossl_sslctx_get_verify_mode(self);
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(ossl_sslctx_get_client_cert_cb(self)))
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 = ossl_sslctx_get_timeout(self);
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 = ossl_sslctx_get_verify_dep(self);
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 = rb_iv_get(self, "@npn_protocols");
902
+ val = rb_attr_get(self, id_i_npn_protocols);
799
903
  if (!NIL_P(val)) {
800
- rb_iv_set(self, "@_protocols", ssl_encode_npn_protocols(val));
801
- SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *) self);
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(rb_iv_get(self, "@npn_select_cb"))) {
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 = rb_iv_get(self, "@alpn_protocols");
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
- SSL_CTX_set_alpn_protos(ctx, (const unsigned char *)StringValueCStr(rprotos), RSTRING_LENINT(rprotos));
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(rb_iv_get(self, "@alpn_select_cb"))) {
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 = ossl_sslctx_get_sess_id_ctx(self);
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(rb_iv_get(self, "@session_get_cb"))) {
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(rb_iv_get(self, "@session_new_cb"))) {
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(rb_iv_get(self, "@session_remove_cb"))) {
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 = rb_iv_get(self, "@servername_cb");
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, INT2FIX(bits));
869
- rb_ary_push(ary, INT2FIX(alg_bits));
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 ciphers configured for this context.
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
- if(!ctx){
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 ciphers for this context. Note in a server
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 void
1147
- ossl_ssl_shutdown(SSL *ssl)
1148
- {
1149
- int i, rc;
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
- ossl_ssl_setup(VALUE self)
1435
+ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1189
1436
  {
1190
- VALUE io, v_ctx, cb;
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(!ssl){
1197
- #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
1198
- VALUE hostname = rb_iv_get(self, "@hostname");
1199
- #endif
1479
+ if (ssl_started(ssl))
1480
+ return Qtrue;
1200
1481
 
1201
- v_ctx = ossl_ssl_get_ctx(self);
1202
- GetSSLCTX(v_ctx, ctx);
1203
-
1204
- ssl = SSL_new(ctx);
1205
- if (!ssl) {
1206
- ossl_raise(eSSLError, "SSL_new");
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
- VALUE exc = ossl_exc_new(eSSLErrorWaitWritable, "write would block");
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
- VALUE exc = ossl_exc_new(eSSLErrorWaitReadable, "read would block");
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
- ossl_ssl_data_get_struct(self, ssl);
1532
+ GetSSL(self, ssl);
1284
1533
 
1285
- GetOpenFile(ossl_ssl_get_io(self), fptr);
1534
+ GetOpenFile(rb_attr_get(self, id_i_io), fptr);
1286
1535
  for(;;){
1287
1536
  ret = func(ssl);
1288
1537
 
1289
- cb_state = rb_ivar_get(self, ID_callback_state);
1290
- if (!NIL_P(cb_state))
1291
- rb_jump_tag(NUM2INT(cb_state));
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)) str = rb_str_new(0, ilen);
1431
- else{
1432
- StringValue(str);
1433
- rb_str_modify(str);
1434
- rb_str_resize(str, ilen);
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
- if(ilen == 0) return str;
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
- GetOpenFile(ossl_ssl_get_io(self), fptr);
1440
- if (ssl) {
1441
- if(!nonblock && SSL_pending(ssl) <= 0)
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), RSTRING_LENINT(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() == 0 && nread == 0) {
1463
- if (no_exception_p(opts)) { return Qnil; }
1464
- rb_eof_error();
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
- ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
1474
- rb_warning("SSL session is not started yet.");
1475
- if (nonblock) {
1476
- return rb_funcall(ossl_ssl_get_io(self), meth, 3, len, str, opts);
1477
- } else {
1478
- return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str);
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
- GetOpenFile(ossl_ssl_get_io(self), fptr);
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
- ID id_syswrite = rb_intern("syswrite");
1565
- rb_warning("SSL session is not started yet.");
1566
- return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str);
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
- ossl_ssl_data_get_struct(self, ssl);
1615
-
1616
- ossl_ssl_shutdown(ssl);
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
- ossl_ssl_data_get_struct(self, ssl);
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
- ossl_ssl_data_get_struct(self, ssl);
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
- ossl_ssl_data_get_struct(self, ssl);
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
- ossl_ssl_data_get_struct(self, ssl);
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
- ossl_ssl_data_get_struct(self, ssl);
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
- ossl_ssl_data_get_struct(self, ssl);
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
- ossl_ssl_data_get_struct(self, ssl);
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
- ossl_ssl_data_get_struct(self, ssl);
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
- UNREACHABLE;
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
- /* why is ossl_ssl_setup delayed? */
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
- ossl_ssl_data_get_struct(self, ssl);
2141
+ GetSSL(self, ssl);
1838
2142
 
1839
- return INT2FIX(SSL_get_verify_result(ssl));
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
- ossl_ssl_data_get_struct(self, ssl);
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
- ossl_ssl_data_get_struct(self, ssl);
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 client
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
- ossl_ssl_data_get_struct(self, ssl);
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"); /* let rdoc know about mOSSL */
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("@callback_state");
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 stopped.
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
- * An OpenSSL::X509::Store used for certificate verification
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 must return an OpenSSL::PKey::EC instance of the correct
2067
- * key length.
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 Protocol
2172
- * Negotiation. Supported in OpenSSL 1.0.1 and higher. Has no effect
2173
- * on the client side. If not set explicitly, the NPN extension will
2174
- * not be sent by the server in the handshake.
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 server MUST select a protocol of those advertised by
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 client - any protocols
2188
- * advertised by the server will be ignored.
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", LONG2FIX(SSL_SESS_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", LONG2FIX(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */
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", LONG2FIX(SSL_SESS_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", LONG2FIX(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */
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", LONG2FIX(SSL_SESS_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", LONG2FIX(SSL_SESS_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", LONG2FIX(SSL_SESS_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", LONG2FIX(SSL_SESS_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
  }