rubysl-openssl 2.4.0 → 2.5.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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rubysl/openssl/deprecation.rb +1 -0
  3. data/ext/rubysl/openssl/extconf.rb +6 -8
  4. data/ext/rubysl/openssl/openssl_missing.c +1 -3
  5. data/ext/rubysl/openssl/openssl_missing.h +1 -3
  6. data/ext/rubysl/openssl/ossl.c +15 -3
  7. data/ext/rubysl/openssl/ossl.h +5 -4
  8. data/ext/rubysl/openssl/ossl_asn1.c +19 -13
  9. data/ext/rubysl/openssl/ossl_asn1.h +1 -2
  10. data/ext/rubysl/openssl/ossl_bio.c +1 -2
  11. data/ext/rubysl/openssl/ossl_bio.h +1 -3
  12. data/ext/rubysl/openssl/ossl_bn.c +227 -90
  13. data/ext/rubysl/openssl/ossl_bn.h +1 -3
  14. data/ext/rubysl/openssl/ossl_cipher.c +5 -11
  15. data/ext/rubysl/openssl/ossl_cipher.h +1 -3
  16. data/ext/rubysl/openssl/ossl_config.c +1 -2
  17. data/ext/rubysl/openssl/ossl_config.h +1 -3
  18. data/ext/rubysl/openssl/ossl_digest.c +6 -7
  19. data/ext/rubysl/openssl/ossl_digest.h +1 -3
  20. data/ext/rubysl/openssl/ossl_engine.c +11 -7
  21. data/ext/rubysl/openssl/ossl_engine.h +1 -2
  22. data/ext/rubysl/openssl/ossl_hmac.c +1 -2
  23. data/ext/rubysl/openssl/ossl_hmac.h +1 -2
  24. data/ext/rubysl/openssl/ossl_ns_spki.c +7 -6
  25. data/ext/rubysl/openssl/ossl_ns_spki.h +1 -3
  26. data/ext/rubysl/openssl/ossl_ocsp.c +39 -25
  27. data/ext/rubysl/openssl/ossl_ocsp.h +1 -2
  28. data/ext/rubysl/openssl/ossl_pkcs12.c +10 -6
  29. data/ext/rubysl/openssl/ossl_pkcs12.h +1 -3
  30. data/ext/rubysl/openssl/ossl_pkcs5.c +0 -1
  31. data/ext/rubysl/openssl/ossl_pkcs7.c +29 -16
  32. data/ext/rubysl/openssl/ossl_pkcs7.h +1 -3
  33. data/ext/rubysl/openssl/ossl_pkey.c +10 -8
  34. data/ext/rubysl/openssl/ossl_pkey.h +5 -6
  35. data/ext/rubysl/openssl/ossl_pkey_dh.c +5 -74
  36. data/ext/rubysl/openssl/ossl_pkey_dsa.c +7 -6
  37. data/ext/rubysl/openssl/ossl_pkey_ec.c +4 -2
  38. data/ext/rubysl/openssl/ossl_pkey_rsa.c +5 -5
  39. data/ext/rubysl/openssl/ossl_rand.c +13 -5
  40. data/ext/rubysl/openssl/ossl_rand.h +1 -3
  41. data/ext/rubysl/openssl/ossl_ssl.c +334 -265
  42. data/ext/rubysl/openssl/ossl_ssl.h +1 -5
  43. data/ext/rubysl/openssl/ossl_ssl_session.c +5 -1
  44. data/ext/rubysl/openssl/ossl_version.h +1 -2
  45. data/ext/rubysl/openssl/ossl_x509.c +1 -3
  46. data/ext/rubysl/openssl/ossl_x509.h +1 -2
  47. data/ext/rubysl/openssl/ossl_x509attr.c +9 -6
  48. data/ext/rubysl/openssl/ossl_x509cert.c +14 -12
  49. data/ext/rubysl/openssl/ossl_x509crl.c +15 -13
  50. data/ext/rubysl/openssl/ossl_x509ext.c +13 -8
  51. data/ext/rubysl/openssl/ossl_x509name.c +9 -6
  52. data/ext/rubysl/openssl/ossl_x509req.c +12 -10
  53. data/ext/rubysl/openssl/ossl_x509revoked.c +12 -10
  54. data/ext/rubysl/openssl/ossl_x509store.c +17 -10
  55. data/ext/rubysl/openssl/ruby_missing.h +1 -2
  56. data/lib/openssl/bn.rb +2 -8
  57. data/lib/openssl/buffering.rb +3 -7
  58. data/lib/openssl/cipher.rb +3 -9
  59. data/lib/openssl/config.rb +2 -1
  60. data/lib/openssl/digest.rb +3 -10
  61. data/lib/openssl/pkey.rb +37 -0
  62. data/lib/openssl/ssl.rb +128 -17
  63. data/lib/openssl/x509.rb +2 -8
  64. data/lib/rubysl/openssl.rb +4 -7
  65. data/lib/rubysl/openssl/version.rb +1 -1
  66. metadata +12 -11
@@ -1,11 +1,10 @@
1
1
  /*
2
- * $Id: ossl_pkey_dsa.c 47744 2014-09-30 05:25:32Z nobu $
3
2
  * 'OpenSSL for Ruby' project
4
3
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
4
  * All rights reserved.
6
5
  */
7
6
  /*
8
- * This program is licenced under the same licence as Ruby.
7
+ * This program is licensed under the same licence as Ruby.
9
8
  * (See the file 'LICENCE'.)
10
9
  */
11
10
  #if !defined(OPENSSL_NO_DSA)
@@ -40,6 +39,7 @@ dsa_instance(VALUE klass, DSA *dsa)
40
39
  if (!dsa) {
41
40
  return Qfalse;
42
41
  }
42
+ obj = NewPKey(klass);
43
43
  if (!(pkey = EVP_PKEY_new())) {
44
44
  return Qfalse;
45
45
  }
@@ -47,7 +47,7 @@ dsa_instance(VALUE klass, DSA *dsa)
47
47
  EVP_PKEY_free(pkey);
48
48
  return Qfalse;
49
49
  }
50
- WrapPKey(klass, obj, pkey);
50
+ SetPKey(obj, pkey);
51
51
 
52
52
  return obj;
53
53
  }
@@ -60,10 +60,11 @@ ossl_dsa_new(EVP_PKEY *pkey)
60
60
  if (!pkey) {
61
61
  obj = dsa_instance(cDSA, DSA_new());
62
62
  } else {
63
+ obj = NewPKey(cDSA);
63
64
  if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DSA) {
64
65
  ossl_raise(rb_eTypeError, "Not a DSA key!");
65
66
  }
66
- WrapPKey(cDSA, obj, pkey);
67
+ SetPKey(obj, pkey);
67
68
  }
68
69
  if (obj == Qfalse) {
69
70
  ossl_raise(eDSAError, NULL);
@@ -109,7 +110,7 @@ dsa_generate(int size)
109
110
  unsigned long h;
110
111
 
111
112
  if (!dsa) return 0;
112
- if (!RAND_bytes(seed, seed_len)) {
113
+ if (RAND_bytes(seed, seed_len) <= 0) {
113
114
  DSA_free(dsa);
114
115
  return 0;
115
116
  }
@@ -143,7 +144,7 @@ dsa_generate(int size)
143
144
  int seed_len = 20, counter;
144
145
  unsigned long h;
145
146
 
146
- if (!RAND_bytes(seed, seed_len)) {
147
+ if (RAND_bytes(seed, seed_len) <= 0) {
147
148
  return 0;
148
149
  }
149
150
  dsa = DSA_generate_parameters(size, seed, seed_len, &counter, &h,
@@ -116,6 +116,7 @@ static VALUE ec_instance(VALUE klass, EC_KEY *ec)
116
116
  if (!ec) {
117
117
  return Qfalse;
118
118
  }
119
+ obj = NewPKey(klass);
119
120
  if (!(pkey = EVP_PKEY_new())) {
120
121
  return Qfalse;
121
122
  }
@@ -123,7 +124,7 @@ static VALUE ec_instance(VALUE klass, EC_KEY *ec)
123
124
  EVP_PKEY_free(pkey);
124
125
  return Qfalse;
125
126
  }
126
- WrapPKey(klass, obj, pkey);
127
+ SetPKey(obj, pkey);
127
128
 
128
129
  return obj;
129
130
  }
@@ -135,10 +136,11 @@ VALUE ossl_ec_new(EVP_PKEY *pkey)
135
136
  if (!pkey) {
136
137
  obj = ec_instance(cEC, EC_KEY_new());
137
138
  } else {
139
+ obj = NewPKey(cEC);
138
140
  if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) {
139
141
  ossl_raise(rb_eTypeError, "Not a EC key!");
140
142
  }
141
- WrapPKey(cEC, obj, pkey);
143
+ SetPKey(obj, pkey);
142
144
  }
143
145
  if (obj == Qfalse) {
144
146
  ossl_raise(eECError, NULL);
@@ -1,11 +1,10 @@
1
1
  /*
2
- * $Id: ossl_pkey_rsa.c 47744 2014-09-30 05:25:32Z nobu $
3
2
  * 'OpenSSL for Ruby' project
4
3
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
4
  * All rights reserved.
6
5
  */
7
6
  /*
8
- * This program is licenced under the same licence as Ruby.
7
+ * This program is licensed under the same licence as Ruby.
9
8
  * (See the file 'LICENCE'.)
10
9
  */
11
10
  #if !defined(OPENSSL_NO_RSA)
@@ -40,6 +39,7 @@ rsa_instance(VALUE klass, RSA *rsa)
40
39
  if (!rsa) {
41
40
  return Qfalse;
42
41
  }
42
+ obj = NewPKey(klass);
43
43
  if (!(pkey = EVP_PKEY_new())) {
44
44
  return Qfalse;
45
45
  }
@@ -47,7 +47,7 @@ rsa_instance(VALUE klass, RSA *rsa)
47
47
  EVP_PKEY_free(pkey);
48
48
  return Qfalse;
49
49
  }
50
- WrapPKey(klass, obj, pkey);
50
+ SetPKey(obj, pkey);
51
51
 
52
52
  return obj;
53
53
  }
@@ -61,10 +61,11 @@ ossl_rsa_new(EVP_PKEY *pkey)
61
61
  obj = rsa_instance(cRSA, RSA_new());
62
62
  }
63
63
  else {
64
+ obj = NewPKey(cRSA);
64
65
  if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
65
66
  ossl_raise(rb_eTypeError, "Not a RSA key!");
66
67
  }
67
- WrapPKey(cRSA, obj, pkey);
68
+ SetPKey(obj, pkey);
68
69
  }
69
70
  if (obj == Qfalse) {
70
71
  ossl_raise(eRSAError, NULL);
@@ -698,4 +699,3 @@ Init_ossl_rsa(void)
698
699
  {
699
700
  }
700
701
  #endif /* NO_RSA */
701
-
@@ -1,11 +1,10 @@
1
1
  /*
2
- * $Id: ossl_rand.c 47782 2014-10-04 00:01:07Z zzak $
3
2
  * 'OpenSSL for Ruby' project
4
3
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
4
  *
6
5
  * All rights reserved.
7
6
  *
8
- * This program is licenced under the same licence as Ruby.
7
+ * This program is licensed under the same licence as Ruby.
9
8
  * (See the file 'LICENCE'.)
10
9
  */
11
10
  #include "ossl.h"
@@ -111,10 +110,16 @@ ossl_rand_bytes(VALUE self, VALUE len)
111
110
  {
112
111
  VALUE str;
113
112
  int n = NUM2INT(len);
113
+ int ret;
114
114
 
115
115
  str = rb_str_new(0, n);
116
- if (!RAND_bytes((unsigned char *)RSTRING_PTR(str), n)) {
117
- ossl_raise(eRandomError, NULL);
116
+ 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);
121
+ } else if (ret == -1) {
122
+ ossl_raise(eRandomError, "RAND_bytes is not supported");
118
123
  }
119
124
 
120
125
  return str;
@@ -148,6 +153,7 @@ ossl_rand_pseudo_bytes(VALUE self, VALUE len)
148
153
  return str;
149
154
  }
150
155
 
156
+ #ifdef HAVE_RAND_EGD
151
157
  /*
152
158
  * call-seq:
153
159
  * egd(filename) -> true
@@ -186,6 +192,7 @@ ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
186
192
  }
187
193
  return Qtrue;
188
194
  }
195
+ #endif /* HAVE_RAND_EGD */
189
196
 
190
197
  /*
191
198
  * call-seq:
@@ -219,8 +226,9 @@ Init_ossl_rand(void)
219
226
  rb_define_module_function(mRandom, "write_random_file", ossl_rand_write_file, 1);
220
227
  rb_define_module_function(mRandom, "random_bytes", ossl_rand_bytes, 1);
221
228
  rb_define_module_function(mRandom, "pseudo_bytes", ossl_rand_pseudo_bytes, 1);
229
+ #ifdef HAVE_RAND_EGD
222
230
  rb_define_module_function(mRandom, "egd", ossl_rand_egd, 1);
223
231
  rb_define_module_function(mRandom, "egd_bytes", ossl_rand_egd_bytes, 2);
232
+ #endif /* HAVE_RAND_EGD */
224
233
  rb_define_module_function(mRandom, "status?", ossl_rand_status, 0);
225
234
  }
226
-
@@ -1,11 +1,10 @@
1
1
  /*
2
- * $Id: ossl_rand.h 25189 2009-10-02 12:04:37Z akr $
3
2
  * 'OpenSSL for Ruby' project
4
3
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
4
  * All rights reserved.
6
5
  */
7
6
  /*
8
- * This program is licenced under the same licence as Ruby.
7
+ * This program is licensed under the same licence as Ruby.
9
8
  * (See the file 'LICENCE'.)
10
9
  */
11
10
  #if !defined(_OSSL_RAND_H_)
@@ -17,4 +16,3 @@ extern VALUE eRandomError;
17
16
  void Init_ossl_rand(void);
18
17
 
19
18
  #endif /* _OSSL_RAND_H_ */
20
-
@@ -1,5 +1,4 @@
1
1
  /*
2
- * $Id: ossl_ssl.c 48801 2014-12-12 21:58:34Z nobu $
3
2
  * 'OpenSSL for Ruby' project
4
3
  * Copyright (C) 2000-2002 GOTOU Yuuzou <gotoyuzo@notwork.org>
5
4
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
@@ -7,7 +6,7 @@
7
6
  * All rights reserved.
8
7
  */
9
8
  /*
10
- * This program is licenced under the same licence as Ruby.
9
+ * This program is licensed under the same licence as Ruby.
11
10
  * (See the file 'LICENCE'.)
12
11
  */
13
12
  #include "ossl.h"
@@ -29,7 +28,8 @@
29
28
  } while (0)
30
29
 
31
30
  VALUE mSSL;
32
- VALUE eSSLError;
31
+ static VALUE mSSLExtConfig;
32
+ static VALUE eSSLError;
33
33
  VALUE cSSLContext;
34
34
  VALUE cSSLSocket;
35
35
 
@@ -45,11 +45,9 @@ static VALUE eSSLErrorWaitWritable;
45
45
  #define ossl_sslctx_set_verify_mode(o,v) rb_iv_set((o),"@verify_mode",(v))
46
46
  #define ossl_sslctx_set_verify_dep(o,v) rb_iv_set((o),"@verify_depth",(v))
47
47
  #define ossl_sslctx_set_verify_cb(o,v) rb_iv_set((o),"@verify_callback",(v))
48
- #define ossl_sslctx_set_options(o,v) rb_iv_set((o),"@options",(v))
49
48
  #define ossl_sslctx_set_cert_store(o,v) rb_iv_set((o),"@cert_store",(v))
50
49
  #define ossl_sslctx_set_extra_cert(o,v) rb_iv_set((o),"@extra_chain_cert",(v))
51
50
  #define ossl_sslctx_set_client_cert_cb(o,v) rb_iv_set((o),"@client_cert_cb",(v))
52
- #define ossl_sslctx_set_tmp_dh_cb(o,v) rb_iv_set((o),"@tmp_dh_callback",(v))
53
51
  #define ossl_sslctx_set_sess_id_ctx(o, v) rb_iv_set((o),"@session_id_context",(v))
54
52
 
55
53
  #define ossl_sslctx_get_cert(o) rb_iv_get((o),"@cert")
@@ -61,53 +59,25 @@ static VALUE eSSLErrorWaitWritable;
61
59
  #define ossl_sslctx_get_verify_mode(o) rb_iv_get((o),"@verify_mode")
62
60
  #define ossl_sslctx_get_verify_dep(o) rb_iv_get((o),"@verify_depth")
63
61
  #define ossl_sslctx_get_verify_cb(o) rb_iv_get((o),"@verify_callback")
64
- #define ossl_sslctx_get_options(o) rb_iv_get((o),"@options")
65
62
  #define ossl_sslctx_get_cert_store(o) rb_iv_get((o),"@cert_store")
66
63
  #define ossl_sslctx_get_extra_cert(o) rb_iv_get((o),"@extra_chain_cert")
67
64
  #define ossl_sslctx_get_client_cert_cb(o) rb_iv_get((o),"@client_cert_cb")
68
- #define ossl_sslctx_get_tmp_dh_cb(o) rb_iv_get((o),"@tmp_dh_callback")
65
+ #define ossl_sslctx_get_tmp_ecdh_cb(o) rb_iv_get((o),"@tmp_ecdh_callback")
69
66
  #define ossl_sslctx_get_sess_id_ctx(o) rb_iv_get((o),"@session_id_context")
70
67
 
71
- static const char *ossl_sslctx_attrs[] = {
72
- "cert", "key", "client_ca", "ca_file", "ca_path",
73
- "timeout", "verify_mode", "verify_depth", "renegotiation_cb",
74
- "verify_callback", "options", "cert_store", "extra_chain_cert",
75
- "client_cert_cb", "tmp_dh_callback", "session_id_context",
76
- "session_get_cb", "session_new_cb", "session_remove_cb",
77
- #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
78
- "servername_cb",
79
- #endif
80
- #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
81
- "npn_protocols",
82
- "npn_select_cb",
83
- #endif
84
- };
85
-
86
68
  #define ossl_ssl_get_io(o) rb_iv_get((o),"@io")
87
69
  #define ossl_ssl_get_ctx(o) rb_iv_get((o),"@context")
88
- #define ossl_ssl_get_sync_close(o) rb_iv_get((o),"@sync_close")
89
70
  #define ossl_ssl_get_x509(o) rb_iv_get((o),"@x509")
90
71
  #define ossl_ssl_get_key(o) rb_iv_get((o),"@key")
91
- #define ossl_ssl_get_tmp_dh(o) rb_iv_get((o),"@tmp_dh")
92
72
 
93
- #define ossl_ssl_set_io(o,v) rb_iv_set((o),"@io",(v))
94
- #define ossl_ssl_set_ctx(o,v) rb_iv_set((o),"@context",(v))
95
- #define ossl_ssl_set_sync_close(o,v) rb_iv_set((o),"@sync_close",(v))
96
73
  #define ossl_ssl_set_x509(o,v) rb_iv_set((o),"@x509",(v))
97
74
  #define ossl_ssl_set_key(o,v) rb_iv_set((o),"@key",(v))
98
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))
99
77
 
100
- static const char *ossl_ssl_attr_readers[] = { "io", "context", };
101
- static const char *ossl_ssl_attrs[] = {
102
- #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
103
- "hostname",
104
- #endif
105
- "sync_close",
106
- };
107
-
108
- ID ID_callback_state;
78
+ static ID ID_callback_state;
109
79
 
110
- static VALUE sym_exception;
80
+ static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
111
81
 
112
82
  /*
113
83
  * SSLContext class
@@ -150,11 +120,9 @@ static const struct {
150
120
  #undef OSSL_SSL_METHOD_ENTRY
151
121
  };
152
122
 
153
- int ossl_ssl_ex_vcb_idx;
154
- int ossl_ssl_ex_store_p;
155
- int ossl_ssl_ex_ptr_idx;
156
- int ossl_ssl_ex_client_cert_cb_idx;
157
- int ossl_ssl_ex_tmp_dh_callback_idx;
123
+ static int ossl_ssl_ex_vcb_idx;
124
+ static int ossl_ssl_ex_store_p;
125
+ static int ossl_ssl_ex_ptr_idx;
158
126
 
159
127
  static void
160
128
  ossl_sslctx_free(void *ptr)
@@ -178,17 +146,22 @@ ossl_sslctx_s_alloc(VALUE klass)
178
146
  {
179
147
  SSL_CTX *ctx;
180
148
  long mode = SSL_MODE_ENABLE_PARTIAL_WRITE;
149
+ VALUE obj;
181
150
 
182
151
  #ifdef SSL_MODE_RELEASE_BUFFERS
183
152
  mode |= SSL_MODE_RELEASE_BUFFERS;
184
153
  #endif
185
154
 
155
+ obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
186
156
  ctx = SSL_CTX_new(SSLv23_method());
187
157
  if (!ctx) {
188
158
  ossl_raise(eSSLError, "SSL_CTX_new");
189
159
  }
190
160
  SSL_CTX_set_mode(ctx, mode);
191
- return TypedData_Wrap_Struct(klass, &ossl_sslctx_type, ctx);
161
+ RTYPEDDATA_DATA(obj) = ctx;
162
+ SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)obj);
163
+
164
+ return obj;
192
165
  }
193
166
 
194
167
  /*
@@ -203,13 +176,13 @@ ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
203
176
  {
204
177
  SSL_METHOD *method = NULL;
205
178
  const char *s;
179
+ VALUE m = ssl_method;
206
180
  int i;
207
181
 
208
182
  SSL_CTX *ctx;
209
183
  if (RB_TYPE_P(ssl_method, T_SYMBOL))
210
- s = rb_id2name(SYM2ID(ssl_method));
211
- else
212
- s = StringValuePtr(ssl_method);
184
+ m = rb_sym2str(ssl_method);
185
+ s = StringValueCStr(m);
213
186
  for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
214
187
  if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) {
215
188
  method = ossl_ssl_method_tab[i].func();
@@ -217,7 +190,7 @@ ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
217
190
  }
218
191
  }
219
192
  if (!method) {
220
- ossl_raise(rb_eArgError, "unknown SSL method `%s'.", s);
193
+ ossl_raise(rb_eArgError, "unknown SSL method `%"PRIsVALUE"'.", m);
221
194
  }
222
195
  GetSSLCTX(self, ctx);
223
196
  if (SSL_CTX_set_ssl_version(ctx, method) != 1) {
@@ -227,41 +200,12 @@ ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
227
200
  return ssl_method;
228
201
  }
229
202
 
230
- /*
231
- * call-seq:
232
- * SSLContext.new => ctx
233
- * SSLContext.new(:TLSv1) => ctx
234
- * SSLContext.new("SSLv23_client") => ctx
235
- *
236
- * You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS
237
- */
238
- static VALUE
239
- ossl_sslctx_initialize(int argc, VALUE *argv, VALUE self)
240
- {
241
- VALUE ssl_method;
242
- int i;
243
-
244
- for(i = 0; i < numberof(ossl_sslctx_attrs); i++){
245
- char buf[32];
246
- snprintf(buf, sizeof(buf), "@%s", ossl_sslctx_attrs[i]);
247
- rb_iv_set(self, buf, Qnil);
248
- }
249
- if (rb_scan_args(argc, argv, "01", &ssl_method) == 0){
250
- return self;
251
- }
252
- ossl_sslctx_set_ssl_version(self, ssl_method);
253
-
254
- return self;
255
- }
256
-
257
203
  static VALUE
258
204
  ossl_call_client_cert_cb(VALUE obj)
259
205
  {
260
206
  VALUE cb, ary, cert, key;
261
- SSL *ssl;
262
207
 
263
- GetSSL(obj, ssl);
264
- cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx);
208
+ cb = rb_funcall(obj, rb_intern("client_cert_cb"), 0);
265
209
  if (NIL_P(cb)) return Qfalse;
266
210
  ary = rb_funcall(cb, rb_intern("call"), 1, obj);
267
211
  Check_Type(ary, T_ARRAY);
@@ -279,8 +223,7 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
279
223
  VALUE obj, success;
280
224
 
281
225
  obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
282
- success = rb_protect((VALUE(*)_((VALUE)))ossl_call_client_cert_cb,
283
- obj, NULL);
226
+ success = rb_protect(ossl_call_client_cert_cb, obj, NULL);
284
227
  if (!RTEST(success)) return 0;
285
228
  *x509 = DupX509CertPtr(ossl_ssl_get_x509(obj));
286
229
  *pkey = DupPKeyPtr(ossl_ssl_get_key(obj));
@@ -290,52 +233,71 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
290
233
 
291
234
  #if !defined(OPENSSL_NO_DH)
292
235
  static VALUE
293
- ossl_call_tmp_dh_callback(VALUE *args)
236
+ ossl_call_tmp_dh_callback(VALUE args)
294
237
  {
295
- SSL *ssl;
296
238
  VALUE cb, dh;
297
239
  EVP_PKEY *pkey;
298
240
 
299
- GetSSL(args[0], ssl);
300
- cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx);
241
+ cb = rb_funcall(rb_ary_entry(args, 0), rb_intern("tmp_dh_callback"), 0);
242
+
301
243
  if (NIL_P(cb)) return Qfalse;
302
- dh = rb_funcall(cb, rb_intern("call"), 3, args[0], args[1], args[2]);
244
+ dh = rb_apply(cb, rb_intern("call"), args);
303
245
  pkey = GetPKeyPtr(dh);
304
246
  if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) return Qfalse;
305
- ossl_ssl_set_tmp_dh(args[0], dh);
306
247
 
307
- return Qtrue;
248
+ return dh;
308
249
  }
309
250
 
310
251
  static DH*
311
252
  ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
312
253
  {
313
- VALUE args[3], success;
254
+ VALUE args, dh, rb_ssl;
255
+
256
+ rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
257
+
258
+ args = rb_ary_new_from_args(3, rb_ssl, INT2FIX(is_export), INT2FIX(keylength));
314
259
 
315
- args[0] = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
316
- args[1] = INT2FIX(is_export);
317
- args[2] = INT2FIX(keylength);
318
- success = rb_protect((VALUE(*)_((VALUE)))ossl_call_tmp_dh_callback,
319
- (VALUE)args, NULL);
320
- if (!RTEST(success)) return NULL;
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);
321
263
 
322
- return GetPKeyPtr(ossl_ssl_get_tmp_dh(args[0]))->pkey.dh;
264
+ return GetPKeyPtr(dh)->pkey.dh;
323
265
  }
266
+ #endif /* OPENSSL_NO_DH */
324
267
 
325
- static DH*
326
- ossl_default_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
268
+ #if !defined(OPENSSL_NO_EC)
269
+ static VALUE
270
+ ossl_call_tmp_ecdh_callback(VALUE args)
327
271
  {
328
- rb_warning("using default DH parameters.");
272
+ VALUE cb, ecdh;
273
+ EVP_PKEY *pkey;
329
274
 
330
- switch(keylength){
331
- case 512:
332
- return OSSL_DEFAULT_DH_512;
333
- case 1024:
334
- return OSSL_DEFAULT_DH_1024;
335
- }
336
- return NULL;
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;
281
+
282
+ return ecdh;
337
283
  }
338
- #endif /* OPENSSL_NO_DH */
284
+
285
+ static EC_KEY*
286
+ ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
287
+ {
288
+ VALUE args, ecdh, rb_ssl;
289
+
290
+ rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
291
+
292
+ args = rb_ary_new_from_args(3, rb_ssl, INT2FIX(is_export), INT2FIX(keylength));
293
+
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);
297
+
298
+ return GetPKeyPtr(ecdh)->pkey.ec;
299
+ }
300
+ #endif
339
301
 
340
302
  static int
341
303
  ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
@@ -352,14 +314,12 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
352
314
  static VALUE
353
315
  ossl_call_session_get_cb(VALUE ary)
354
316
  {
355
- VALUE ssl_obj, sslctx_obj, cb;
317
+ VALUE ssl_obj, cb;
356
318
 
357
319
  Check_Type(ary, T_ARRAY);
358
320
  ssl_obj = rb_ary_entry(ary, 0);
359
321
 
360
- sslctx_obj = rb_iv_get(ssl_obj, "@context");
361
- if (NIL_P(sslctx_obj)) return Qnil;
362
- cb = rb_iv_get(sslctx_obj, "@session_get_cb");
322
+ cb = rb_funcall(ssl_obj, rb_intern("session_get_cb"), 0);
363
323
  if (NIL_P(cb)) return Qnil;
364
324
 
365
325
  return rb_funcall(cb, rb_intern("call"), 1, ary);
@@ -382,7 +342,7 @@ ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
382
342
  rb_ary_push(ary, ssl_obj);
383
343
  rb_ary_push(ary, rb_str_new((const char *)buf, len));
384
344
 
385
- ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_get_cb, ary, &state);
345
+ ret_obj = rb_protect(ossl_call_session_get_cb, ary, &state);
386
346
  if (state) {
387
347
  rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
388
348
  return NULL;
@@ -399,14 +359,12 @@ ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
399
359
  static VALUE
400
360
  ossl_call_session_new_cb(VALUE ary)
401
361
  {
402
- VALUE ssl_obj, sslctx_obj, cb;
362
+ VALUE ssl_obj, cb;
403
363
 
404
364
  Check_Type(ary, T_ARRAY);
405
365
  ssl_obj = rb_ary_entry(ary, 0);
406
366
 
407
- sslctx_obj = rb_iv_get(ssl_obj, "@context");
408
- if (NIL_P(sslctx_obj)) return Qnil;
409
- cb = rb_iv_get(sslctx_obj, "@session_new_cb");
367
+ cb = rb_funcall(ssl_obj, rb_intern("session_new_cb"), 0);
410
368
  if (NIL_P(cb)) return Qnil;
411
369
 
412
370
  return rb_funcall(cb, rb_intern("call"), 1, ary);
@@ -433,7 +391,7 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
433
391
  rb_ary_push(ary, ssl_obj);
434
392
  rb_ary_push(ary, sess_obj);
435
393
 
436
- rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state);
394
+ rb_protect(ossl_call_session_new_cb, ary, &state);
437
395
  if (state) {
438
396
  rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
439
397
  }
@@ -532,6 +490,7 @@ ossl_call_servername_cb(VALUE ary)
532
490
  GetSSL(ssl_obj, ssl);
533
491
  GetSSLCTX(ret_obj, ctx2);
534
492
  SSL_set_SSL_CTX(ssl, ctx2);
493
+ rb_iv_set(ssl_obj, "@context", ret_obj);
535
494
  } else if (!NIL_P(ret_obj)) {
536
495
  ossl_raise(rb_eArgError, "servername_cb must return an OpenSSL::SSL::SSLContext object or nil");
537
496
  }
@@ -600,13 +559,13 @@ ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
600
559
  return Qnil;
601
560
  }
602
561
 
603
- static void
604
- ssl_npn_encode_protocols(VALUE sslctx, VALUE protocols)
562
+ static VALUE
563
+ ssl_encode_npn_protocols(VALUE protocols)
605
564
  {
606
565
  VALUE encoded = rb_str_new2("");
607
566
  rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded);
608
567
  StringValueCStr(encoded);
609
- rb_iv_set(sslctx, "@_protocols", encoded);
568
+ return encoded;
610
569
  }
611
570
 
612
571
  static int
@@ -621,32 +580,61 @@ ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
621
580
  return SSL_TLSEXT_ERR_OK;
622
581
  }
623
582
 
583
+ static int
584
+ ssl_npn_select_cb_common(VALUE cb, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen)
585
+ {
586
+ VALUE selected;
587
+ long len;
588
+ VALUE protocols = rb_ary_new();
589
+ unsigned char l;
590
+ const unsigned char *in_end = in + inlen;
591
+
592
+ /* assume OpenSSL verifies this format */
593
+ /* The format is len_1|proto_1|...|len_n|proto_n */
594
+ while (in < in_end) {
595
+ l = *in++;
596
+ rb_ary_push(protocols, rb_str_new((const char *)in, l));
597
+ in += l;
598
+ }
599
+
600
+ selected = rb_funcall(cb, rb_intern("call"), 1, protocols);
601
+ StringValue(selected);
602
+ len = RSTRING_LEN(selected);
603
+ if (len < 1 || len >= 256) {
604
+ ossl_raise(eSSLError, "Selected protocol name must have length 1..255");
605
+ }
606
+ *out = (unsigned char *)RSTRING_PTR(selected);
607
+ *outlen = (unsigned char)len;
608
+
609
+ return SSL_TLSEXT_ERR_OK;
610
+ }
611
+
624
612
  static int
625
613
  ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
626
614
  {
627
- int i = 0;
628
- VALUE sslctx_obj, cb, protocols, selected;
615
+ VALUE sslctx_obj, cb;
629
616
 
630
617
  sslctx_obj = (VALUE) arg;
631
618
  cb = rb_iv_get(sslctx_obj, "@npn_select_cb");
632
- protocols = rb_ary_new();
633
619
 
634
- /* The format is len_1|proto_1|...|len_n|proto_n\0 */
635
- while (in[i]) {
636
- VALUE protocol = rb_str_new((const char *) &in[i + 1], in[i]);
637
- rb_ary_push(protocols, protocol);
638
- i += in[i] + 1;
639
- }
620
+ return ssl_npn_select_cb_common(cb, (const unsigned char **)out, outlen, in, inlen);
621
+ }
640
622
 
641
- selected = rb_funcall(cb, rb_intern("call"), 1, protocols);
642
- StringValue(selected);
643
- *out = (unsigned char *) StringValuePtr(selected);
644
- *outlen = RSTRING_LENINT(selected);
623
+ #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
624
+ static int
625
+ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
626
+ {
627
+ VALUE sslctx_obj, cb;
645
628
 
646
- return SSL_TLSEXT_ERR_OK;
629
+ sslctx_obj = (VALUE) arg;
630
+ cb = rb_iv_get(sslctx_obj, "@alpn_select_cb");
631
+
632
+ return ssl_npn_select_cb_common(cb, out, outlen, in, inlen);
647
633
  }
648
634
  #endif
649
635
 
636
+ #endif
637
+
650
638
  /* This function may serve as the entry point to support further
651
639
  * callbacks. */
652
640
  static void
@@ -660,6 +648,39 @@ ssl_info_cb(const SSL *ssl, int where, int val)
660
648
  }
661
649
  }
662
650
 
651
+ /*
652
+ * Gets various OpenSSL options.
653
+ */
654
+ static VALUE
655
+ ossl_sslctx_get_options(VALUE self)
656
+ {
657
+ SSL_CTX *ctx;
658
+ GetSSLCTX(self, ctx);
659
+ return LONG2NUM(SSL_CTX_get_options(ctx));
660
+ }
661
+
662
+ /*
663
+ * Sets various OpenSSL options.
664
+ */
665
+ static VALUE
666
+ ossl_sslctx_set_options(VALUE self, VALUE options)
667
+ {
668
+ SSL_CTX *ctx;
669
+
670
+ rb_check_frozen(self);
671
+ GetSSLCTX(self, ctx);
672
+
673
+ SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx));
674
+
675
+ if (NIL_P(options)) {
676
+ SSL_CTX_set_options(ctx, SSL_OP_ALL);
677
+ } else {
678
+ SSL_CTX_set_options(ctx, NUM2LONG(options));
679
+ }
680
+
681
+ return self;
682
+ }
683
+
663
684
  /*
664
685
  * call-seq:
665
686
  * ctx.setup => Qtrue # first time
@@ -677,21 +698,22 @@ ossl_sslctx_setup(VALUE self)
677
698
  X509_STORE *store;
678
699
  EVP_PKEY *key = NULL;
679
700
  char *ca_path = NULL, *ca_file = NULL;
680
- int i, verify_mode;
701
+ int verify_mode;
702
+ long i;
681
703
  VALUE val;
682
704
 
683
705
  if(OBJ_FROZEN(self)) return Qnil;
684
706
  GetSSLCTX(self, ctx);
685
707
 
686
708
  #if !defined(OPENSSL_NO_DH)
687
- if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){
688
- SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
689
- }
690
- else{
691
- SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback);
709
+ SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
710
+ #endif
711
+
712
+ #if !defined(OPENSSL_NO_EC)
713
+ if (RTEST(ossl_sslctx_get_tmp_ecdh_cb(self))){
714
+ SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
692
715
  }
693
716
  #endif
694
- SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self);
695
717
 
696
718
  val = ossl_sslctx_get_cert_store(self);
697
719
  if(!NIL_P(val)){
@@ -734,7 +756,7 @@ ossl_sslctx_setup(VALUE self)
734
756
  if(!NIL_P(val)){
735
757
  if (RB_TYPE_P(val, T_ARRAY)) {
736
758
  for(i = 0; i < RARRAY_LEN(val); i++){
737
- client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]);
759
+ client_ca = GetX509CertPtr(RARRAY_AREF(val, i));
738
760
  if (!SSL_CTX_add_client_CA(ctx, client_ca)){
739
761
  /* Copies X509_NAME => FREE it. */
740
762
  ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
@@ -771,17 +793,10 @@ ossl_sslctx_setup(VALUE self)
771
793
  val = ossl_sslctx_get_verify_dep(self);
772
794
  if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
773
795
 
774
- val = ossl_sslctx_get_options(self);
775
- if(!NIL_P(val)) {
776
- SSL_CTX_set_options(ctx, NUM2LONG(val));
777
- } else {
778
- SSL_CTX_set_options(ctx, SSL_OP_ALL);
779
- }
780
-
781
796
  #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
782
797
  val = rb_iv_get(self, "@npn_protocols");
783
798
  if (!NIL_P(val)) {
784
- ssl_npn_encode_protocols(self, val);
799
+ rb_iv_set(self, "@_protocols", ssl_encode_npn_protocols(val));
785
800
  SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *) self);
786
801
  OSSL_Debug("SSL NPN advertise callback added");
787
802
  }
@@ -791,6 +806,19 @@ ossl_sslctx_setup(VALUE self)
791
806
  }
792
807
  #endif
793
808
 
809
+ #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
810
+ val = rb_iv_get(self, "@alpn_protocols");
811
+ if (!NIL_P(val)) {
812
+ VALUE rprotos = ssl_encode_npn_protocols(val);
813
+ SSL_CTX_set_alpn_protos(ctx, (const unsigned char *)StringValueCStr(rprotos), RSTRING_LENINT(rprotos));
814
+ OSSL_Debug("SSL ALPN values added");
815
+ }
816
+ if (RTEST(rb_iv_get(self, "@alpn_select_cb"))) {
817
+ SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
818
+ OSSL_Debug("SSL ALPN select callback added");
819
+ }
820
+ #endif
821
+
794
822
  rb_obj_freeze(self);
795
823
 
796
824
  val = ossl_sslctx_get_sess_id_ctx(self);
@@ -1127,7 +1155,7 @@ ossl_ssl_shutdown(SSL *ssl)
1127
1155
  * Ignore the case SSL_shutdown returns -1. Empty handshake_func
1128
1156
  * must not happen.
1129
1157
  */
1130
- if (rc = SSL_shutdown(ssl))
1158
+ if ((rc = SSL_shutdown(ssl)) != 0)
1131
1159
  break;
1132
1160
  }
1133
1161
  SSL_clear(ssl);
@@ -1155,44 +1183,6 @@ ossl_ssl_s_alloc(VALUE klass)
1155
1183
  return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
1156
1184
  }
1157
1185
 
1158
- /*
1159
- * call-seq:
1160
- * SSLSocket.new(io) => aSSLSocket
1161
- * SSLSocket.new(io, ctx) => aSSLSocket
1162
- *
1163
- * Creates a new SSL socket from +io+ which must be a real ruby object (not an
1164
- * IO-like object that responds to read/write).
1165
- *
1166
- * If +ctx+ is provided the SSL Sockets initial params will be taken from
1167
- * the context.
1168
- *
1169
- * The OpenSSL::Buffering module provides additional IO methods.
1170
- *
1171
- * This method will freeze the SSLContext if one is provided;
1172
- * however, session management is still allowed in the frozen SSLContext.
1173
- */
1174
- static VALUE
1175
- ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1176
- {
1177
- VALUE io, ctx;
1178
-
1179
- if (rb_scan_args(argc, argv, "11", &io, &ctx) == 1) {
1180
- ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
1181
- }
1182
- OSSL_Check_Kind(ctx, cSSLContext);
1183
- Check_Type(io, T_FILE);
1184
- ossl_ssl_set_io(self, io);
1185
- ossl_ssl_set_ctx(self, ctx);
1186
- ossl_ssl_set_sync_close(self, Qfalse);
1187
- ossl_sslctx_setup(ctx);
1188
-
1189
- rb_iv_set(self, "@hostname", Qnil);
1190
-
1191
- rb_call_super(0, 0);
1192
-
1193
- return self;
1194
- }
1195
-
1196
1186
  static VALUE
1197
1187
  ossl_ssl_setup(VALUE self)
1198
1188
  {
@@ -1230,10 +1220,6 @@ ossl_ssl_setup(VALUE self)
1230
1220
  SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void*)self);
1231
1221
  cb = ossl_sslctx_get_verify_cb(v_ctx);
1232
1222
  SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void*)cb);
1233
- cb = ossl_sslctx_get_client_cert_cb(v_ctx);
1234
- SSL_set_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx, (void*)cb);
1235
- cb = ossl_sslctx_get_tmp_dh_cb(v_ctx);
1236
- SSL_set_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx, (void*)cb);
1237
1223
  SSL_set_info_callback(ssl, ssl_info_cb);
1238
1224
  }
1239
1225
 
@@ -1273,13 +1259,23 @@ read_would_block(int nonblock)
1273
1259
  }
1274
1260
  }
1275
1261
 
1262
+ static int
1263
+ no_exception_p(VALUE opts)
1264
+ {
1265
+ if (RB_TYPE_P(opts, T_HASH) &&
1266
+ rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse)
1267
+ return 1;
1268
+ return 0;
1269
+ }
1270
+
1276
1271
  static VALUE
1277
- ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, int nonblock)
1272
+ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1278
1273
  {
1279
1274
  SSL *ssl;
1280
1275
  rb_io_t *fptr;
1281
1276
  int ret, ret2;
1282
1277
  VALUE cb_state;
1278
+ int nonblock = opts != Qfalse;
1283
1279
 
1284
1280
  rb_ivar_set(self, ID_callback_state, Qnil);
1285
1281
 
@@ -1298,10 +1294,12 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, int nonblock)
1298
1294
 
1299
1295
  switch((ret2 = ssl_get_error(ssl, ret))){
1300
1296
  case SSL_ERROR_WANT_WRITE:
1297
+ if (no_exception_p(opts)) { return sym_wait_writable; }
1301
1298
  write_would_block(nonblock);
1302
1299
  rb_io_wait_writable(FPTR_TO_FD(fptr));
1303
1300
  continue;
1304
1301
  case SSL_ERROR_WANT_READ:
1302
+ if (no_exception_p(opts)) { return sym_wait_readable; }
1305
1303
  read_would_block(nonblock);
1306
1304
  rb_io_wait_readable(FPTR_TO_FD(fptr));
1307
1305
  continue;
@@ -1327,12 +1325,13 @@ static VALUE
1327
1325
  ossl_ssl_connect(VALUE self)
1328
1326
  {
1329
1327
  ossl_ssl_setup(self);
1330
- return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0);
1328
+
1329
+ return ossl_start_ssl(self, SSL_connect, "SSL_connect", Qfalse);
1331
1330
  }
1332
1331
 
1333
1332
  /*
1334
1333
  * call-seq:
1335
- * ssl.connect_nonblock => self
1334
+ * ssl.connect_nonblock([options]) => self
1336
1335
  *
1337
1336
  * Initiates the SSL/TLS handshake as a client in non-blocking manner.
1338
1337
  *
@@ -1347,12 +1346,20 @@ ossl_ssl_connect(VALUE self)
1347
1346
  * retry
1348
1347
  * end
1349
1348
  *
1349
+ * By specifying `exception: false`, the options hash allows you to indicate
1350
+ * that connect_nonblock should not raise an IO::WaitReadable or
1351
+ * IO::WaitWritable exception, but return the symbol :wait_readable or
1352
+ * :wait_writable instead.
1350
1353
  */
1351
1354
  static VALUE
1352
- ossl_ssl_connect_nonblock(VALUE self)
1355
+ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
1353
1356
  {
1357
+ VALUE opts;
1358
+ rb_scan_args(argc, argv, "0:", &opts);
1359
+
1354
1360
  ossl_ssl_setup(self);
1355
- return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1);
1361
+
1362
+ return ossl_start_ssl(self, SSL_connect, "SSL_connect", opts);
1356
1363
  }
1357
1364
 
1358
1365
  /*
@@ -1366,12 +1373,13 @@ static VALUE
1366
1373
  ossl_ssl_accept(VALUE self)
1367
1374
  {
1368
1375
  ossl_ssl_setup(self);
1369
- return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0);
1376
+
1377
+ return ossl_start_ssl(self, SSL_accept, "SSL_accept", Qfalse);
1370
1378
  }
1371
1379
 
1372
1380
  /*
1373
1381
  * call-seq:
1374
- * ssl.accept_nonblock => self
1382
+ * ssl.accept_nonblock([options]) => self
1375
1383
  *
1376
1384
  * Initiates the SSL/TLS handshake as a server in non-blocking manner.
1377
1385
  *
@@ -1386,12 +1394,20 @@ ossl_ssl_accept(VALUE self)
1386
1394
  * retry
1387
1395
  * end
1388
1396
  *
1397
+ * By specifying `exception: false`, the options hash allows you to indicate
1398
+ * that accept_nonblock should not raise an IO::WaitReadable or
1399
+ * IO::WaitWritable exception, but return the symbol :wait_readable or
1400
+ * :wait_writable instead.
1389
1401
  */
1390
1402
  static VALUE
1391
- ossl_ssl_accept_nonblock(VALUE self)
1403
+ ossl_ssl_accept_nonblock(int argc, VALUE *argv, VALUE self)
1392
1404
  {
1405
+ VALUE opts;
1406
+
1407
+ rb_scan_args(argc, argv, "0:", &opts);
1393
1408
  ossl_ssl_setup(self);
1394
- return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1);
1409
+
1410
+ return ossl_start_ssl(self, SSL_accept, "SSL_accept", opts);
1395
1411
  }
1396
1412
 
1397
1413
  static VALUE
@@ -1399,15 +1415,15 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1399
1415
  {
1400
1416
  SSL *ssl;
1401
1417
  int ilen, nread = 0;
1402
- int no_exception = 0;
1403
1418
  VALUE len, str;
1404
1419
  rb_io_t *fptr;
1405
1420
  VALUE opts = Qnil;
1406
1421
 
1407
- rb_scan_args(argc, argv, "11:", &len, &str, &opts);
1408
-
1409
- if (!NIL_P(opts) && Qfalse == rb_hash_aref(opts, sym_exception))
1410
- no_exception = 1;
1422
+ if (nonblock) {
1423
+ rb_scan_args(argc, argv, "11:", &len, &str, &opts);
1424
+ } else {
1425
+ rb_scan_args(argc, argv, "11", &len, &str);
1426
+ }
1411
1427
 
1412
1428
  ilen = NUM2INT(len);
1413
1429
  if(NIL_P(str)) str = rb_str_new(0, ilen);
@@ -1429,21 +1445,21 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1429
1445
  case SSL_ERROR_NONE:
1430
1446
  goto end;
1431
1447
  case SSL_ERROR_ZERO_RETURN:
1432
- if (no_exception) { return Qnil; }
1448
+ if (no_exception_p(opts)) { return Qnil; }
1433
1449
  rb_eof_error();
1434
1450
  case SSL_ERROR_WANT_WRITE:
1435
- if (no_exception) { return ID2SYM(rb_intern("wait_writable")); }
1451
+ if (no_exception_p(opts)) { return sym_wait_writable; }
1436
1452
  write_would_block(nonblock);
1437
1453
  rb_io_wait_writable(FPTR_TO_FD(fptr));
1438
1454
  continue;
1439
1455
  case SSL_ERROR_WANT_READ:
1440
- if (no_exception) { return ID2SYM(rb_intern("wait_readable")); }
1456
+ if (no_exception_p(opts)) { return sym_wait_readable; }
1441
1457
  read_would_block(nonblock);
1442
1458
  rb_io_wait_readable(FPTR_TO_FD(fptr));
1443
1459
  continue;
1444
1460
  case SSL_ERROR_SYSCALL:
1445
1461
  if(ERR_peek_error() == 0 && nread == 0) {
1446
- if (no_exception) { return Qnil; }
1462
+ if (no_exception_p(opts)) { return Qnil; }
1447
1463
  rb_eof_error();
1448
1464
  }
1449
1465
  rb_sys_fail(0);
@@ -1503,11 +1519,12 @@ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
1503
1519
  }
1504
1520
 
1505
1521
  static VALUE
1506
- ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock, int no_exception)
1522
+ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1507
1523
  {
1508
1524
  SSL *ssl;
1509
1525
  int nwrite = 0;
1510
1526
  rb_io_t *fptr;
1527
+ int nonblock = opts != Qfalse;
1511
1528
 
1512
1529
  StringValue(str);
1513
1530
  GetSSL(self, ssl);
@@ -1520,12 +1537,12 @@ ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock, int no_exception)
1520
1537
  case SSL_ERROR_NONE:
1521
1538
  goto end;
1522
1539
  case SSL_ERROR_WANT_WRITE:
1523
- if (no_exception) { return ID2SYM(rb_intern("wait_writable")); }
1540
+ if (no_exception_p(opts)) { return sym_wait_writable; }
1524
1541
  write_would_block(nonblock);
1525
1542
  rb_io_wait_writable(FPTR_TO_FD(fptr));
1526
1543
  continue;
1527
1544
  case SSL_ERROR_WANT_READ:
1528
- if (no_exception) { return ID2SYM(rb_intern("wait_readable")); }
1545
+ if (no_exception_p(opts)) { return sym_wait_readable; }
1529
1546
  read_would_block(nonblock);
1530
1547
  rb_io_wait_readable(FPTR_TO_FD(fptr));
1531
1548
  continue;
@@ -1555,7 +1572,7 @@ ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock, int no_exception)
1555
1572
  static VALUE
1556
1573
  ossl_ssl_write(VALUE self, VALUE str)
1557
1574
  {
1558
- return ossl_ssl_write_internal(self, str, 0, 0);
1575
+ return ossl_ssl_write_internal(self, str, Qfalse);
1559
1576
  }
1560
1577
 
1561
1578
  /*
@@ -1568,45 +1585,34 @@ ossl_ssl_write(VALUE self, VALUE str)
1568
1585
  static VALUE
1569
1586
  ossl_ssl_write_nonblock(int argc, VALUE *argv, VALUE self)
1570
1587
  {
1571
- VALUE str;
1572
- VALUE opts = Qnil;
1573
- int no_exception = 0;
1588
+ VALUE str, opts;
1574
1589
 
1575
1590
  rb_scan_args(argc, argv, "1:", &str, &opts);
1576
1591
 
1577
- if (!NIL_P(opts) && Qfalse == rb_hash_aref(opts, sym_exception))
1578
- no_exception = 1;
1579
-
1580
- return ossl_ssl_write_internal(self, str, 1, no_exception);
1592
+ return ossl_ssl_write_internal(self, str, opts);
1581
1593
  }
1582
1594
 
1583
1595
  /*
1584
1596
  * call-seq:
1585
- * ssl.sysclose => nil
1597
+ * ssl.stop => nil
1586
1598
  *
1587
- * Shuts down the SSL connection and prepares it for another connection.
1599
+ * Stops the SSL connection and prepares it for another connection.
1588
1600
  */
1589
1601
  static VALUE
1590
- ossl_ssl_close(VALUE self)
1602
+ ossl_ssl_stop(VALUE self)
1591
1603
  {
1592
1604
  SSL *ssl;
1593
- VALUE io;
1594
1605
 
1595
1606
  /* ossl_ssl_data_get_struct() is not usable here because it may return
1596
1607
  * from this function; */
1597
1608
 
1598
1609
  GetSSL(self, ssl);
1599
1610
 
1600
- io = ossl_ssl_get_io(self);
1601
- if (!RTEST(rb_funcall(io, rb_intern("closed?"), 0))) {
1602
- if (ssl) {
1603
- ossl_ssl_shutdown(ssl);
1604
- SSL_free(ssl);
1605
- }
1606
- DATA_PTR(self) = NULL;
1607
- if (RTEST(ossl_ssl_get_sync_close(self)))
1608
- rb_funcall(io, rb_intern("close"), 0);
1611
+ if (ssl) {
1612
+ ossl_ssl_shutdown(ssl);
1613
+ SSL_free(ssl);
1609
1614
  }
1615
+ DATA_PTR(self) = NULL;
1610
1616
 
1611
1617
  return Qnil;
1612
1618
  }
@@ -1879,6 +1885,31 @@ ossl_ssl_npn_protocol(VALUE self)
1879
1885
  return rb_str_new((const char *) out, outlen);
1880
1886
  }
1881
1887
  # endif
1888
+
1889
+ # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
1890
+ /*
1891
+ * call-seq:
1892
+ * ssl.alpn_protocol => String
1893
+ *
1894
+ * Returns the ALPN protocol string that was finally selected by the client
1895
+ * during the handshake.
1896
+ */
1897
+ static VALUE
1898
+ ossl_ssl_alpn_protocol(VALUE self)
1899
+ {
1900
+ SSL *ssl;
1901
+ const unsigned char *out;
1902
+ unsigned int outlen;
1903
+
1904
+ ossl_ssl_data_get_struct(self, ssl);
1905
+
1906
+ SSL_get0_alpn_selected(ssl, &out, &outlen);
1907
+ if (!outlen)
1908
+ return Qnil;
1909
+ else
1910
+ return rb_str_new((const char *) out, outlen);
1911
+ }
1912
+ # endif
1882
1913
  #endif /* !defined(OPENSSL_NO_SOCK) */
1883
1914
 
1884
1915
  void
@@ -1896,10 +1927,6 @@ Init_ossl_ssl(void)
1896
1927
  ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0);
1897
1928
  ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0);
1898
1929
  ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_ptr_idx",0,0,0);
1899
- ossl_ssl_ex_client_cert_cb_idx =
1900
- SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_client_cert_cb_idx",0,0,0);
1901
- ossl_ssl_ex_tmp_dh_callback_idx =
1902
- SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_tmp_dh_callback_idx",0,0,0);
1903
1930
 
1904
1931
  /* Document-module: OpenSSL::SSL
1905
1932
  *
@@ -1909,6 +1936,17 @@ Init_ossl_ssl(void)
1909
1936
  * of SSLContext to set up connections.
1910
1937
  */
1911
1938
  mSSL = rb_define_module_under(mOSSL, "SSL");
1939
+
1940
+ /* Document-module: OpenSSL::ExtConfig
1941
+ *
1942
+ * This module contains configuration information about the SSL extension,
1943
+ * for example if socket support is enabled, or the host name TLS extension
1944
+ * is enabled. Constants in this module will always be defined, but contain
1945
+ * `true` or `false` values depending on the configuration of your OpenSSL
1946
+ * installation.
1947
+ */
1948
+ mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig");
1949
+
1912
1950
  /* Document-class: OpenSSL::SSL::SSLError
1913
1951
  *
1914
1952
  * Generic error class raised by SSLSocket and SSLContext.
@@ -1996,11 +2034,6 @@ Init_ossl_ssl(void)
1996
2034
  */
1997
2035
  rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
1998
2036
 
1999
- /*
2000
- * Sets various OpenSSL options.
2001
- */
2002
- rb_attr(cSSLContext, rb_intern("options"), 1, 1, Qfalse);
2003
-
2004
2037
  /*
2005
2038
  * An OpenSSL::X509::Store used for certificate verification
2006
2039
  */
@@ -2023,16 +2056,16 @@ Init_ossl_ssl(void)
2023
2056
  rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
2024
2057
 
2025
2058
  /*
2026
- * A callback invoked when DH parameters are required.
2059
+ * A callback invoked when ECDH parameters are required.
2027
2060
  *
2028
2061
  * The callback is invoked with the Session for the key exchange, an
2029
2062
  * flag indicating the use of an export cipher and the keylength
2030
2063
  * required.
2031
2064
  *
2032
- * The callback must return an OpenSSL::PKey::DH instance of the correct
2065
+ * The callback must return an OpenSSL::PKey::EC instance of the correct
2033
2066
  * key length.
2034
2067
  */
2035
- rb_attr(cSSLContext, rb_intern("tmp_dh_callback"), 1, 1, Qfalse);
2068
+ rb_attr(cSSLContext, rb_intern("tmp_ecdh_callback"), 1, 1, Qfalse);
2036
2069
 
2037
2070
  /*
2038
2071
  * Sets the context in which a session can be reused. This allows
@@ -2066,15 +2099,17 @@ Init_ossl_ssl(void)
2066
2099
  rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
2067
2100
 
2068
2101
  #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
2069
- /*
2070
- * A callback invoked at connect time to distinguish between multiple
2071
- * server names.
2072
- *
2073
- * The callback is invoked with an SSLSocket and a server name. The
2074
- * callback must return an SSLContext for the server name or nil.
2075
- */
2076
- rb_attr(cSSLContext, rb_intern("servername_cb"), 1, 1, Qfalse);
2102
+ rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
2103
+ #else
2104
+ rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qfalse);
2077
2105
  #endif
2106
+
2107
+ #ifdef TLS_DH_anon_WITH_AES_256_GCM_SHA384
2108
+ rb_define_const(mSSLExtConfig, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", Qtrue);
2109
+ #else
2110
+ rb_define_const(mSSLExtConfig, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", Qfalse);
2111
+ #endif
2112
+
2078
2113
  /*
2079
2114
  * A callback invoked whenever a new handshake is initiated. May be used
2080
2115
  * to disable renegotiation entirely.
@@ -2129,9 +2164,40 @@ Init_ossl_ssl(void)
2129
2164
  rb_attr(cSSLContext, rb_intern("npn_select_cb"), 1, 1, Qfalse);
2130
2165
  #endif
2131
2166
 
2167
+ #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2168
+ /*
2169
+ * An Enumerable of Strings. Each String represents a protocol to be
2170
+ * advertised as the list of supported protocols for Application-Layer Protocol
2171
+ * Negotiation. Supported in OpenSSL 1.0.1 and higher. Has no effect
2172
+ * on the client side. If not set explicitly, the NPN extension will
2173
+ * not be sent by the server in the handshake.
2174
+ *
2175
+ * === Example
2176
+ *
2177
+ * ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"]
2178
+ */
2179
+ rb_attr(cSSLContext, rb_intern("alpn_protocols"), 1, 1, Qfalse);
2180
+ /*
2181
+ * A callback invoked on the server side when the server needs to select
2182
+ * a protocol from the list sent by the client. Supported in OpenSSL 1.0.2
2183
+ * and higher. The server MUST select a protocol of those advertised by
2184
+ * the client. If none is acceptable, raising an error in the callback
2185
+ * will cause the handshake to fail. Not setting this callback explicitly
2186
+ * means not supporting the ALPN extension on the client - any protocols
2187
+ * advertised by the server will be ignored.
2188
+ *
2189
+ * === Example
2190
+ *
2191
+ * ctx.alpn_select_cb = lambda do |protocols|
2192
+ * #inspect the protocols and select one
2193
+ * protocols.first
2194
+ * end
2195
+ */
2196
+ rb_attr(cSSLContext, rb_intern("alpn_select_cb"), 1, 1, Qfalse);
2197
+ #endif
2198
+
2132
2199
  rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2133
2200
  rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
2134
- rb_define_method(cSSLContext, "initialize", ossl_sslctx_initialize, -1);
2135
2201
  rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1);
2136
2202
  rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2137
2203
  rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
@@ -2193,6 +2259,8 @@ Init_ossl_ssl(void)
2193
2259
  rb_define_method(cSSLContext, "session_cache_size=", ossl_sslctx_set_session_cache_size, 1);
2194
2260
  rb_define_method(cSSLContext, "session_cache_stats", ossl_sslctx_get_session_cache_stats, 0);
2195
2261
  rb_define_method(cSSLContext, "flush_sessions", ossl_sslctx_flush_sessions, -1);
2262
+ rb_define_method(cSSLContext, "options", ossl_sslctx_get_options, 0);
2263
+ rb_define_method(cSSLContext, "options=", ossl_sslctx_set_options, 1);
2196
2264
 
2197
2265
  ary = rb_ary_new2(numberof(ossl_ssl_method_tab));
2198
2266
  for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
@@ -2211,24 +2279,19 @@ Init_ossl_ssl(void)
2211
2279
  */
2212
2280
  cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
2213
2281
  #ifdef OPENSSL_NO_SOCK
2214
- rb_define_method(cSSLSocket, "initialize", rb_notimplement, -1);
2282
+ rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue);
2215
2283
  #else
2284
+ rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse);
2216
2285
  rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
2217
- for(i = 0; i < numberof(ossl_ssl_attr_readers); i++)
2218
- rb_attr(cSSLSocket, rb_intern(ossl_ssl_attr_readers[i]), 1, 0, Qfalse);
2219
- for(i = 0; i < numberof(ossl_ssl_attrs); i++)
2220
- rb_attr(cSSLSocket, rb_intern(ossl_ssl_attrs[i]), 1, 1, Qfalse);
2221
- rb_define_alias(cSSLSocket, "to_io", "io");
2222
- rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
2223
2286
  rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0);
2224
- rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, 0);
2287
+ rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, -1);
2225
2288
  rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0);
2226
- rb_define_method(cSSLSocket, "accept_nonblock", ossl_ssl_accept_nonblock, 0);
2289
+ rb_define_method(cSSLSocket, "accept_nonblock", ossl_ssl_accept_nonblock, -1);
2227
2290
  rb_define_method(cSSLSocket, "sysread", ossl_ssl_read, -1);
2228
2291
  rb_define_private_method(cSSLSocket, "sysread_nonblock", ossl_ssl_read_nonblock, -1);
2229
2292
  rb_define_method(cSSLSocket, "syswrite", ossl_ssl_write, 1);
2230
2293
  rb_define_private_method(cSSLSocket, "syswrite_nonblock", ossl_ssl_write_nonblock, -1);
2231
- rb_define_method(cSSLSocket, "sysclose", ossl_ssl_close, 0);
2294
+ rb_define_private_method(cSSLSocket, "stop", ossl_ssl_stop, 0);
2232
2295
  rb_define_method(cSSLSocket, "cert", ossl_ssl_get_cert, 0);
2233
2296
  rb_define_method(cSSLSocket, "peer_cert", ossl_ssl_get_peer_cert, 0);
2234
2297
  rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0);
@@ -2241,12 +2304,15 @@ Init_ossl_ssl(void)
2241
2304
  rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1);
2242
2305
  rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
2243
2306
  rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
2307
+ # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2308
+ rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
2309
+ # endif
2244
2310
  # ifdef HAVE_OPENSSL_NPN_NEGOTIATED
2245
2311
  rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2246
2312
  # endif
2247
2313
  #endif
2248
2314
 
2249
- #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2NUM(SSL_##x))
2315
+ #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, LONG2NUM(SSL_##x))
2250
2316
 
2251
2317
  ossl_ssl_def_const(VERIFY_NONE);
2252
2318
  ossl_ssl_def_const(VERIFY_PEER);
@@ -2301,5 +2367,8 @@ Init_ossl_ssl(void)
2301
2367
  ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG);
2302
2368
  ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
2303
2369
 
2370
+ #undef rb_intern
2304
2371
  sym_exception = ID2SYM(rb_intern("exception"));
2372
+ sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
2373
+ sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
2305
2374
  }