rubysl-openssl 1.0.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -6
  3. data/ext/rubysl/openssl/.gitignore +3 -0
  4. data/ext/rubysl/openssl/deprecation.rb +21 -0
  5. data/ext/rubysl/openssl/extconf.rb +45 -32
  6. data/ext/rubysl/openssl/openssl_missing.c +20 -7
  7. data/ext/rubysl/openssl/openssl_missing.h +22 -15
  8. data/ext/rubysl/openssl/ossl.c +610 -61
  9. data/ext/rubysl/openssl/ossl.h +31 -17
  10. data/ext/rubysl/openssl/ossl_asn1.c +974 -183
  11. data/ext/rubysl/openssl/ossl_asn1.h +3 -3
  12. data/ext/rubysl/openssl/ossl_bio.c +4 -3
  13. data/ext/rubysl/openssl/ossl_bio.h +1 -1
  14. data/ext/rubysl/openssl/ossl_bn.c +32 -28
  15. data/ext/rubysl/openssl/ossl_bn.h +1 -1
  16. data/ext/rubysl/openssl/ossl_cipher.c +494 -93
  17. data/ext/rubysl/openssl/ossl_cipher.h +1 -1
  18. data/ext/rubysl/openssl/ossl_config.c +4 -5
  19. data/ext/rubysl/openssl/ossl_config.h +1 -1
  20. data/ext/rubysl/openssl/ossl_digest.c +206 -24
  21. data/ext/rubysl/openssl/ossl_digest.h +1 -1
  22. data/ext/rubysl/openssl/ossl_engine.c +48 -26
  23. data/ext/rubysl/openssl/ossl_engine.h +1 -1
  24. data/ext/rubysl/openssl/ossl_hmac.c +40 -38
  25. data/ext/rubysl/openssl/ossl_hmac.h +1 -1
  26. data/ext/rubysl/openssl/ossl_ns_spki.c +157 -25
  27. data/ext/rubysl/openssl/ossl_ns_spki.h +1 -1
  28. data/ext/rubysl/openssl/ossl_ocsp.c +57 -40
  29. data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
  30. data/ext/rubysl/openssl/ossl_pkcs12.c +15 -13
  31. data/ext/rubysl/openssl/ossl_pkcs12.h +1 -1
  32. data/ext/rubysl/openssl/ossl_pkcs5.c +108 -18
  33. data/ext/rubysl/openssl/ossl_pkcs7.c +44 -37
  34. data/ext/rubysl/openssl/ossl_pkcs7.h +1 -1
  35. data/ext/rubysl/openssl/ossl_pkey.c +211 -15
  36. data/ext/rubysl/openssl/ossl_pkey.h +19 -9
  37. data/ext/rubysl/openssl/ossl_pkey_dh.c +180 -47
  38. data/ext/rubysl/openssl/ossl_pkey_dsa.c +184 -47
  39. data/ext/rubysl/openssl/ossl_pkey_ec.c +177 -93
  40. data/ext/rubysl/openssl/ossl_pkey_rsa.c +209 -102
  41. data/ext/rubysl/openssl/ossl_rand.c +15 -15
  42. data/ext/rubysl/openssl/ossl_rand.h +1 -1
  43. data/ext/rubysl/openssl/ossl_ssl.c +939 -192
  44. data/ext/rubysl/openssl/ossl_ssl.h +6 -6
  45. data/ext/rubysl/openssl/ossl_ssl_session.c +78 -62
  46. data/ext/rubysl/openssl/ossl_version.h +2 -2
  47. data/ext/rubysl/openssl/ossl_x509.c +1 -1
  48. data/ext/rubysl/openssl/ossl_x509.h +1 -1
  49. data/ext/rubysl/openssl/ossl_x509attr.c +20 -19
  50. data/ext/rubysl/openssl/ossl_x509cert.c +169 -67
  51. data/ext/rubysl/openssl/ossl_x509crl.c +41 -39
  52. data/ext/rubysl/openssl/ossl_x509ext.c +51 -38
  53. data/ext/rubysl/openssl/ossl_x509name.c +139 -29
  54. data/ext/rubysl/openssl/ossl_x509req.c +42 -40
  55. data/ext/rubysl/openssl/ossl_x509revoked.c +20 -20
  56. data/ext/rubysl/openssl/ossl_x509store.c +99 -47
  57. data/ext/rubysl/openssl/ruby_missing.h +3 -16
  58. data/lib/openssl/bn.rb +19 -19
  59. data/lib/openssl/buffering.rb +222 -14
  60. data/lib/openssl/cipher.rb +20 -20
  61. data/lib/openssl/config.rb +1 -4
  62. data/lib/openssl/digest.rb +47 -19
  63. data/lib/openssl/ssl.rb +197 -1
  64. data/lib/openssl/x509.rb +162 -1
  65. data/lib/rubysl/openssl.rb +4 -8
  66. data/lib/rubysl/openssl/version.rb +1 -1
  67. data/rubysl-openssl.gemspec +1 -2
  68. metadata +16 -34
  69. data/ext/rubysl/openssl/extconf.h +0 -50
  70. data/lib/openssl/net/ftptls.rb +0 -53
  71. data/lib/openssl/net/telnets.rb +0 -251
  72. data/lib/openssl/pkcs7.rb +0 -25
  73. data/lib/openssl/ssl-internal.rb +0 -187
  74. data/lib/openssl/x509-internal.rb +0 -153
@@ -1,5 +1,5 @@
1
1
  /*
2
- * $Id: ossl_rand.c 16692 2008-05-29 18:15:50Z knu $
2
+ * $Id$
3
3
  * 'OpenSSL for Ruby' project
4
4
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
5
  * All rights reserved.
@@ -37,7 +37,7 @@ static VALUE
37
37
  ossl_rand_seed(VALUE self, VALUE str)
38
38
  {
39
39
  StringValue(str);
40
- RAND_seed(RSTRING_PTR(str), RSTRING_LEN(str));
40
+ RAND_seed(RSTRING_PTR(str), RSTRING_LENINT(str));
41
41
 
42
42
  return str;
43
43
  }
@@ -51,7 +51,7 @@ static VALUE
51
51
  ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
52
52
  {
53
53
  StringValue(str);
54
- RAND_add(RSTRING_PTR(str), RSTRING_LEN(str), NUM2DBL(entropy));
54
+ RAND_add(RSTRING_PTR(str), RSTRING_LENINT(str), NUM2DBL(entropy));
55
55
 
56
56
  return self;
57
57
  }
@@ -65,7 +65,7 @@ static VALUE
65
65
  ossl_rand_load_file(VALUE self, VALUE filename)
66
66
  {
67
67
  SafeStringValue(filename);
68
-
68
+
69
69
  if(!RAND_load_file(RSTRING_PTR(filename), -1)) {
70
70
  ossl_raise(eRandomError, NULL);
71
71
  }
@@ -99,7 +99,7 @@ ossl_rand_bytes(VALUE self, VALUE len)
99
99
  int n = NUM2INT(len);
100
100
 
101
101
  str = rb_str_new(0, n);
102
- if (!RAND_bytes(RSTRING_PTR(str), n)) {
102
+ if (!RAND_bytes((unsigned char *)RSTRING_PTR(str), n)) {
103
103
  ossl_raise(eRandomError, NULL);
104
104
  }
105
105
 
@@ -118,7 +118,7 @@ ossl_rand_pseudo_bytes(VALUE self, VALUE len)
118
118
  int n = NUM2INT(len);
119
119
 
120
120
  str = rb_str_new(0, n);
121
- if (!RAND_pseudo_bytes(RSTRING_PTR(str), n)) {
121
+ if (!RAND_pseudo_bytes((unsigned char *)RSTRING_PTR(str), n)) {
122
122
  ossl_raise(eRandomError, NULL);
123
123
  }
124
124
 
@@ -134,7 +134,7 @@ static VALUE
134
134
  ossl_rand_egd(VALUE self, VALUE filename)
135
135
  {
136
136
  SafeStringValue(filename);
137
-
137
+
138
138
  if(!RAND_egd(RSTRING_PTR(filename))) {
139
139
  ossl_raise(eRandomError, NULL);
140
140
  }
@@ -149,7 +149,7 @@ ossl_rand_egd(VALUE self, VALUE filename)
149
149
  static VALUE
150
150
  ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
151
151
  {
152
- long n = NUM2INT(len);
152
+ int n = NUM2INT(len);
153
153
 
154
154
  SafeStringValue(filename);
155
155
 
@@ -172,8 +172,8 @@ ossl_rand_status(VALUE self)
172
172
  }
173
173
 
174
174
  #define DEFMETH(class, name, func, argc) \
175
- rb_define_method(class, name, func, argc); \
176
- rb_define_singleton_method(class, name, func, argc);
175
+ rb_define_method((class), (name), (func), (argc)); \
176
+ rb_define_singleton_method((class), (name), (func), (argc));
177
177
 
178
178
  /*
179
179
  * INIT
@@ -181,14 +181,14 @@ ossl_rand_status(VALUE self)
181
181
  void
182
182
  Init_ossl_rand()
183
183
  {
184
- #if 0 /* let rdoc know about mOSSL */
185
- mOSSL = rb_define_module("OpenSSL");
184
+ #if 0
185
+ mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
186
186
  #endif
187
187
 
188
188
  mRandom = rb_define_module_under(mOSSL, "Random");
189
-
189
+
190
190
  eRandomError = rb_define_class_under(mRandom, "RandomError", eOSSLError);
191
-
191
+
192
192
  DEFMETH(mRandom, "seed", ossl_rand_seed, 1);
193
193
  DEFMETH(mRandom, "random_add", ossl_rand_add, 2);
194
194
  DEFMETH(mRandom, "load_random_file", ossl_rand_load_file, 1);
@@ -196,7 +196,7 @@ Init_ossl_rand()
196
196
  DEFMETH(mRandom, "random_bytes", ossl_rand_bytes, 1);
197
197
  DEFMETH(mRandom, "pseudo_bytes", ossl_rand_pseudo_bytes, 1);
198
198
  DEFMETH(mRandom, "egd", ossl_rand_egd, 1);
199
- DEFMETH(mRandom, "egd_bytes", ossl_rand_egd_bytes, 2);
199
+ DEFMETH(mRandom, "egd_bytes", ossl_rand_egd_bytes, 2);
200
200
  DEFMETH(mRandom, "status?", ossl_rand_status, 0)
201
201
  }
202
202
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- * $Id: ossl_rand.h 11708 2007-02-12 23:01:19Z shyouhei $
2
+ * $Id$
3
3
  * 'OpenSSL for Ruby' project
4
4
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
5
  * All rights reserved.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * $Id: ossl_ssl.c 32234 2011-06-26 08:58:06Z shyouhei $
2
+ * $Id$
3
3
  * 'OpenSSL for Ruby' project
4
4
  * Copyright (C) 2000-2002 GOTOU Yuuzou <gotoyuzo@notwork.org>
5
5
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
@@ -11,19 +11,17 @@
11
11
  * (See the file 'LICENCE'.)
12
12
  */
13
13
  #include "ossl.h"
14
- #include <rubysig.h>
15
- #include <rubyio.h>
16
14
 
17
15
  #if defined(HAVE_UNISTD_H)
18
16
  # include <unistd.h> /* for read(), and write() */
19
17
  #endif
20
18
 
21
- #define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
19
+ #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
22
20
 
23
21
  #ifdef _WIN32
24
22
  # define TO_SOCKET(s) _get_osfhandle(s)
25
23
  #else
26
- # define TO_SOCKET(s) s
24
+ # define TO_SOCKET(s) (s)
27
25
  #endif
28
26
 
29
27
  VALUE mSSL;
@@ -31,44 +29,51 @@ VALUE eSSLError;
31
29
  VALUE cSSLContext;
32
30
  VALUE cSSLSocket;
33
31
 
34
- #define ossl_sslctx_set_cert(o,v) rb_iv_set((o),"@cert",(v))
35
- #define ossl_sslctx_set_key(o,v) rb_iv_set((o),"@key",(v))
36
- #define ossl_sslctx_set_client_ca(o,v) rb_iv_set((o),"@client_ca",(v))
37
- #define ossl_sslctx_set_ca_file(o,v) rb_iv_set((o),"@ca_file",(v))
38
- #define ossl_sslctx_set_ca_path(o,v) rb_iv_set((o),"@ca_path",(v))
39
- #define ossl_sslctx_set_timeout(o,v) rb_iv_set((o),"@timeout",(v))
40
- #define ossl_sslctx_set_verify_mode(o,v) rb_iv_set((o),"@verify_mode",(v))
41
- #define ossl_sslctx_set_verify_dep(o,v) rb_iv_set((o),"@verify_depth",(v))
42
- #define ossl_sslctx_set_verify_cb(o,v) rb_iv_set((o),"@verify_callback",(v))
43
- #define ossl_sslctx_set_options(o,v) rb_iv_set((o),"@options",(v))
44
- #define ossl_sslctx_set_cert_store(o,v) rb_iv_set((o),"@cert_store",(v))
45
- #define ossl_sslctx_set_extra_cert(o,v) rb_iv_set((o),"@extra_chain_cert",(v))
46
- #define ossl_sslctx_set_client_cert_cb(o,v) rb_iv_set((o),"@client_cert_cb",(v))
47
- #define ossl_sslctx_set_tmp_dh_cb(o,v) rb_iv_set((o),"@tmp_dh_callback",(v))
48
- #define ossl_sslctx_set_sess_id_ctx(o, v) rb_iv_get((o),"@session_id_context"(v))
49
-
50
- #define ossl_sslctx_get_cert(o) rb_iv_get((o),"@cert")
51
- #define ossl_sslctx_get_key(o) rb_iv_get((o),"@key")
52
- #define ossl_sslctx_get_client_ca(o) rb_iv_get((o),"@client_ca")
53
- #define ossl_sslctx_get_ca_file(o) rb_iv_get((o),"@ca_file")
54
- #define ossl_sslctx_get_ca_path(o) rb_iv_get((o),"@ca_path")
55
- #define ossl_sslctx_get_timeout(o) rb_iv_get((o),"@timeout")
56
- #define ossl_sslctx_get_verify_mode(o) rb_iv_get((o),"@verify_mode")
57
- #define ossl_sslctx_get_verify_dep(o) rb_iv_get((o),"@verify_depth")
58
- #define ossl_sslctx_get_verify_cb(o) rb_iv_get((o),"@verify_callback")
59
- #define ossl_sslctx_get_options(o) rb_iv_get((o),"@options")
60
- #define ossl_sslctx_get_cert_store(o) rb_iv_get((o),"@cert_store")
61
- #define ossl_sslctx_get_extra_cert(o) rb_iv_get((o),"@extra_chain_cert")
62
- #define ossl_sslctx_get_client_cert_cb(o) rb_iv_get((o),"@client_cert_cb")
63
- #define ossl_sslctx_get_tmp_dh_cb(o) rb_iv_get((o),"@tmp_dh_callback")
64
- #define ossl_sslctx_get_sess_id_ctx(o) rb_iv_get((o),"@session_id_context")
32
+ #define ossl_sslctx_set_cert(o,v) rb_iv_set((o),"@cert",(v))
33
+ #define ossl_sslctx_set_key(o,v) rb_iv_set((o),"@key",(v))
34
+ #define ossl_sslctx_set_client_ca(o,v) rb_iv_set((o),"@client_ca",(v))
35
+ #define ossl_sslctx_set_ca_file(o,v) rb_iv_set((o),"@ca_file",(v))
36
+ #define ossl_sslctx_set_ca_path(o,v) rb_iv_set((o),"@ca_path",(v))
37
+ #define ossl_sslctx_set_timeout(o,v) rb_iv_set((o),"@timeout",(v))
38
+ #define ossl_sslctx_set_verify_mode(o,v) rb_iv_set((o),"@verify_mode",(v))
39
+ #define ossl_sslctx_set_verify_dep(o,v) rb_iv_set((o),"@verify_depth",(v))
40
+ #define ossl_sslctx_set_verify_cb(o,v) rb_iv_set((o),"@verify_callback",(v))
41
+ #define ossl_sslctx_set_options(o,v) rb_iv_set((o),"@options",(v))
42
+ #define ossl_sslctx_set_cert_store(o,v) rb_iv_set((o),"@cert_store",(v))
43
+ #define ossl_sslctx_set_extra_cert(o,v) rb_iv_set((o),"@extra_chain_cert",(v))
44
+ #define ossl_sslctx_set_client_cert_cb(o,v) rb_iv_set((o),"@client_cert_cb",(v))
45
+ #define ossl_sslctx_set_tmp_dh_cb(o,v) rb_iv_set((o),"@tmp_dh_callback",(v))
46
+ #define ossl_sslctx_set_sess_id_ctx(o, v) rb_iv_set((o),"@session_id_context",(v))
47
+
48
+ #define ossl_sslctx_get_cert(o) rb_iv_get((o),"@cert")
49
+ #define ossl_sslctx_get_key(o) rb_iv_get((o),"@key")
50
+ #define ossl_sslctx_get_client_ca(o) rb_iv_get((o),"@client_ca")
51
+ #define ossl_sslctx_get_ca_file(o) rb_iv_get((o),"@ca_file")
52
+ #define ossl_sslctx_get_ca_path(o) rb_iv_get((o),"@ca_path")
53
+ #define ossl_sslctx_get_timeout(o) rb_iv_get((o),"@timeout")
54
+ #define ossl_sslctx_get_verify_mode(o) rb_iv_get((o),"@verify_mode")
55
+ #define ossl_sslctx_get_verify_dep(o) rb_iv_get((o),"@verify_depth")
56
+ #define ossl_sslctx_get_verify_cb(o) rb_iv_get((o),"@verify_callback")
57
+ #define ossl_sslctx_get_options(o) rb_iv_get((o),"@options")
58
+ #define ossl_sslctx_get_cert_store(o) rb_iv_get((o),"@cert_store")
59
+ #define ossl_sslctx_get_extra_cert(o) rb_iv_get((o),"@extra_chain_cert")
60
+ #define ossl_sslctx_get_client_cert_cb(o) rb_iv_get((o),"@client_cert_cb")
61
+ #define ossl_sslctx_get_tmp_dh_cb(o) rb_iv_get((o),"@tmp_dh_callback")
62
+ #define ossl_sslctx_get_sess_id_ctx(o) rb_iv_get((o),"@session_id_context")
65
63
 
66
64
  static const char *ossl_sslctx_attrs[] = {
67
65
  "cert", "key", "client_ca", "ca_file", "ca_path",
68
- "timeout", "verify_mode", "verify_depth",
66
+ "timeout", "verify_mode", "verify_depth", "renegotiation_cb",
69
67
  "verify_callback", "options", "cert_store", "extra_chain_cert",
70
68
  "client_cert_cb", "tmp_dh_callback", "session_id_context",
71
69
  "session_get_cb", "session_new_cb", "session_remove_cb",
70
+ #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
71
+ "servername_cb",
72
+ #endif
73
+ #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
74
+ "npn_protocols",
75
+ "npn_select_cb",
76
+ #endif
72
77
  };
73
78
 
74
79
  #define ossl_ssl_get_io(o) rb_iv_get((o),"@io")
@@ -86,7 +91,12 @@ static const char *ossl_sslctx_attrs[] = {
86
91
  #define ossl_ssl_set_tmp_dh(o,v) rb_iv_set((o),"@tmp_dh",(v))
87
92
 
88
93
  static const char *ossl_ssl_attr_readers[] = { "io", "context", };
89
- static const char *ossl_ssl_attrs[] = { "sync_close", };
94
+ static const char *ossl_ssl_attrs[] = {
95
+ #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
96
+ "hostname",
97
+ #endif
98
+ "sync_close",
99
+ };
90
100
 
91
101
  ID ID_callback_state;
92
102
 
@@ -97,12 +107,24 @@ struct {
97
107
  const char *name;
98
108
  SSL_METHOD *(*func)(void);
99
109
  } ossl_ssl_method_tab[] = {
100
- #define OSSL_SSL_METHOD_ENTRY(name) { #name, name##_method }
110
+ #define OSSL_SSL_METHOD_ENTRY(name) { #name, (SSL_METHOD *(*)(void))name##_method }
101
111
  OSSL_SSL_METHOD_ENTRY(TLSv1),
102
112
  OSSL_SSL_METHOD_ENTRY(TLSv1_server),
103
113
  OSSL_SSL_METHOD_ENTRY(TLSv1_client),
114
+ #if defined(HAVE_TLSV1_2_METHOD) && defined(HAVE_TLSV1_2_SERVER_METHOD) && \
115
+ defined(HAVE_TLSV1_2_CLIENT_METHOD)
116
+ OSSL_SSL_METHOD_ENTRY(TLSv1_2),
117
+ OSSL_SSL_METHOD_ENTRY(TLSv1_2_server),
118
+ OSSL_SSL_METHOD_ENTRY(TLSv1_2_client),
119
+ #endif
120
+ #if defined(HAVE_TLSV1_1_METHOD) && defined(HAVE_TLSV1_1_SERVER_METHOD) && \
121
+ defined(HAVE_TLSV1_1_CLIENT_METHOD)
122
+ OSSL_SSL_METHOD_ENTRY(TLSv1_1),
123
+ OSSL_SSL_METHOD_ENTRY(TLSv1_1_server),
124
+ OSSL_SSL_METHOD_ENTRY(TLSv1_1_client),
125
+ #endif
104
126
  #if defined(HAVE_SSLV2_METHOD) && defined(HAVE_SSLV2_SERVER_METHOD) && \
105
- defined(HAVE_SSLV2_CLIENT_METHOD)
127
+ defined(HAVE_SSLV2_CLIENT_METHOD)
106
128
  OSSL_SSL_METHOD_ENTRY(SSLv2),
107
129
  OSSL_SSL_METHOD_ENTRY(SSLv2_server),
108
130
  OSSL_SSL_METHOD_ENTRY(SSLv2_client),
@@ -134,15 +156,27 @@ static VALUE
134
156
  ossl_sslctx_s_alloc(VALUE klass)
135
157
  {
136
158
  SSL_CTX *ctx;
159
+ long mode = SSL_MODE_ENABLE_PARTIAL_WRITE;
160
+
161
+ #ifdef SSL_MODE_RELEASE_BUFFERS
162
+ mode |= SSL_MODE_RELEASE_BUFFERS;
163
+ #endif
137
164
 
138
165
  ctx = SSL_CTX_new(SSLv23_method());
139
166
  if (!ctx) {
140
- ossl_raise(eSSLError, "SSL_CTX_new:");
167
+ ossl_raise(eSSLError, "SSL_CTX_new");
141
168
  }
142
- SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
169
+ SSL_CTX_set_mode(ctx, mode);
143
170
  return Data_Wrap_Struct(klass, 0, ossl_sslctx_free, ctx);
144
171
  }
145
172
 
173
+ /*
174
+ * call-seq:
175
+ * ctx.ssl_version = :TLSv1
176
+ * ctx.ssl_version = "SSLv23_client"
177
+ *
178
+ * You can get a list of valid versions with OpenSSL::SSL::SSLContext::METHODS
179
+ */
146
180
  static VALUE
147
181
  ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
148
182
  {
@@ -166,7 +200,7 @@ ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
166
200
  }
167
201
  Data_Get_Struct(self, SSL_CTX, ctx);
168
202
  if (SSL_CTX_set_ssl_version(ctx, method) != 1) {
169
- ossl_raise(eSSLError, "SSL_CTX_set_ssl_version:");
203
+ ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");
170
204
  }
171
205
 
172
206
  return ssl_method;
@@ -221,13 +255,12 @@ ossl_call_client_cert_cb(VALUE obj)
221
255
  static int
222
256
  ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
223
257
  {
224
- VALUE obj;
225
- int status, success;
258
+ VALUE obj, success;
226
259
 
227
260
  obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
228
261
  success = rb_protect((VALUE(*)_((VALUE)))ossl_call_client_cert_cb,
229
- obj, &status);
230
- if (status || !success) return 0;
262
+ obj, NULL);
263
+ if (!RTEST(success)) return 0;
231
264
  *x509 = DupX509CertPtr(ossl_ssl_get_x509(obj));
232
265
  *pkey = DupPKeyPtr(ossl_ssl_get_key(obj));
233
266
 
@@ -256,15 +289,14 @@ ossl_call_tmp_dh_callback(VALUE *args)
256
289
  static DH*
257
290
  ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
258
291
  {
259
- VALUE args[3];
260
- int status, success;
292
+ VALUE args[3], success;
261
293
 
262
294
  args[0] = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
263
295
  args[1] = INT2FIX(is_export);
264
296
  args[2] = INT2FIX(keylength);
265
297
  success = rb_protect((VALUE(*)_((VALUE)))ossl_call_tmp_dh_callback,
266
- (VALUE)args, &status);
267
- if (status || !success) return NULL;
298
+ (VALUE)args, NULL);
299
+ if (!RTEST(success)) return NULL;
268
300
 
269
301
  return GetPKeyPtr(ossl_ssl_get_tmp_dh(args[0]))->pkey.dh;
270
302
  }
@@ -299,8 +331,8 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
299
331
  static VALUE
300
332
  ossl_call_session_get_cb(VALUE ary)
301
333
  {
302
- VALUE ssl_obj, sslctx_obj, cb, ret;
303
-
334
+ VALUE ssl_obj, sslctx_obj, cb;
335
+
304
336
  Check_Type(ary, T_ARRAY);
305
337
  ssl_obj = rb_ary_entry(ary, 0);
306
338
 
@@ -327,7 +359,7 @@ ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
327
359
  ssl_obj = (VALUE)ptr;
328
360
  ary = rb_ary_new2(2);
329
361
  rb_ary_push(ary, ssl_obj);
330
- rb_ary_push(ary, rb_str_new(buf, len));
362
+ rb_ary_push(ary, rb_str_new((const char *)buf, len));
331
363
 
332
364
  ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_get_cb, ary, &state);
333
365
  if (state) {
@@ -346,8 +378,8 @@ ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
346
378
  static VALUE
347
379
  ossl_call_session_new_cb(VALUE ary)
348
380
  {
349
- VALUE ssl_obj, sslctx_obj, cb, ret;
350
-
381
+ VALUE ssl_obj, sslctx_obj, cb;
382
+
351
383
  Check_Type(ary, T_ARRAY);
352
384
  ssl_obj = rb_ary_entry(ary, 0);
353
385
 
@@ -363,7 +395,7 @@ ossl_call_session_new_cb(VALUE ary)
363
395
  static int
364
396
  ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
365
397
  {
366
- VALUE ary, ssl_obj, sess_obj, ret_obj;
398
+ VALUE ary, ssl_obj, sess_obj;
367
399
  void *ptr;
368
400
  int state = 0;
369
401
 
@@ -380,20 +412,26 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
380
412
  rb_ary_push(ary, ssl_obj);
381
413
  rb_ary_push(ary, sess_obj);
382
414
 
383
- ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state);
415
+ rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state);
384
416
  if (state) {
385
417
  rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
386
- return 0; /* what should be returned here??? */
387
418
  }
388
419
 
389
- return RTEST(ret_obj) ? 1 : 0;
420
+ /*
421
+ * return 0 which means to OpenSSL that the the session is still
422
+ * valid (since we created Ruby Session object) and was not freed by us
423
+ * with SSL_SESSION_free(). Call SSLContext#remove_session(sess) in
424
+ * session_get_cb block if you don't want OpenSSL to cache the session
425
+ * internally.
426
+ */
427
+ return 0;
390
428
  }
391
429
 
392
430
  static VALUE
393
431
  ossl_call_session_remove_cb(VALUE ary)
394
432
  {
395
- VALUE sslctx_obj, cb, ret;
396
-
433
+ VALUE sslctx_obj, cb;
434
+
397
435
  Check_Type(ary, T_ARRAY);
398
436
  sslctx_obj = rb_ary_entry(ary, 0);
399
437
 
@@ -406,7 +444,7 @@ ossl_call_session_remove_cb(VALUE ary)
406
444
  static void
407
445
  ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
408
446
  {
409
- VALUE ary, sslctx_obj, sess_obj, ret_obj;
447
+ VALUE ary, sslctx_obj, sess_obj;
410
448
  void *ptr;
411
449
  int state = 0;
412
450
 
@@ -423,7 +461,7 @@ ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
423
461
  rb_ary_push(ary, sslctx_obj);
424
462
  rb_ary_push(ary, sess_obj);
425
463
 
426
- ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state);
464
+ rb_protect((VALUE(*)_((VALUE)))ossl_call_session_remove_cb, ary, &state);
427
465
  if (state) {
428
466
  /*
429
467
  the SSL_CTX is frozen, nowhere to save state.
@@ -448,13 +486,167 @@ ossl_sslctx_add_extra_chain_cert_i(VALUE i, VALUE arg)
448
486
  return i;
449
487
  }
450
488
 
489
+ static VALUE ossl_sslctx_setup(VALUE self);
490
+
491
+ #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
492
+ static VALUE
493
+ ossl_call_servername_cb(VALUE ary)
494
+ {
495
+ VALUE ssl_obj, sslctx_obj, cb, ret_obj;
496
+
497
+ Check_Type(ary, T_ARRAY);
498
+ ssl_obj = rb_ary_entry(ary, 0);
499
+
500
+ sslctx_obj = rb_iv_get(ssl_obj, "@context");
501
+ if (NIL_P(sslctx_obj)) return Qnil;
502
+ cb = rb_iv_get(sslctx_obj, "@servername_cb");
503
+ if (NIL_P(cb)) return Qnil;
504
+
505
+ ret_obj = rb_funcall(cb, rb_intern("call"), 1, ary);
506
+ if (rb_obj_is_kind_of(ret_obj, cSSLContext)) {
507
+ SSL *ssl;
508
+ SSL_CTX *ctx2;
509
+
510
+ ossl_sslctx_setup(ret_obj);
511
+ Data_Get_Struct(ssl_obj, SSL, ssl);
512
+ Data_Get_Struct(ret_obj, SSL_CTX, ctx2);
513
+ SSL_set_SSL_CTX(ssl, ctx2);
514
+ } else if (!NIL_P(ret_obj)) {
515
+ ossl_raise(rb_eArgError, "servername_cb must return an OpenSSL::SSL::SSLContext object or nil");
516
+ }
517
+
518
+ return ret_obj;
519
+ }
520
+
521
+ static int
522
+ ssl_servername_cb(SSL *ssl, int *ad, void *arg)
523
+ {
524
+ VALUE ary, ssl_obj;
525
+ void *ptr;
526
+ int state = 0;
527
+ const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
528
+
529
+ if (!servername)
530
+ return SSL_TLSEXT_ERR_OK;
531
+
532
+ if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
533
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
534
+ ssl_obj = (VALUE)ptr;
535
+ ary = rb_ary_new2(2);
536
+ rb_ary_push(ary, ssl_obj);
537
+ rb_ary_push(ary, rb_str_new2(servername));
538
+
539
+ rb_protect((VALUE(*)_((VALUE)))ossl_call_servername_cb, ary, &state);
540
+ if (state) {
541
+ rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
542
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
543
+ }
544
+
545
+ return SSL_TLSEXT_ERR_OK;
546
+ }
547
+ #endif
548
+
549
+ static void
550
+ ssl_renegotiation_cb(const SSL *ssl)
551
+ {
552
+ VALUE ssl_obj, sslctx_obj, cb;
553
+ void *ptr;
554
+
555
+ if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
556
+ ossl_raise(eSSLError, "SSL object could not be retrieved");
557
+ ssl_obj = (VALUE)ptr;
558
+
559
+ sslctx_obj = rb_iv_get(ssl_obj, "@context");
560
+ if (NIL_P(sslctx_obj)) return;
561
+ cb = rb_iv_get(sslctx_obj, "@renegotiation_cb");
562
+ if (NIL_P(cb)) return;
563
+
564
+ (void) rb_funcall(cb, rb_intern("call"), 1, ssl_obj);
565
+ }
566
+
567
+ #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
568
+ static VALUE
569
+ ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
570
+ {
571
+ int len = RSTRING_LENINT(cur);
572
+ char len_byte;
573
+ if (len < 1 || len > 255)
574
+ ossl_raise(eSSLError, "Advertised protocol must have length 1..255");
575
+ /* Encode the length byte */
576
+ len_byte = len;
577
+ rb_str_buf_cat(encoded, &len_byte, 1);
578
+ rb_str_buf_cat(encoded, RSTRING_PTR(cur), len);
579
+ return Qnil;
580
+ }
581
+
582
+ static void
583
+ ssl_npn_encode_protocols(VALUE sslctx, VALUE protocols)
584
+ {
585
+ VALUE encoded = rb_str_new2("");
586
+ rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded);
587
+ StringValueCStr(encoded);
588
+ rb_iv_set(sslctx, "@_protocols", encoded);
589
+ }
590
+
591
+ static int
592
+ ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg)
593
+ {
594
+ VALUE sslctx_obj = (VALUE) arg;
595
+ VALUE protocols = rb_iv_get(sslctx_obj, "@_protocols");
596
+
597
+ *out = (const unsigned char *) RSTRING_PTR(protocols);
598
+ *outlen = RSTRING_LENINT(protocols);
599
+
600
+ return SSL_TLSEXT_ERR_OK;
601
+ }
602
+
603
+ static int
604
+ ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
605
+ {
606
+ int i = 0;
607
+ VALUE sslctx_obj, cb, protocols, selected;
608
+
609
+ sslctx_obj = (VALUE) arg;
610
+ cb = rb_iv_get(sslctx_obj, "@npn_select_cb");
611
+ protocols = rb_ary_new();
612
+
613
+ /* The format is len_1|proto_1|...|len_n|proto_n\0 */
614
+ while (in[i]) {
615
+ VALUE protocol = rb_str_new((const char *) &in[i + 1], in[i]);
616
+ rb_ary_push(protocols, protocol);
617
+ i += in[i] + 1;
618
+ }
619
+
620
+ selected = rb_funcall(cb, rb_intern("call"), 1, protocols);
621
+ StringValue(selected);
622
+ *out = (unsigned char *) StringValuePtr(selected);
623
+ *outlen = RSTRING_LENINT(selected);
624
+
625
+ return SSL_TLSEXT_ERR_OK;
626
+ }
627
+ #endif
628
+
629
+ /* This function may serve as the entry point to support further
630
+ * callbacks. */
631
+ static void
632
+ ssl_info_cb(const SSL *ssl, int where, int val)
633
+ {
634
+ int state = SSL_state(ssl);
635
+
636
+ if ((where & SSL_CB_HANDSHAKE_START) &&
637
+ (state & SSL_ST_ACCEPT)) {
638
+ ssl_renegotiation_cb(ssl);
639
+ }
640
+ }
641
+
451
642
  /*
452
643
  * call-seq:
453
644
  * ctx.setup => Qtrue # first time
454
645
  * ctx.setup => nil # thereafter
455
646
  *
456
647
  * This method is called automatically when a new SSLSocket is created.
457
- * Normally you do not need to call this method (unless you are writing an extension in C).
648
+ * Normally you do not need to call this method (unless you are writing an
649
+ * extension in C).
458
650
  */
459
651
  static VALUE
460
652
  ossl_sslctx_setup(VALUE self)
@@ -506,14 +698,14 @@ ossl_sslctx_setup(VALUE self)
506
698
  if (cert && key) {
507
699
  if (!SSL_CTX_use_certificate(ctx, cert)) {
508
700
  /* Adds a ref => Safe to FREE */
509
- ossl_raise(eSSLError, "SSL_CTX_use_certificate:");
701
+ ossl_raise(eSSLError, "SSL_CTX_use_certificate");
510
702
  }
511
703
  if (!SSL_CTX_use_PrivateKey(ctx, key)) {
512
704
  /* Adds a ref => Safe to FREE */
513
- ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey:");
705
+ ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
514
706
  }
515
707
  if (!SSL_CTX_check_private_key(ctx)) {
516
- ossl_raise(eSSLError, "SSL_CTX_check_private_key:");
708
+ ossl_raise(eSSLError, "SSL_CTX_check_private_key");
517
709
  }
518
710
  }
519
711
 
@@ -556,22 +748,36 @@ ossl_sslctx_setup(VALUE self)
556
748
  if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));
557
749
 
558
750
  val = ossl_sslctx_get_verify_dep(self);
559
- if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2LONG(val));
751
+ if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
560
752
 
561
753
  val = ossl_sslctx_get_options(self);
562
754
  if(!NIL_P(val)) {
563
- SSL_CTX_set_options(ctx, NUM2LONG(val));
755
+ SSL_CTX_set_options(ctx, NUM2LONG(val));
564
756
  } else {
565
- SSL_CTX_set_options(ctx, SSL_OP_ALL);
757
+ SSL_CTX_set_options(ctx, SSL_OP_ALL);
566
758
  }
759
+
760
+ #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
761
+ val = rb_iv_get(self, "@npn_protocols");
762
+ if (!NIL_P(val)) {
763
+ ssl_npn_encode_protocols(self, val);
764
+ SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *) self);
765
+ OSSL_Debug("SSL NPN advertise callback added");
766
+ }
767
+ if (RTEST(rb_iv_get(self, "@npn_select_cb"))) {
768
+ SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
769
+ OSSL_Debug("SSL NPN select callback added");
770
+ }
771
+ #endif
772
+
567
773
  rb_obj_freeze(self);
568
774
 
569
775
  val = ossl_sslctx_get_sess_id_ctx(self);
570
776
  if (!NIL_P(val)){
571
777
  StringValue(val);
572
- if (!SSL_CTX_set_session_id_context(ctx, RSTRING_PTR(val),
573
- RSTRING_LEN(val))){
574
- ossl_raise(eSSLError, "SSL_CTX_set_session_id_context:");
778
+ if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
779
+ RSTRING_LENINT(val))){
780
+ ossl_raise(eSSLError, "SSL_CTX_set_session_id_context");
575
781
  }
576
782
  }
577
783
 
@@ -587,6 +793,15 @@ ossl_sslctx_setup(VALUE self)
587
793
  SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
588
794
  OSSL_Debug("SSL SESSION remove callback added");
589
795
  }
796
+
797
+ #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
798
+ val = rb_iv_get(self, "@servername_cb");
799
+ if (!NIL_P(val)) {
800
+ SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
801
+ OSSL_Debug("SSL TLSEXT servername callback added");
802
+ }
803
+ #endif
804
+
590
805
  return Qtrue;
591
806
  }
592
807
 
@@ -609,6 +824,8 @@ ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher)
609
824
  /*
610
825
  * call-seq:
611
826
  * ctx.ciphers => [[name, version, bits, alg_bits], ...]
827
+ *
828
+ * The list of ciphers configured for this context.
612
829
  */
613
830
  static VALUE
614
831
  ossl_sslctx_get_ciphers(VALUE self)
@@ -629,10 +846,10 @@ ossl_sslctx_get_ciphers(VALUE self)
629
846
  if (!ciphers)
630
847
  return rb_ary_new();
631
848
 
632
- num = sk_num((STACK*)ciphers);
849
+ num = sk_SSL_CIPHER_num(ciphers);
633
850
  ary = rb_ary_new2(num);
634
851
  for(i = 0; i < num; i++){
635
- cipher = (SSL_CIPHER*)sk_value((STACK*)ciphers, i);
852
+ cipher = sk_SSL_CIPHER_value(ciphers, i);
636
853
  rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher));
637
854
  }
638
855
  return ary;
@@ -643,6 +860,12 @@ ossl_sslctx_get_ciphers(VALUE self)
643
860
  * ctx.ciphers = "cipher1:cipher2:..."
644
861
  * ctx.ciphers = [name, ...]
645
862
  * ctx.ciphers = [[name, version, bits, alg_bits], ...]
863
+ *
864
+ * Sets the list of available ciphers for this context. Note in a server
865
+ * context some ciphers require the appropriate certificates. For example, an
866
+ * RSA cipher can only be chosen when an RSA certificate is available.
867
+ *
868
+ * See also OpenSSL::Cipher and OpenSSL::Cipher::ciphers
646
869
  */
647
870
  static VALUE
648
871
  ossl_sslctx_set_ciphers(VALUE self, VALUE v)
@@ -674,17 +897,17 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
674
897
  return Qnil;
675
898
  }
676
899
  if (!SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(str))) {
677
- ossl_raise(eSSLError, "SSL_CTX_set_cipher_list:");
900
+ ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
678
901
  }
679
902
 
680
903
  return v;
681
904
  }
682
905
 
683
-
684
906
  /*
685
907
  * call-seq:
686
908
  * ctx.session_add(session) -> true | false
687
909
  *
910
+ * Adds +session+ to the session cache
688
911
  */
689
912
  static VALUE
690
913
  ossl_sslctx_session_add(VALUE self, VALUE arg)
@@ -702,6 +925,7 @@ ossl_sslctx_session_add(VALUE self, VALUE arg)
702
925
  * call-seq:
703
926
  * ctx.session_remove(session) -> true | false
704
927
  *
928
+ * Removes +session+ from the session cache
705
929
  */
706
930
  static VALUE
707
931
  ossl_sslctx_session_remove(VALUE self, VALUE arg)
@@ -717,8 +941,9 @@ ossl_sslctx_session_remove(VALUE self, VALUE arg)
717
941
 
718
942
  /*
719
943
  * call-seq:
720
- * ctx.session_cache_mode -> integer
944
+ * ctx.session_cache_mode -> Integer
721
945
  *
946
+ * The current session cache mode.
722
947
  */
723
948
  static VALUE
724
949
  ossl_sslctx_get_session_cache_mode(VALUE self)
@@ -732,8 +957,11 @@ ossl_sslctx_get_session_cache_mode(VALUE self)
732
957
 
733
958
  /*
734
959
  * call-seq:
735
- * ctx.session_cache_mode=(integer) -> integer
960
+ * ctx.session_cache_mode=(integer) -> Integer
736
961
  *
962
+ * Sets the SSL session cache mode. Bitwise-or together the desired
963
+ * SESSION_CACHE_* constants to set. See SSL_CTX_set_session_cache_mode(3) for
964
+ * details.
737
965
  */
738
966
  static VALUE
739
967
  ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg)
@@ -749,8 +977,10 @@ ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg)
749
977
 
750
978
  /*
751
979
  * call-seq:
752
- * ctx.session_cache_size -> integer
980
+ * ctx.session_cache_size -> Integer
753
981
  *
982
+ * Returns the current session cache size. Zero is used to represent an
983
+ * unlimited cache size.
754
984
  */
755
985
  static VALUE
756
986
  ossl_sslctx_get_session_cache_size(VALUE self)
@@ -764,8 +994,10 @@ ossl_sslctx_get_session_cache_size(VALUE self)
764
994
 
765
995
  /*
766
996
  * call-seq:
767
- * ctx.session_cache_size=(integer) -> integer
997
+ * ctx.session_cache_size=(integer) -> Integer
768
998
  *
999
+ * Sets the session cache size. Returns the previously valid session cache
1000
+ * size. Zero is used to represent an unlimited session cache size.
769
1001
  */
770
1002
  static VALUE
771
1003
  ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg)
@@ -783,6 +1015,23 @@ ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg)
783
1015
  * call-seq:
784
1016
  * ctx.session_cache_stats -> Hash
785
1017
  *
1018
+ * Returns a Hash containing the following keys:
1019
+ *
1020
+ * :accept:: Number of started SSL/TLS handshakes in server mode
1021
+ * :accept_good:: Number of established SSL/TLS sessions in server mode
1022
+ * :accept_renegotiate:: Number of start renegotiations in server mode
1023
+ * :cache_full:: Number of sessions that were removed due to cache overflow
1024
+ * :cache_hits:: Number of successfully reused connections
1025
+ * :cache_misses:: Number of sessions proposed by clients that were not found
1026
+ * in the cache
1027
+ * :cache_num:: Number of sessions in the internal session cache
1028
+ * :cb_hits:: Number of sessions retrieved from the external cache in server
1029
+ * mode
1030
+ * :connect:: Number of started SSL/TLS handshakes in client mode
1031
+ * :connect_good:: Number of established SSL/TLS sessions in client mode
1032
+ * :connect_renegotiate:: Number of start renegotiations in client mode
1033
+ * :timeouts:: Number of sessions proposed by clients that were found in the
1034
+ * cache but had expired due to timeouts
786
1035
  */
787
1036
  static VALUE
788
1037
  ossl_sslctx_get_session_cache_stats(VALUE self)
@@ -814,6 +1063,7 @@ ossl_sslctx_get_session_cache_stats(VALUE self)
814
1063
  * call-seq:
815
1064
  * ctx.flush_sessions(time | nil) -> self
816
1065
  *
1066
+ * Removes sessions in the internal cache that have expired at +time+.
817
1067
  */
818
1068
  static VALUE
819
1069
  ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
@@ -821,7 +1071,6 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
821
1071
  VALUE arg1;
822
1072
  SSL_CTX *ctx;
823
1073
  time_t tm = 0;
824
- int cb_state;
825
1074
 
826
1075
  rb_scan_args(argc, argv, "01", &arg1);
827
1076
 
@@ -832,7 +1081,7 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
832
1081
  } else if (rb_obj_is_instance_of(arg1, rb_cTime)) {
833
1082
  tm = NUM2LONG(rb_funcall(arg1, rb_intern("to_i"), 0));
834
1083
  } else {
835
- rb_raise(rb_eArgError, "arg must be Time or nil");
1084
+ ossl_raise(rb_eArgError, "arg must be Time or nil");
836
1085
  }
837
1086
 
838
1087
  SSL_CTX_flush_sessions(ctx, (long)tm);
@@ -846,16 +1095,27 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
846
1095
  static void
847
1096
  ossl_ssl_shutdown(SSL *ssl)
848
1097
  {
1098
+ int i, rc;
1099
+
849
1100
  if (ssl) {
850
- SSL_shutdown(ssl);
851
- SSL_clear(ssl);
1101
+ /* 4 is from SSL_smart_shutdown() of mod_ssl.c (v2.2.19) */
1102
+ /* It says max 2x pending + 2x data = 4 */
1103
+ for (i = 0; i < 4; ++i) {
1104
+ /*
1105
+ * Ignore the case SSL_shutdown returns -1. Empty handshake_func
1106
+ * must not happen.
1107
+ */
1108
+ if (rc = SSL_shutdown(ssl))
1109
+ break;
1110
+ }
1111
+ SSL_clear(ssl);
1112
+ ERR_clear_error();
852
1113
  }
853
1114
  }
854
1115
 
855
1116
  static void
856
1117
  ossl_ssl_free(SSL *ssl)
857
1118
  {
858
- ossl_ssl_shutdown(ssl);
859
1119
  SSL_free(ssl);
860
1120
  }
861
1121
 
@@ -870,9 +1130,11 @@ ossl_ssl_s_alloc(VALUE klass)
870
1130
  * SSLSocket.new(io) => aSSLSocket
871
1131
  * SSLSocket.new(io, ctx) => aSSLSocket
872
1132
  *
873
- * === Parameters
874
- * * +io+ is a real ruby IO object. Not an IO like object that responds to read/write.
875
- * * +ctx+ is an OpenSSLSSL::SSLContext.
1133
+ * Creates a new SSL socket from +io+ which must be a real ruby object (not an
1134
+ * IO-like object that responds to read/write.
1135
+ *
1136
+ * If +ctx+ is provided the SSL Sockets initial params will be taken from
1137
+ * the context.
876
1138
  *
877
1139
  * The OpenSSL::Buffering module provides additional IO methods.
878
1140
  *
@@ -893,6 +1155,9 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
893
1155
  ossl_ssl_set_ctx(self, ctx);
894
1156
  ossl_ssl_set_sync_close(self, Qfalse);
895
1157
  ossl_sslctx_setup(ctx);
1158
+
1159
+ rb_iv_set(self, "@hostname", Qnil);
1160
+
896
1161
  rb_call_super(0, 0);
897
1162
 
898
1163
  return self;
@@ -908,15 +1173,25 @@ ossl_ssl_setup(VALUE self)
908
1173
 
909
1174
  Data_Get_Struct(self, SSL, ssl);
910
1175
  if(!ssl){
1176
+ #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
1177
+ VALUE hostname = rb_iv_get(self, "@hostname");
1178
+ #endif
1179
+
911
1180
  v_ctx = ossl_ssl_get_ctx(self);
912
1181
  Data_Get_Struct(v_ctx, SSL_CTX, ctx);
913
1182
 
914
1183
  ssl = SSL_new(ctx);
915
1184
  if (!ssl) {
916
- ossl_raise(eSSLError, "SSL_new:");
1185
+ ossl_raise(eSSLError, "SSL_new");
917
1186
  }
918
1187
  DATA_PTR(self) = ssl;
919
1188
 
1189
+ #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
1190
+ if (!NIL_P(hostname)) {
1191
+ if (SSL_set_tlsext_host_name(ssl, StringValuePtr(hostname)) != 1)
1192
+ ossl_raise(eSSLError, "SSL_set_tlsext_host_name");
1193
+ }
1194
+ #endif
920
1195
  io = ossl_ssl_get_io(self);
921
1196
  GetOpenFile(io, fptr);
922
1197
  rb_io_check_readable(fptr);
@@ -929,19 +1204,49 @@ ossl_ssl_setup(VALUE self)
929
1204
  SSL_set_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx, (void*)cb);
930
1205
  cb = ossl_sslctx_get_tmp_dh_cb(v_ctx);
931
1206
  SSL_set_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx, (void*)cb);
1207
+ SSL_set_info_callback(ssl, ssl_info_cb);
932
1208
  }
933
1209
 
934
1210
  return Qtrue;
935
1211
  }
936
1212
 
937
1213
  #ifdef _WIN32
938
- #define ssl_get_error(ssl, ret) (errno = WSAGetLastError(), SSL_get_error(ssl, ret))
1214
+ #define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
939
1215
  #else
940
- #define ssl_get_error(ssl, ret) SSL_get_error(ssl, ret)
1216
+ #define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret))
941
1217
  #endif
942
1218
 
1219
+ #define ossl_ssl_data_get_struct(v, ssl) \
1220
+ do { \
1221
+ Data_Get_Struct((v), SSL, (ssl)); \
1222
+ if (!(ssl)) { \
1223
+ rb_warning("SSL session is not started yet."); \
1224
+ return Qnil; \
1225
+ } \
1226
+ } while (0)
1227
+
1228
+ static void
1229
+ write_would_block(int nonblock)
1230
+ {
1231
+ if (nonblock) {
1232
+ VALUE exc = ossl_exc_new(eSSLError, "write would block");
1233
+ rb_extend_object(exc, rb_mWaitWritable);
1234
+ rb_exc_raise(exc);
1235
+ }
1236
+ }
1237
+
1238
+ static void
1239
+ read_would_block(int nonblock)
1240
+ {
1241
+ if (nonblock) {
1242
+ VALUE exc = ossl_exc_new(eSSLError, "read would block");
1243
+ rb_extend_object(exc, rb_mWaitReadable);
1244
+ rb_exc_raise(exc);
1245
+ }
1246
+ }
1247
+
943
1248
  static VALUE
944
- ossl_start_ssl(VALUE self, int (*func)(), const char *funcname)
1249
+ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, int nonblock)
945
1250
  {
946
1251
  SSL *ssl;
947
1252
  rb_io_t *fptr;
@@ -950,15 +1255,26 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname)
950
1255
 
951
1256
  rb_ivar_set(self, ID_callback_state, Qnil);
952
1257
 
953
- Data_Get_Struct(self, SSL, ssl);
1258
+ ossl_ssl_data_get_struct(self, ssl);
1259
+
954
1260
  GetOpenFile(ossl_ssl_get_io(self), fptr);
955
1261
  for(;;){
956
- if((ret = func(ssl)) > 0) break;
1262
+ ret = func(ssl);
1263
+
1264
+ cb_state = rb_ivar_get(self, ID_callback_state);
1265
+ if (!NIL_P(cb_state))
1266
+ rb_jump_tag(NUM2INT(cb_state));
1267
+
1268
+ if (ret > 0)
1269
+ break;
1270
+
957
1271
  switch((ret2 = ssl_get_error(ssl, ret))){
958
1272
  case SSL_ERROR_WANT_WRITE:
1273
+ write_would_block(nonblock);
959
1274
  rb_io_wait_writable(FPTR_TO_FD(fptr));
960
1275
  continue;
961
1276
  case SSL_ERROR_WANT_READ:
1277
+ read_would_block(nonblock);
962
1278
  rb_io_wait_readable(FPTR_TO_FD(fptr));
963
1279
  continue;
964
1280
  case SSL_ERROR_SYSCALL:
@@ -969,46 +1285,89 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname)
969
1285
  }
970
1286
  }
971
1287
 
972
- cb_state = rb_ivar_get(self, ID_callback_state);
973
- if (!NIL_P(cb_state))
974
- rb_jump_tag(NUM2INT(cb_state));
975
-
976
1288
  return self;
977
1289
  }
978
1290
 
979
1291
  /*
980
1292
  * call-seq:
981
1293
  * ssl.connect => self
1294
+ *
1295
+ * Initiates an SSL/TLS handshake with a server. The handshake may be started
1296
+ * after unencrypted data has been sent over the socket.
982
1297
  */
983
1298
  static VALUE
984
1299
  ossl_ssl_connect(VALUE self)
985
1300
  {
986
1301
  ossl_ssl_setup(self);
987
- return ossl_start_ssl(self, SSL_connect, "SSL_connect");
1302
+ return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0);
1303
+ }
1304
+
1305
+ /*
1306
+ * call-seq:
1307
+ * ssl.connect_nonblock => self
1308
+ *
1309
+ * Initiates the SSL/TLS handshake as a client in non-blocking manner.
1310
+ *
1311
+ * # emulates blocking connect
1312
+ * begin
1313
+ * ssl.connect_nonblock
1314
+ * rescue IO::WaitReadable
1315
+ * IO.select([s2])
1316
+ * retry
1317
+ * rescue IO::WaitWritable
1318
+ * IO.select(nil, [s2])
1319
+ * retry
1320
+ * end
1321
+ *
1322
+ */
1323
+ static VALUE
1324
+ ossl_ssl_connect_nonblock(VALUE self)
1325
+ {
1326
+ ossl_ssl_setup(self);
1327
+ return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1);
988
1328
  }
989
1329
 
990
1330
  /*
991
1331
  * call-seq:
992
1332
  * ssl.accept => self
1333
+ *
1334
+ * Waits for a SSL/TLS client to initiate a handshake. The handshake may be
1335
+ * started after unencrypted data has been sent over the socket.
993
1336
  */
994
1337
  static VALUE
995
1338
  ossl_ssl_accept(VALUE self)
996
1339
  {
997
1340
  ossl_ssl_setup(self);
998
- return ossl_start_ssl(self, SSL_accept, "SSL_accept");
1341
+ return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0);
999
1342
  }
1000
1343
 
1001
1344
  /*
1002
1345
  * call-seq:
1003
- * ssl.sysread(length) => string
1004
- * ssl.sysread(length, buffer) => buffer
1346
+ * ssl.accept_nonblock => self
1347
+ *
1348
+ * Initiates the SSL/TLS handshake as a server in non-blocking manner.
1349
+ *
1350
+ * # emulates blocking accept
1351
+ * begin
1352
+ * ssl.accept_nonblock
1353
+ * rescue IO::WaitReadable
1354
+ * IO.select([s2])
1355
+ * retry
1356
+ * rescue IO::WaitWritable
1357
+ * IO.select(nil, [s2])
1358
+ * retry
1359
+ * end
1005
1360
  *
1006
- * === Parameters
1007
- * * +length+ is a positive integer.
1008
- * * +buffer+ is a string used to store the result.
1009
1361
  */
1010
1362
  static VALUE
1011
- ossl_ssl_read(int argc, VALUE *argv, VALUE self)
1363
+ ossl_ssl_accept_nonblock(VALUE self)
1364
+ {
1365
+ ossl_ssl_setup(self);
1366
+ return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1);
1367
+ }
1368
+
1369
+ static VALUE
1370
+ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1012
1371
  {
1013
1372
  SSL *ssl;
1014
1373
  int ilen, nread = 0;
@@ -1028,33 +1387,35 @@ ossl_ssl_read(int argc, VALUE *argv, VALUE self)
1028
1387
  Data_Get_Struct(self, SSL, ssl);
1029
1388
  GetOpenFile(ossl_ssl_get_io(self), fptr);
1030
1389
  if (ssl) {
1031
- if(SSL_pending(ssl) <= 0)
1390
+ if(!nonblock && SSL_pending(ssl) <= 0)
1032
1391
  rb_thread_wait_fd(FPTR_TO_FD(fptr));
1033
1392
  for (;;){
1034
- nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LEN(str));
1393
+ nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
1035
1394
  switch(ssl_get_error(ssl, nread)){
1036
1395
  case SSL_ERROR_NONE:
1037
1396
  goto end;
1038
1397
  case SSL_ERROR_ZERO_RETURN:
1039
1398
  rb_eof_error();
1040
1399
  case SSL_ERROR_WANT_WRITE:
1400
+ write_would_block(nonblock);
1041
1401
  rb_io_wait_writable(FPTR_TO_FD(fptr));
1042
1402
  continue;
1043
1403
  case SSL_ERROR_WANT_READ:
1404
+ read_would_block(nonblock);
1044
1405
  rb_io_wait_readable(FPTR_TO_FD(fptr));
1045
1406
  continue;
1046
1407
  case SSL_ERROR_SYSCALL:
1047
1408
  if(ERR_peek_error() == 0 && nread == 0) rb_eof_error();
1048
1409
  rb_sys_fail(0);
1049
1410
  default:
1050
- ossl_raise(eSSLError, "SSL_read:");
1411
+ ossl_raise(eSSLError, "SSL_read");
1051
1412
  }
1052
1413
  }
1053
1414
  }
1054
1415
  else {
1055
- ID id_sysread = rb_intern("sysread");
1416
+ ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
1056
1417
  rb_warning("SSL session is not started yet.");
1057
- return rb_funcall(ossl_ssl_get_io(self), id_sysread, 2, len, str);
1418
+ return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str);
1058
1419
  }
1059
1420
 
1060
1421
  end:
@@ -1066,10 +1427,37 @@ ossl_ssl_read(int argc, VALUE *argv, VALUE self)
1066
1427
 
1067
1428
  /*
1068
1429
  * call-seq:
1069
- * ssl.syswrite(string) => integer
1430
+ * ssl.sysread(length) => string
1431
+ * ssl.sysread(length, buffer) => buffer
1432
+ *
1433
+ * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+
1434
+ * is provided the data will be written into it.
1070
1435
  */
1071
1436
  static VALUE
1072
- ossl_ssl_write(VALUE self, VALUE str)
1437
+ ossl_ssl_read(int argc, VALUE *argv, VALUE self)
1438
+ {
1439
+ return ossl_ssl_read_internal(argc, argv, self, 0);
1440
+ }
1441
+
1442
+ /*
1443
+ * call-seq:
1444
+ * ssl.sysread_nonblock(length) => string
1445
+ * ssl.sysread_nonblock(length, buffer) => buffer
1446
+ *
1447
+ * A non-blocking version of #sysread. Raises an SSLError if reading would
1448
+ * block.
1449
+ *
1450
+ * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+
1451
+ * is provided the data will be written into it.
1452
+ */
1453
+ static VALUE
1454
+ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
1455
+ {
1456
+ return ossl_ssl_read_internal(argc, argv, self, 1);
1457
+ }
1458
+
1459
+ static VALUE
1460
+ ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock)
1073
1461
  {
1074
1462
  SSL *ssl;
1075
1463
  int nwrite = 0;
@@ -1081,20 +1469,22 @@ ossl_ssl_write(VALUE self, VALUE str)
1081
1469
 
1082
1470
  if (ssl) {
1083
1471
  for (;;){
1084
- nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LEN(str));
1472
+ nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
1085
1473
  switch(ssl_get_error(ssl, nwrite)){
1086
1474
  case SSL_ERROR_NONE:
1087
1475
  goto end;
1088
1476
  case SSL_ERROR_WANT_WRITE:
1477
+ write_would_block(nonblock);
1089
1478
  rb_io_wait_writable(FPTR_TO_FD(fptr));
1090
1479
  continue;
1091
1480
  case SSL_ERROR_WANT_READ:
1481
+ read_would_block(nonblock);
1092
1482
  rb_io_wait_readable(FPTR_TO_FD(fptr));
1093
1483
  continue;
1094
1484
  case SSL_ERROR_SYSCALL:
1095
1485
  if (errno) rb_sys_fail(0);
1096
1486
  default:
1097
- ossl_raise(eSSLError, "SSL_write:");
1487
+ ossl_raise(eSSLError, "SSL_write");
1098
1488
  }
1099
1489
  }
1100
1490
  }
@@ -1108,19 +1498,54 @@ ossl_ssl_write(VALUE self, VALUE str)
1108
1498
  return INT2NUM(nwrite);
1109
1499
  }
1110
1500
 
1501
+ /*
1502
+ * call-seq:
1503
+ * ssl.syswrite(string) => Integer
1504
+ *
1505
+ * Writes +string+ to the SSL connection.
1506
+ */
1507
+ static VALUE
1508
+ ossl_ssl_write(VALUE self, VALUE str)
1509
+ {
1510
+ return ossl_ssl_write_internal(self, str, 0);
1511
+ }
1512
+
1513
+ /*
1514
+ * call-seq:
1515
+ * ssl.syswrite_nonblock(string) => Integer
1516
+ *
1517
+ * Writes +string+ to the SSL connection in a non-blocking manner. Raises an
1518
+ * SSLError if writing would block.
1519
+ */
1520
+ static VALUE
1521
+ ossl_ssl_write_nonblock(VALUE self, VALUE str)
1522
+ {
1523
+ return ossl_ssl_write_internal(self, str, 1);
1524
+ }
1525
+
1111
1526
  /*
1112
1527
  * call-seq:
1113
1528
  * ssl.sysclose => nil
1529
+ *
1530
+ * Shuts down the SSL connection and prepares it for another connection.
1114
1531
  */
1115
1532
  static VALUE
1116
1533
  ossl_ssl_close(VALUE self)
1117
1534
  {
1118
1535
  SSL *ssl;
1119
1536
 
1120
- Data_Get_Struct(self, SSL, ssl);
1121
- ossl_ssl_shutdown(ssl);
1122
- if (RTEST(ossl_ssl_get_sync_close(self)))
1123
- rb_funcall(ossl_ssl_get_io(self), rb_intern("close"), 0);
1537
+ ossl_ssl_data_get_struct(self, ssl);
1538
+
1539
+ if (ssl) {
1540
+ VALUE io = ossl_ssl_get_io(self);
1541
+ if (!RTEST(rb_funcall(io, rb_intern("closed?"), 0))) {
1542
+ ossl_ssl_shutdown(ssl);
1543
+ SSL_free(ssl);
1544
+ DATA_PTR(self) = NULL;
1545
+ if (RTEST(ossl_ssl_get_sync_close(self)))
1546
+ rb_funcall(io, rb_intern("close"), 0);
1547
+ }
1548
+ }
1124
1549
 
1125
1550
  return Qnil;
1126
1551
  }
@@ -1128,6 +1553,8 @@ ossl_ssl_close(VALUE self)
1128
1553
  /*
1129
1554
  * call-seq:
1130
1555
  * ssl.cert => cert or nil
1556
+ *
1557
+ * The X509 certificate for this socket endpoint.
1131
1558
  */
1132
1559
  static VALUE
1133
1560
  ossl_ssl_get_cert(VALUE self)
@@ -1135,11 +1562,7 @@ ossl_ssl_get_cert(VALUE self)
1135
1562
  SSL *ssl;
1136
1563
  X509 *cert = NULL;
1137
1564
 
1138
- Data_Get_Struct(self, SSL, ssl);
1139
- if (ssl) {
1140
- rb_warning("SSL session is not started yet.");
1141
- return Qnil;
1142
- }
1565
+ ossl_ssl_data_get_struct(self, ssl);
1143
1566
 
1144
1567
  /*
1145
1568
  * Is this OpenSSL bug? Should add a ref?
@@ -1156,6 +1579,8 @@ ossl_ssl_get_cert(VALUE self)
1156
1579
  /*
1157
1580
  * call-seq:
1158
1581
  * ssl.peer_cert => cert or nil
1582
+ *
1583
+ * The X509 certificate for this socket's peer.
1159
1584
  */
1160
1585
  static VALUE
1161
1586
  ossl_ssl_get_peer_cert(VALUE self)
@@ -1164,12 +1589,7 @@ ossl_ssl_get_peer_cert(VALUE self)
1164
1589
  X509 *cert = NULL;
1165
1590
  VALUE obj;
1166
1591
 
1167
- Data_Get_Struct(self, SSL, ssl);
1168
-
1169
- if (!ssl){
1170
- rb_warning("SSL session is not started yet.");
1171
- return Qnil;
1172
- }
1592
+ ossl_ssl_data_get_struct(self, ssl);
1173
1593
 
1174
1594
  cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */
1175
1595
 
@@ -1185,6 +1605,8 @@ ossl_ssl_get_peer_cert(VALUE self)
1185
1605
  /*
1186
1606
  * call-seq:
1187
1607
  * ssl.peer_cert_chain => [cert, ...] or nil
1608
+ *
1609
+ * The X509 certificate chain for this socket's peer.
1188
1610
  */
1189
1611
  static VALUE
1190
1612
  ossl_ssl_get_peer_cert_chain(VALUE self)
@@ -1195,11 +1617,8 @@ ossl_ssl_get_peer_cert_chain(VALUE self)
1195
1617
  VALUE ary;
1196
1618
  int i, num;
1197
1619
 
1198
- Data_Get_Struct(self, SSL, ssl);
1199
- if(!ssl){
1200
- rb_warning("SSL session is not started yet.");
1201
- return Qnil;
1202
- }
1620
+ ossl_ssl_data_get_struct(self, ssl);
1621
+
1203
1622
  chain = SSL_get_peer_cert_chain(ssl);
1204
1623
  if(!chain) return Qnil;
1205
1624
  num = sk_X509_num(chain);
@@ -1213,21 +1632,37 @@ ossl_ssl_get_peer_cert_chain(VALUE self)
1213
1632
  }
1214
1633
 
1215
1634
  /*
1216
- * call-seq:
1217
- * ssl.cipher => [name, version, bits, alg_bits]
1218
- */
1635
+ * call-seq:
1636
+ * ssl.version => String
1637
+ *
1638
+ * Returns a String representing the SSL/TLS version that was negotiated
1639
+ * for the connection, for example "TLSv1.2".
1640
+ */
1641
+ static VALUE
1642
+ ossl_ssl_get_version(VALUE self)
1643
+ {
1644
+ SSL *ssl;
1645
+
1646
+ ossl_ssl_data_get_struct(self, ssl);
1647
+
1648
+ return rb_str_new2(SSL_get_version(ssl));
1649
+ }
1650
+
1651
+ /*
1652
+ * call-seq:
1653
+ * ssl.cipher => [name, version, bits, alg_bits]
1654
+ *
1655
+ * The cipher being used for the current connection
1656
+ */
1219
1657
  static VALUE
1220
1658
  ossl_ssl_get_cipher(VALUE self)
1221
1659
  {
1222
1660
  SSL *ssl;
1223
1661
  SSL_CIPHER *cipher;
1224
1662
 
1225
- Data_Get_Struct(self, SSL, ssl);
1226
- if (!ssl) {
1227
- rb_warning("SSL session is not started yet.");
1228
- return Qnil;
1229
- }
1230
- cipher = SSL_get_current_cipher(ssl);
1663
+ ossl_ssl_data_get_struct(self, ssl);
1664
+
1665
+ cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl);
1231
1666
 
1232
1667
  return ossl_ssl_cipher_to_ary(cipher);
1233
1668
  }
@@ -1235,6 +1670,8 @@ ossl_ssl_get_cipher(VALUE self)
1235
1670
  /*
1236
1671
  * call-seq:
1237
1672
  * ssl.state => string
1673
+ *
1674
+ * A description of the current connection state.
1238
1675
  */
1239
1676
  static VALUE
1240
1677
  ossl_ssl_get_state(VALUE self)
@@ -1242,11 +1679,8 @@ ossl_ssl_get_state(VALUE self)
1242
1679
  SSL *ssl;
1243
1680
  VALUE ret;
1244
1681
 
1245
- Data_Get_Struct(self, SSL, ssl);
1246
- if (!ssl) {
1247
- rb_warning("SSL session is not started yet.");
1248
- return Qnil;
1249
- }
1682
+ ossl_ssl_data_get_struct(self, ssl);
1683
+
1250
1684
  ret = rb_str_new2(SSL_state_string(ssl));
1251
1685
  if (ruby_verbose) {
1252
1686
  rb_str_cat2(ret, ": ");
@@ -1257,49 +1691,47 @@ ossl_ssl_get_state(VALUE self)
1257
1691
 
1258
1692
  /*
1259
1693
  * call-seq:
1260
- * ssl.pending => integer
1694
+ * ssl.pending => Integer
1695
+ *
1696
+ * The number of bytes that are immediately available for reading
1261
1697
  */
1262
1698
  static VALUE
1263
1699
  ossl_ssl_pending(VALUE self)
1264
1700
  {
1265
1701
  SSL *ssl;
1266
1702
 
1267
- Data_Get_Struct(self, SSL, ssl);
1268
- if (!ssl) {
1269
- rb_warning("SSL session is not started yet.");
1270
- return Qnil;
1271
- }
1703
+ ossl_ssl_data_get_struct(self, ssl);
1272
1704
 
1273
1705
  return INT2NUM(SSL_pending(ssl));
1274
1706
  }
1275
1707
 
1276
1708
  /*
1277
- * call-seq:
1278
- * ssl.session_reused? -> true | false
1709
+ * call-seq:
1710
+ * ssl.session_reused? -> true | false
1279
1711
  *
1712
+ * Returns true if a reused session was negotiated during the handshake.
1280
1713
  */
1281
1714
  static VALUE
1282
1715
  ossl_ssl_session_reused(VALUE self)
1283
1716
  {
1284
1717
  SSL *ssl;
1285
1718
 
1286
- Data_Get_Struct(self, SSL, ssl);
1287
- if (!ssl) {
1288
- rb_warning("SSL session is not started yet.");
1289
- return Qnil;
1290
- }
1719
+ ossl_ssl_data_get_struct(self, ssl);
1291
1720
 
1292
1721
  switch(SSL_session_reused(ssl)) {
1293
1722
  case 1: return Qtrue;
1294
1723
  case 0: return Qfalse;
1295
1724
  default: ossl_raise(eSSLError, "SSL_session_reused");
1296
1725
  }
1726
+
1727
+ UNREACHABLE;
1297
1728
  }
1298
1729
 
1299
1730
  /*
1300
- * call-seq:
1301
- * ssl.session = session -> session
1731
+ * call-seq:
1732
+ * ssl.session = session -> session
1302
1733
  *
1734
+ * Sets the Session to be used when the connection is established.
1303
1735
  */
1304
1736
  static VALUE
1305
1737
  ossl_ssl_set_session(VALUE self, VALUE arg1)
@@ -1310,11 +1742,7 @@ ossl_ssl_set_session(VALUE self, VALUE arg1)
1310
1742
  /* why is ossl_ssl_setup delayed? */
1311
1743
  ossl_ssl_setup(self);
1312
1744
 
1313
- Data_Get_Struct(self, SSL, ssl);
1314
- if (!ssl) {
1315
- rb_warning("SSL session is not started yet.");
1316
- return Qnil;
1317
- }
1745
+ ossl_ssl_data_get_struct(self, ssl);
1318
1746
 
1319
1747
  SafeGetSSLSession(arg1, sess);
1320
1748
 
@@ -1324,58 +1752,319 @@ ossl_ssl_set_session(VALUE self, VALUE arg1)
1324
1752
  return arg1;
1325
1753
  }
1326
1754
 
1755
+ /*
1756
+ * call-seq:
1757
+ * ssl.verify_result => Integer
1758
+ *
1759
+ * Returns the result of the peer certificates verification. See verify(1)
1760
+ * for error values and descriptions.
1761
+ *
1762
+ * If no peer certificate was presented X509_V_OK is returned.
1763
+ */
1327
1764
  static VALUE
1328
1765
  ossl_ssl_get_verify_result(VALUE self)
1329
1766
  {
1330
1767
  SSL *ssl;
1331
1768
 
1332
- Data_Get_Struct(self, SSL, ssl);
1333
- if (!ssl) {
1334
- rb_warning("SSL session is not started yet.");
1335
- return Qnil;
1336
- }
1769
+ ossl_ssl_data_get_struct(self, ssl);
1337
1770
 
1338
1771
  return INT2FIX(SSL_get_verify_result(ssl));
1339
1772
  }
1340
1773
 
1774
+ /*
1775
+ * call-seq:
1776
+ * ssl.client_ca => [x509name, ...]
1777
+ *
1778
+ * Returns the list of client CAs. Please note that in contrast to
1779
+ * SSLContext#client_ca= no array of X509::Certificate is returned but
1780
+ * X509::Name instances of the CA's subject distinguished name.
1781
+ *
1782
+ * In server mode, returns the list set by SSLContext#client_ca=.
1783
+ * In client mode, returns the list of client CAs sent from the server.
1784
+ */
1785
+ static VALUE
1786
+ ossl_ssl_get_client_ca_list(VALUE self)
1787
+ {
1788
+ SSL *ssl;
1789
+ STACK_OF(X509_NAME) *ca;
1790
+
1791
+ ossl_ssl_data_get_struct(self, ssl);
1792
+
1793
+ ca = SSL_get_client_CA_list(ssl);
1794
+ return ossl_x509name_sk2ary(ca);
1795
+ }
1796
+
1797
+ #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
1798
+ /*
1799
+ * call-seq:
1800
+ * ssl.npn_protocol => String
1801
+ *
1802
+ * Returns the protocol string that was finally selected by the client
1803
+ * during the handshake.
1804
+ */
1805
+ static VALUE
1806
+ ossl_ssl_npn_protocol(VALUE self)
1807
+ {
1808
+ SSL *ssl;
1809
+ const unsigned char *out;
1810
+ unsigned int outlen;
1811
+
1812
+ ossl_ssl_data_get_struct(self, ssl);
1813
+
1814
+ SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
1815
+ if (!outlen)
1816
+ return Qnil;
1817
+ else
1818
+ return rb_str_new((const char *) out, outlen);
1819
+ }
1820
+ #endif
1821
+
1341
1822
  void
1342
1823
  Init_ossl_ssl()
1343
1824
  {
1344
1825
  int i;
1345
1826
  VALUE ary;
1346
1827
 
1347
- #if 0 /* let rdoc know about mOSSL */
1348
- mOSSL = rb_define_module("OpenSSL");
1828
+ #if 0
1829
+ mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
1349
1830
  #endif
1350
1831
 
1351
1832
  ID_callback_state = rb_intern("@callback_state");
1352
1833
 
1353
- ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,"ossl_ssl_ex_vcb_idx",0,0,0);
1354
- ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,"ossl_ssl_ex_store_p",0,0,0);
1355
- ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,"ossl_ssl_ex_ptr_idx",0,0,0);
1834
+ ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0);
1835
+ ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0);
1836
+ ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_ptr_idx",0,0,0);
1356
1837
  ossl_ssl_ex_client_cert_cb_idx =
1357
- SSL_get_ex_new_index(0,"ossl_ssl_ex_client_cert_cb_idx",0,0,0);
1838
+ SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_client_cert_cb_idx",0,0,0);
1358
1839
  ossl_ssl_ex_tmp_dh_callback_idx =
1359
- SSL_get_ex_new_index(0,"ossl_ssl_ex_tmp_dh_callback_idx",0,0,0);
1840
+ SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_tmp_dh_callback_idx",0,0,0);
1360
1841
 
1842
+ /* Document-module: OpenSSL::SSL
1843
+ *
1844
+ * Use SSLContext to set up the parameters for a TLS (former SSL)
1845
+ * connection. Both client and server TLS connections are supported,
1846
+ * SSLSocket and SSLServer may be used in conjunction with an instance
1847
+ * of SSLContext to set up connections.
1848
+ */
1361
1849
  mSSL = rb_define_module_under(mOSSL, "SSL");
1850
+ /* Document-class: OpenSSL::SSL::SSLError
1851
+ *
1852
+ * Generic error class raised by SSLSocket and SSLContext.
1853
+ */
1362
1854
  eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError);
1363
1855
 
1364
1856
  Init_ossl_ssl_session();
1365
1857
 
1366
- /* class SSLContext
1858
+ /* Document-class: OpenSSL::SSL::SSLContext
1367
1859
  *
1368
- * The following attributes are available but don't show up in rdoc.
1369
- * All attributes must be set before calling SSLSocket.new(io, ctx).
1860
+ * An SSLContext is used to set various options regarding certificates,
1861
+ * algorithms, verification, session caching, etc. The SSLContext is
1862
+ * used to create an SSLSocket.
1863
+ *
1864
+ * All attributes must be set before creating an SSLSocket as the
1865
+ * SSLContext will be frozen afterward.
1866
+ *
1867
+ * The following attributes are available but don't show up in rdoc:
1370
1868
  * * ssl_version, cert, key, client_ca, ca_file, ca_path, timeout,
1371
1869
  * * verify_mode, verify_depth client_cert_cb, tmp_dh_callback,
1372
1870
  * * session_id_context, session_add_cb, session_new_cb, session_remove_cb
1373
1871
  */
1374
1872
  cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject);
1375
1873
  rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc);
1376
- for(i = 0; i < numberof(ossl_sslctx_attrs); i++)
1377
- rb_attr(cSSLContext, rb_intern(ossl_sslctx_attrs[i]), 1, 1, Qfalse);
1874
+
1875
+ /*
1876
+ * Context certificate
1877
+ */
1878
+ rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse);
1879
+
1880
+ /*
1881
+ * Context private key
1882
+ */
1883
+ rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse);
1884
+
1885
+ /*
1886
+ * A certificate or Array of certificates that will be sent to the client.
1887
+ */
1888
+ rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse);
1889
+
1890
+ /*
1891
+ * The path to a file containing a PEM-format CA certificate
1892
+ */
1893
+ rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse);
1894
+
1895
+ /*
1896
+ * The path to a directory containing CA certificates in PEM format.
1897
+ *
1898
+ * Files are looked up by subject's X509 name's hash value.
1899
+ */
1900
+ rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse);
1901
+
1902
+ /*
1903
+ * Maximum session lifetime.
1904
+ */
1905
+ rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse);
1906
+
1907
+ /*
1908
+ * Session verification mode.
1909
+ *
1910
+ * Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE,
1911
+ * VERIFY_FAIL_IF_NO_PEER_CERT and defined on OpenSSL::SSL
1912
+ */
1913
+ rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse);
1914
+
1915
+ /*
1916
+ * Number of CA certificates to walk when verifying a certificate chain.
1917
+ */
1918
+ rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse);
1919
+
1920
+ /*
1921
+ * A callback for additional certificate verification. The callback is
1922
+ * invoked for each certificate in the chain.
1923
+ *
1924
+ * The callback is invoked with two values. +preverify_ok+ indicates
1925
+ * indicates if the verification was passed (true) or not (false).
1926
+ * +store_context+ is an OpenSSL::X509::StoreContext containing the
1927
+ * context used for certificate verification.
1928
+ *
1929
+ * If the callback returns false verification is stopped.
1930
+ */
1931
+ rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
1932
+
1933
+ /*
1934
+ * Sets various OpenSSL options.
1935
+ */
1936
+ rb_attr(cSSLContext, rb_intern("options"), 1, 1, Qfalse);
1937
+
1938
+ /*
1939
+ * An OpenSSL::X509::Store used for certificate verification
1940
+ */
1941
+ rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse);
1942
+
1943
+ /*
1944
+ * An Array of extra X509 certificates to be added to the certificate
1945
+ * chain.
1946
+ */
1947
+ rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse);
1948
+
1949
+ /*
1950
+ * A callback invoked when a client certificate is requested by a server
1951
+ * and no certificate has been set.
1952
+ *
1953
+ * The callback is invoked with a Session and must return an Array
1954
+ * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any
1955
+ * other value is returned the handshake is suspended.
1956
+ */
1957
+ rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
1958
+
1959
+ /*
1960
+ * A callback invoked when DH parameters are required.
1961
+ *
1962
+ * The callback is invoked with the Session for the key exchange, an
1963
+ * flag indicating the use of an export cipher and the keylength
1964
+ * required.
1965
+ *
1966
+ * The callback must return an OpenSSL::PKey::DH instance of the correct
1967
+ * key length.
1968
+ */
1969
+ rb_attr(cSSLContext, rb_intern("tmp_dh_callback"), 1, 1, Qfalse);
1970
+
1971
+ /*
1972
+ * Sets the context in which a session can be reused. This allows
1973
+ * sessions for multiple applications to be distinguished, for exapmle, by
1974
+ * name.
1975
+ */
1976
+ rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse);
1977
+
1978
+ /*
1979
+ * A callback invoked on a server when a session is proposed by the client
1980
+ * but the session could not be found in the server's internal cache.
1981
+ *
1982
+ * The callback is invoked with the SSLSocket and session id. The
1983
+ * callback may return a Session from an external cache.
1984
+ */
1985
+ rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse);
1986
+
1987
+ /*
1988
+ * A callback invoked when a new session was negotiatied.
1989
+ *
1990
+ * The callback is invoked with an SSLSocket. If false is returned the
1991
+ * session will be removed from the internal cache.
1992
+ */
1993
+ rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse);
1994
+
1995
+ /*
1996
+ * A callback invoked when a session is removed from the internal cache.
1997
+ *
1998
+ * The callback is invoked with an SSLContext and a Session.
1999
+ */
2000
+ rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
2001
+
2002
+ #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
2003
+ /*
2004
+ * A callback invoked at connect time to distinguish between multiple
2005
+ * server names.
2006
+ *
2007
+ * The callback is invoked with an SSLSocket and a server name. The
2008
+ * callback must return an SSLContext for the server name or nil.
2009
+ */
2010
+ rb_attr(cSSLContext, rb_intern("servername_cb"), 1, 1, Qfalse);
2011
+ #endif
2012
+ /*
2013
+ * A callback invoked whenever a new handshake is initiated. May be used
2014
+ * to disable renegotiation entirely.
2015
+ *
2016
+ * The callback is invoked with the active SSLSocket. The callback's
2017
+ * return value is irrelevant, normal return indicates "approval" of the
2018
+ * renegotiation and will continue the process. To forbid renegotiation
2019
+ * and to cancel the process, an Error may be raised within the callback.
2020
+ *
2021
+ * === Disable client renegotiation
2022
+ *
2023
+ * When running a server, it is often desirable to disable client
2024
+ * renegotiation entirely. You may use a callback as follows to implement
2025
+ * this feature:
2026
+ *
2027
+ * num_handshakes = 0
2028
+ * ctx.renegotiation_cb = lambda do |ssl|
2029
+ * num_handshakes += 1
2030
+ * raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
2031
+ * end
2032
+ */
2033
+ rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse);
2034
+ #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
2035
+ /*
2036
+ * An Enumerable of Strings. Each String represents a protocol to be
2037
+ * advertised as the list of supported protocols for Next Protocol
2038
+ * Negotiation. Supported in OpenSSL 1.0.1 and higher. Has no effect
2039
+ * on the client side. If not set explicitly, the NPN extension will
2040
+ * not be sent by the server in the handshake.
2041
+ *
2042
+ * === Example
2043
+ *
2044
+ * ctx.npn_protocols = ["http/1.1", "spdy/2"]
2045
+ */
2046
+ rb_attr(cSSLContext, rb_intern("npn_protocols"), 1, 1, Qfalse);
2047
+ /*
2048
+ * A callback invoked on the client side when the client needs to select
2049
+ * a protocol from the list sent by the server. Supported in OpenSSL 1.0.1
2050
+ * and higher. The client MUST select a protocol of those advertised by
2051
+ * the server. If none is acceptable, raising an error in the callback
2052
+ * will cause the handshake to fail. Not setting this callback explicitly
2053
+ * means not supporting the NPN extension on the client - any protocols
2054
+ * advertised by the server will be ignored.
2055
+ *
2056
+ * === Example
2057
+ *
2058
+ * ctx.npn_select_cb = lambda do |protocols|
2059
+ * #inspect the protocols and select one
2060
+ * protocols.first
2061
+ * end
2062
+ */
2063
+ rb_attr(cSSLContext, rb_intern("npn_select_cb"), 1, 1, Qfalse);
2064
+ #endif
2065
+
1378
2066
  rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2067
+ rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
1379
2068
  rb_define_method(cSSLContext, "initialize", ossl_sslctx_initialize, -1);
1380
2069
  rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1);
1381
2070
  rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
@@ -1383,15 +2072,53 @@ Init_ossl_ssl()
1383
2072
 
1384
2073
  rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
1385
2074
 
1386
-
2075
+ /*
2076
+ * No session caching for client or server
2077
+ */
1387
2078
  rb_define_const(cSSLContext, "SESSION_CACHE_OFF", LONG2FIX(SSL_SESS_CACHE_OFF));
2079
+
2080
+ /*
2081
+ * Client sessions are added to the session cache
2082
+ */
1388
2083
  rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT", LONG2FIX(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */
2084
+
2085
+ /*
2086
+ * Server sessions are added to the session cache
2087
+ */
1389
2088
  rb_define_const(cSSLContext, "SESSION_CACHE_SERVER", LONG2FIX(SSL_SESS_CACHE_SERVER));
2089
+
2090
+ /*
2091
+ * Both client and server sessions are added to the session cache
2092
+ */
1390
2093
  rb_define_const(cSSLContext, "SESSION_CACHE_BOTH", LONG2FIX(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */
2094
+
2095
+ /*
2096
+ * Normally the session cache is checked for expired sessions every 255
2097
+ * connections. Since this may lead to a delay that cannot be controlled,
2098
+ * the automatic flushing may be disabled and #flush_sessions can be
2099
+ * called explicitly.
2100
+ */
1391
2101
  rb_define_const(cSSLContext, "SESSION_CACHE_NO_AUTO_CLEAR", LONG2FIX(SSL_SESS_CACHE_NO_AUTO_CLEAR));
2102
+
2103
+ /*
2104
+ * Always perform external lookups of sessions even if they are in the
2105
+ * internal cache.
2106
+ *
2107
+ * This flag has no effect on clients
2108
+ */
1392
2109
  rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_LOOKUP", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP));
2110
+
2111
+ /*
2112
+ * Never automatically store sessions in the internal store.
2113
+ */
1393
2114
  rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_STORE", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_STORE));
2115
+
2116
+ /*
2117
+ * Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and
2118
+ * SESSION_CACHE_NO_INTERNAL_STORE.
2119
+ */
1394
2120
  rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL));
2121
+
1395
2122
  rb_define_method(cSSLContext, "session_add", ossl_sslctx_session_add, 1);
1396
2123
  rb_define_method(cSSLContext, "session_remove", ossl_sslctx_session_remove, 1);
1397
2124
  rb_define_method(cSSLContext, "session_cache_mode", ossl_sslctx_get_session_cache_mode, 0);
@@ -1406,10 +2133,11 @@ Init_ossl_ssl()
1406
2133
  rb_ary_push(ary, ID2SYM(rb_intern(ossl_ssl_method_tab[i].name)));
1407
2134
  }
1408
2135
  rb_obj_freeze(ary);
1409
- /* holds a list of available SSL/TLS methods */
2136
+ /* The list of available SSL/TLS methods */
1410
2137
  rb_define_const(cSSLContext, "METHODS", ary);
1411
2138
 
1412
- /* class SSLSocket
2139
+ /*
2140
+ * Document-class: OpenSSL::SSL::SSLSocket
1413
2141
  *
1414
2142
  * The following attributes are available but don't show up in rdoc.
1415
2143
  * * io, context, sync_close
@@ -1424,21 +2152,31 @@ Init_ossl_ssl()
1424
2152
  rb_define_alias(cSSLSocket, "to_io", "io");
1425
2153
  rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
1426
2154
  rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0);
2155
+ rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, 0);
1427
2156
  rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0);
2157
+ rb_define_method(cSSLSocket, "accept_nonblock", ossl_ssl_accept_nonblock, 0);
1428
2158
  rb_define_method(cSSLSocket, "sysread", ossl_ssl_read, -1);
2159
+ rb_define_private_method(cSSLSocket, "sysread_nonblock", ossl_ssl_read_nonblock, -1);
1429
2160
  rb_define_method(cSSLSocket, "syswrite", ossl_ssl_write, 1);
2161
+ rb_define_private_method(cSSLSocket, "syswrite_nonblock", ossl_ssl_write_nonblock, 1);
1430
2162
  rb_define_method(cSSLSocket, "sysclose", ossl_ssl_close, 0);
1431
2163
  rb_define_method(cSSLSocket, "cert", ossl_ssl_get_cert, 0);
1432
2164
  rb_define_method(cSSLSocket, "peer_cert", ossl_ssl_get_peer_cert, 0);
1433
2165
  rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0);
2166
+ rb_define_method(cSSLSocket, "ssl_version", ossl_ssl_get_version, 0);
1434
2167
  rb_define_method(cSSLSocket, "cipher", ossl_ssl_get_cipher, 0);
1435
2168
  rb_define_method(cSSLSocket, "state", ossl_ssl_get_state, 0);
1436
2169
  rb_define_method(cSSLSocket, "pending", ossl_ssl_pending, 0);
1437
2170
  rb_define_method(cSSLSocket, "session_reused?", ossl_ssl_session_reused, 0);
2171
+ /* implementation of OpenSSL::SSL::SSLSocket#session is in lib/openssl/ssl.rb */
1438
2172
  rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1);
1439
2173
  rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
2174
+ rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
2175
+ #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
2176
+ rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2177
+ #endif
1440
2178
 
1441
- #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2FIX(SSL_##x))
2179
+ #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2NUM(SSL_##x))
1442
2180
 
1443
2181
  ossl_ssl_def_const(VERIFY_NONE);
1444
2182
  ossl_ssl_def_const(VERIFY_PEER);
@@ -1474,8 +2212,17 @@ Init_ossl_ssl()
1474
2212
  ossl_ssl_def_const(OP_NO_SSLv2);
1475
2213
  ossl_ssl_def_const(OP_NO_SSLv3);
1476
2214
  ossl_ssl_def_const(OP_NO_TLSv1);
2215
+ #if defined(SSL_OP_NO_TLSv1_1)
2216
+ ossl_ssl_def_const(OP_NO_TLSv1_1);
2217
+ #endif
2218
+ #if defined(SSL_OP_NO_TLSv1_2)
2219
+ ossl_ssl_def_const(OP_NO_TLSv1_2);
2220
+ #endif
1477
2221
  #if defined(SSL_OP_NO_TICKET)
1478
2222
  ossl_ssl_def_const(OP_NO_TICKET);
2223
+ #endif
2224
+ #if defined(SSL_OP_NO_COMPRESSION)
2225
+ ossl_ssl_def_const(OP_NO_COMPRESSION);
1479
2226
  #endif
1480
2227
  ossl_ssl_def_const(OP_PKCS1_CHECK_1);
1481
2228
  ossl_ssl_def_const(OP_PKCS1_CHECK_2);