openssl 2.0.9 → 2.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of openssl might be problematic. Click here for more details.

Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +28 -69
  3. data/README.md +1 -1
  4. data/ext/openssl/deprecation.rb +0 -3
  5. data/ext/openssl/extconf.rb +8 -52
  6. data/ext/openssl/openssl_missing.c +0 -67
  7. data/ext/openssl/openssl_missing.h +3 -50
  8. data/ext/openssl/ossl.c +81 -74
  9. data/ext/openssl/ossl.h +14 -27
  10. data/ext/openssl/ossl_asn1.c +287 -374
  11. data/ext/openssl/ossl_asn1.h +0 -4
  12. data/ext/openssl/ossl_bio.c +5 -20
  13. data/ext/openssl/ossl_bio.h +0 -2
  14. data/ext/openssl/ossl_bn.c +70 -28
  15. data/ext/openssl/ossl_cipher.c +18 -42
  16. data/ext/openssl/ossl_cipher.h +1 -1
  17. data/ext/openssl/ossl_digest.c +8 -12
  18. data/ext/openssl/ossl_digest.h +1 -1
  19. data/ext/openssl/ossl_engine.c +47 -47
  20. data/ext/openssl/ossl_hmac.c +19 -22
  21. data/ext/openssl/ossl_kdf.c +221 -0
  22. data/ext/openssl/ossl_kdf.h +6 -0
  23. data/ext/openssl/ossl_ns_spki.c +17 -21
  24. data/ext/openssl/ossl_ocsp.c +85 -80
  25. data/ext/openssl/ossl_pkcs12.c +15 -21
  26. data/ext/openssl/ossl_pkcs7.c +8 -21
  27. data/ext/openssl/ossl_pkey.c +24 -48
  28. data/ext/openssl/ossl_pkey.h +1 -6
  29. data/ext/openssl/ossl_pkey_dh.c +11 -11
  30. data/ext/openssl/ossl_pkey_dsa.c +16 -22
  31. data/ext/openssl/ossl_pkey_ec.c +43 -56
  32. data/ext/openssl/ossl_pkey_rsa.c +19 -19
  33. data/ext/openssl/ossl_rand.c +12 -12
  34. data/ext/openssl/ossl_ssl.c +291 -243
  35. data/ext/openssl/ossl_ssl.h +0 -5
  36. data/ext/openssl/ossl_ssl_session.c +7 -9
  37. data/ext/openssl/ossl_version.h +1 -1
  38. data/ext/openssl/ossl_x509.c +0 -15
  39. data/ext/openssl/ossl_x509.h +0 -7
  40. data/ext/openssl/ossl_x509attr.c +3 -7
  41. data/ext/openssl/ossl_x509cert.c +17 -54
  42. data/ext/openssl/ossl_x509crl.c +15 -25
  43. data/ext/openssl/ossl_x509ext.c +9 -14
  44. data/ext/openssl/ossl_x509name.c +76 -41
  45. data/ext/openssl/ossl_x509req.c +10 -47
  46. data/ext/openssl/ossl_x509revoked.c +8 -8
  47. data/ext/openssl/ossl_x509store.c +15 -45
  48. data/ext/openssl/ruby_missing.h +2 -13
  49. data/lib/openssl.rb +1 -0
  50. data/lib/openssl/bn.rb +2 -1
  51. data/lib/openssl/buffering.rb +24 -23
  52. data/lib/openssl/config.rb +12 -11
  53. data/lib/openssl/digest.rb +3 -6
  54. data/lib/openssl/pkcs5.rb +22 -0
  55. data/lib/openssl/pkey.rb +0 -41
  56. data/lib/openssl/ssl.rb +118 -16
  57. data/lib/openssl/x509.rb +7 -1
  58. metadata +8 -7
  59. data/ext/openssl/ossl_pkcs5.c +0 -180
  60. data/ext/openssl/ossl_pkcs5.h +0 -6
@@ -16,7 +16,7 @@ VALUE eRandomError;
16
16
  * call-seq:
17
17
  * seed(str) -> str
18
18
  *
19
- * ::seed is equivalent to ::add where +entropy+ is length of +str+.
19
+ * ::seed is equivalent to ::add where _entropy_ is length of _str_.
20
20
  */
21
21
  static VALUE
22
22
  ossl_rand_seed(VALUE self, VALUE str)
@@ -31,15 +31,15 @@ ossl_rand_seed(VALUE self, VALUE str)
31
31
  * call-seq:
32
32
  * add(str, entropy) -> self
33
33
  *
34
- * Mixes the bytes from +str+ into the Pseudo Random Number Generator(PRNG)
34
+ * Mixes the bytes from _str_ into the Pseudo Random Number Generator(PRNG)
35
35
  * state.
36
36
  *
37
- * Thus, if the data from +str+ are unpredictable to an adversary, this
37
+ * Thus, if the data from _str_ are unpredictable to an adversary, this
38
38
  * increases the uncertainty about the state and makes the PRNG output less
39
39
  * predictable.
40
40
  *
41
- * The +entropy+ argument is (the lower bound of) an estimate of how much
42
- * randomness is contained in +str+, measured in bytes.
41
+ * The _entropy_ argument is (the lower bound of) an estimate of how much
42
+ * randomness is contained in _str_, measured in bytes.
43
43
  *
44
44
  * === Example
45
45
  *
@@ -62,7 +62,7 @@ ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
62
62
  * call-seq:
63
63
  * load_random_file(filename) -> true
64
64
  *
65
- * Reads bytes from +filename+ and adds them to the PRNG.
65
+ * Reads bytes from _filename_ and adds them to the PRNG.
66
66
  */
67
67
  static VALUE
68
68
  ossl_rand_load_file(VALUE self, VALUE filename)
@@ -79,7 +79,7 @@ ossl_rand_load_file(VALUE self, VALUE filename)
79
79
  * call-seq:
80
80
  * write_random_file(filename) -> true
81
81
  *
82
- * Writes a number of random generated bytes (currently 1024) to +filename+
82
+ * Writes a number of random generated bytes (currently 1024) to _filename_
83
83
  * which can be used to initialize the PRNG by calling ::load_random_file in a
84
84
  * later session.
85
85
  */
@@ -98,7 +98,7 @@ ossl_rand_write_file(VALUE self, VALUE filename)
98
98
  * call-seq:
99
99
  * random_bytes(length) -> string
100
100
  *
101
- * Generates +string+ with +length+ number of cryptographically strong
101
+ * Generates a String with _length_ number of cryptographically strong
102
102
  * pseudo-random bytes.
103
103
  *
104
104
  * === Example
@@ -129,7 +129,7 @@ ossl_rand_bytes(VALUE self, VALUE len)
129
129
  * call-seq:
130
130
  * pseudo_bytes(length) -> string
131
131
  *
132
- * Generates +string+ with +length+ number of pseudo-random bytes.
132
+ * Generates a String with _length_ number of pseudo-random bytes.
133
133
  *
134
134
  * Pseudo-random byte sequences generated by ::pseudo_bytes will be unique if
135
135
  * they are of sufficient length, but are not necessarily unpredictable.
@@ -176,9 +176,9 @@ ossl_rand_egd(VALUE self, VALUE filename)
176
176
  * call-seq:
177
177
  * egd_bytes(filename, length) -> true
178
178
  *
179
- * Queries the entropy gathering daemon EGD on socket path given by +filename+.
179
+ * Queries the entropy gathering daemon EGD on socket path given by _filename_.
180
180
  *
181
- * Fetches +length+ number of bytes and uses ::add to seed the OpenSSL built-in
181
+ * Fetches _length_ number of bytes and uses ::add to seed the OpenSSL built-in
182
182
  * PRNG.
183
183
  */
184
184
  static VALUE
@@ -199,7 +199,7 @@ ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
199
199
  * call-seq:
200
200
  * status? => true | false
201
201
  *
202
- * Return true if the PRNG has been seeded with enough data, false otherwise.
202
+ * Return +true+ if the PRNG has been seeded with enough data, +false+ otherwise.
203
203
  */
204
204
  static VALUE
205
205
  ossl_rand_status(VALUE self)
@@ -46,54 +46,19 @@ static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
46
46
  id_i_verify_hostname;
47
47
  static ID id_i_io, id_i_context, id_i_hostname;
48
48
 
49
- /*
50
- * SSLContext class
51
- */
52
- static const struct {
53
- const char *name;
54
- SSL_METHOD *(*func)(void); /* FIXME: constify when dropping 0.9.8 */
55
- int version;
56
- } ossl_ssl_method_tab[] = {
57
- #if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
58
- #define OSSL_SSL_METHOD_ENTRY(name, version) \
59
- { #name, (SSL_METHOD *(*)(void))TLS_method, version }, \
60
- { #name"_server", (SSL_METHOD *(*)(void))TLS_server_method, version }, \
61
- { #name"_client", (SSL_METHOD *(*)(void))TLS_client_method, version }
62
- #else
63
- #define OSSL_SSL_METHOD_ENTRY(name, version) \
64
- { #name, (SSL_METHOD *(*)(void))name##_method, version }, \
65
- { #name"_server", (SSL_METHOD *(*)(void))name##_server_method, version }, \
66
- { #name"_client", (SSL_METHOD *(*)(void))name##_client_method, version }
67
- #endif
68
- #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL2_METHOD) && defined(HAVE_SSLV2_METHOD)
69
- OSSL_SSL_METHOD_ENTRY(SSLv2, SSL2_VERSION),
70
- #endif
71
- #if !defined(OPENSSL_NO_SSL3) && !defined(OPENSSL_NO_SSL3_METHOD) && defined(HAVE_SSLV3_METHOD)
72
- OSSL_SSL_METHOD_ENTRY(SSLv3, SSL3_VERSION),
73
- #endif
74
- #if !defined(OPENSSL_NO_TLS1) && !defined(OPENSSL_NO_TLS1_METHOD)
75
- OSSL_SSL_METHOD_ENTRY(TLSv1, TLS1_VERSION),
76
- #endif
77
- #if !defined(OPENSSL_NO_TLS1_1) && !defined(OPENSSL_NO_TLS1_1_METHOD) && defined(HAVE_TLSV1_1_METHOD)
78
- OSSL_SSL_METHOD_ENTRY(TLSv1_1, TLS1_1_VERSION),
79
- #endif
80
- #if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_TLS1_2_METHOD) && defined(HAVE_TLSV1_2_METHOD)
81
- OSSL_SSL_METHOD_ENTRY(TLSv1_2, TLS1_2_VERSION),
82
- #endif
83
- OSSL_SSL_METHOD_ENTRY(SSLv23, 0),
84
- #undef OSSL_SSL_METHOD_ENTRY
85
- };
86
-
87
49
  static int ossl_ssl_ex_vcb_idx;
88
- static int ossl_ssl_ex_store_p;
89
50
  static int ossl_ssl_ex_ptr_idx;
51
+ static int ossl_sslctx_ex_ptr_idx;
52
+ #if !defined(HAVE_X509_STORE_UP_REF)
53
+ static int ossl_sslctx_ex_store_p;
54
+ #endif
90
55
 
91
56
  static void
92
57
  ossl_sslctx_free(void *ptr)
93
58
  {
94
59
  SSL_CTX *ctx = ptr;
95
60
  #if !defined(HAVE_X509_STORE_UP_REF)
96
- if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1)
61
+ if (ctx && SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_store_p))
97
62
  ctx->cert_store = NULL;
98
63
  #endif
99
64
  SSL_CTX_free(ctx);
@@ -111,22 +76,24 @@ static VALUE
111
76
  ossl_sslctx_s_alloc(VALUE klass)
112
77
  {
113
78
  SSL_CTX *ctx;
114
- long mode = SSL_MODE_ENABLE_PARTIAL_WRITE |
115
- SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
79
+ long mode = 0 |
80
+ SSL_MODE_ENABLE_PARTIAL_WRITE |
81
+ SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
82
+ SSL_MODE_RELEASE_BUFFERS;
116
83
  VALUE obj;
117
84
 
118
- #ifdef SSL_MODE_RELEASE_BUFFERS
119
- mode |= SSL_MODE_RELEASE_BUFFERS;
120
- #endif
121
-
122
85
  obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
86
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
87
+ ctx = SSL_CTX_new(TLS_method());
88
+ #else
123
89
  ctx = SSL_CTX_new(SSLv23_method());
90
+ #endif
124
91
  if (!ctx) {
125
92
  ossl_raise(eSSLError, "SSL_CTX_new");
126
93
  }
127
94
  SSL_CTX_set_mode(ctx, mode);
128
95
  RTYPEDDATA_DATA(obj) = ctx;
129
- SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)obj);
96
+ SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj);
130
97
 
131
98
  #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
132
99
  /* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
@@ -143,49 +110,89 @@ ossl_sslctx_s_alloc(VALUE klass)
143
110
  return obj;
144
111
  }
145
112
 
113
+ static int
114
+ parse_proto_version(VALUE str)
115
+ {
116
+ int i;
117
+ static const struct {
118
+ const char *name;
119
+ int version;
120
+ } map[] = {
121
+ { "SSL2", SSL2_VERSION },
122
+ { "SSL3", SSL3_VERSION },
123
+ { "TLS1", TLS1_VERSION },
124
+ { "TLS1_1", TLS1_1_VERSION },
125
+ { "TLS1_2", TLS1_2_VERSION },
126
+ #ifdef TLS1_3_VERSION
127
+ { "TLS1_3", TLS1_3_VERSION },
128
+ #endif
129
+ };
130
+
131
+ if (NIL_P(str))
132
+ return 0;
133
+ if (RB_INTEGER_TYPE_P(str))
134
+ return NUM2INT(str);
135
+
136
+ if (SYMBOL_P(str))
137
+ str = rb_sym2str(str);
138
+ StringValue(str);
139
+ for (i = 0; i < numberof(map); i++)
140
+ if (!strncmp(map[i].name, RSTRING_PTR(str), RSTRING_LEN(str)))
141
+ return map[i].version;
142
+ rb_raise(rb_eArgError, "unrecognized version %+"PRIsVALUE, str);
143
+ }
144
+
146
145
  /*
147
146
  * call-seq:
148
- * ctx.ssl_version = :TLSv1
149
- * ctx.ssl_version = "SSLv23_client"
147
+ * ctx.set_minmax_proto_version(min, max) -> nil
150
148
  *
151
- * Sets the SSL/TLS protocol version for the context. This forces connections to
152
- * use only the specified protocol version.
153
- *
154
- * You can get a list of valid versions with OpenSSL::SSL::SSLContext::METHODS
149
+ * Sets the minimum and maximum supported protocol versions. See #min_version=
150
+ * and #max_version=.
155
151
  */
156
152
  static VALUE
157
- ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
153
+ ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
158
154
  {
159
155
  SSL_CTX *ctx;
160
- const char *s;
161
- VALUE m = ssl_method;
162
- int i;
156
+ int min, max;
163
157
 
164
158
  GetSSLCTX(self, ctx);
165
- if (RB_TYPE_P(ssl_method, T_SYMBOL))
166
- m = rb_sym2str(ssl_method);
167
- s = StringValueCStr(m);
168
- for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
169
- if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) {
170
- #if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
171
- int version = ossl_ssl_method_tab[i].version;
172
- #endif
173
- SSL_METHOD *method = ossl_ssl_method_tab[i].func();
174
-
175
- if (SSL_CTX_set_ssl_version(ctx, method) != 1)
176
- ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");
159
+ min = parse_proto_version(min_v);
160
+ max = parse_proto_version(max_v);
161
+
162
+ #ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
163
+ if (!SSL_CTX_set_min_proto_version(ctx, min))
164
+ ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
165
+ if (!SSL_CTX_set_max_proto_version(ctx, max))
166
+ ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
167
+ #else
168
+ {
169
+ unsigned long sum = 0, opts = 0;
170
+ int i;
171
+ static const struct {
172
+ int ver;
173
+ unsigned long opts;
174
+ } options_map[] = {
175
+ { SSL2_VERSION, SSL_OP_NO_SSLv2 },
176
+ { SSL3_VERSION, SSL_OP_NO_SSLv3 },
177
+ { TLS1_VERSION, SSL_OP_NO_TLSv1 },
178
+ { TLS1_1_VERSION, SSL_OP_NO_TLSv1_1 },
179
+ { TLS1_2_VERSION, SSL_OP_NO_TLSv1_2 },
180
+ # if defined(TLS1_3_VERSION)
181
+ { TLS1_3_VERSION, SSL_OP_NO_TLSv1_3 },
182
+ # endif
183
+ };
177
184
 
178
- #if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
179
- if (!SSL_CTX_set_min_proto_version(ctx, version))
180
- ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
181
- if (!SSL_CTX_set_max_proto_version(ctx, version))
182
- ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
183
- #endif
184
- return ssl_method;
185
- }
185
+ for (i = 0; i < numberof(options_map); i++) {
186
+ sum |= options_map[i].opts;
187
+ if (min && min > options_map[i].ver || max && max < options_map[i].ver)
188
+ opts |= options_map[i].opts;
189
+ }
190
+ SSL_CTX_clear_options(ctx, sum);
191
+ SSL_CTX_set_options(ctx, opts);
186
192
  }
193
+ #endif
187
194
 
188
- ossl_raise(rb_eArgError, "unknown SSL method `%"PRIsVALUE"'.", m);
195
+ return Qnil;
189
196
  }
190
197
 
191
198
  static VALUE
@@ -380,13 +387,10 @@ ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
380
387
  {
381
388
  VALUE ary, ssl_obj, ret_obj;
382
389
  SSL_SESSION *sess;
383
- void *ptr;
384
390
  int state = 0;
385
391
 
386
392
  OSSL_Debug("SSL SESSION get callback entered");
387
- if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
388
- return NULL;
389
- ssl_obj = (VALUE)ptr;
393
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
390
394
  ary = rb_ary_new2(2);
391
395
  rb_ary_push(ary, ssl_obj);
392
396
  rb_ary_push(ary, rb_str_new((const char *)buf, len));
@@ -399,7 +403,7 @@ ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
399
403
  if (!rb_obj_is_instance_of(ret_obj, cSSLSession))
400
404
  return NULL;
401
405
 
402
- SafeGetSSLSession(ret_obj, sess);
406
+ GetSSLSession(ret_obj, sess);
403
407
  *copy = 1;
404
408
 
405
409
  return sess;
@@ -424,14 +428,11 @@ static int
424
428
  ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
425
429
  {
426
430
  VALUE ary, ssl_obj, sess_obj;
427
- void *ptr;
428
431
  int state = 0;
429
432
 
430
433
  OSSL_Debug("SSL SESSION new callback entered");
431
434
 
432
- if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
433
- return 1;
434
- ssl_obj = (VALUE)ptr;
435
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
435
436
  sess_obj = rb_obj_alloc(cSSLSession);
436
437
  SSL_SESSION_up_ref(sess);
437
438
  DATA_PTR(sess_obj) = sess;
@@ -473,7 +474,6 @@ static void
473
474
  ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
474
475
  {
475
476
  VALUE ary, sslctx_obj, sess_obj;
476
- void *ptr;
477
477
  int state = 0;
478
478
 
479
479
  /*
@@ -485,9 +485,7 @@ ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
485
485
 
486
486
  OSSL_Debug("SSL SESSION remove callback entered");
487
487
 
488
- if ((ptr = SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx)) == NULL)
489
- return;
490
- sslctx_obj = (VALUE)ptr;
488
+ sslctx_obj = (VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx);
491
489
  sess_obj = rb_obj_alloc(cSSLSession);
492
490
  SSL_SESSION_up_ref(sess);
493
491
  DATA_PTR(sess_obj) = sess;
@@ -523,7 +521,6 @@ ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
523
521
 
524
522
  static VALUE ossl_sslctx_setup(VALUE self);
525
523
 
526
- #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
527
524
  static VALUE
528
525
  ossl_call_servername_cb(VALUE ary)
529
526
  {
@@ -558,16 +555,13 @@ static int
558
555
  ssl_servername_cb(SSL *ssl, int *ad, void *arg)
559
556
  {
560
557
  VALUE ary, ssl_obj;
561
- void *ptr;
562
558
  int state = 0;
563
559
  const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
564
560
 
565
561
  if (!servername)
566
562
  return SSL_TLSEXT_ERR_OK;
567
563
 
568
- if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
569
- return SSL_TLSEXT_ERR_ALERT_FATAL;
570
- ssl_obj = (VALUE)ptr;
564
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
571
565
  ary = rb_ary_new2(2);
572
566
  rb_ary_push(ary, ssl_obj);
573
567
  rb_ary_push(ary, rb_str_new2(servername));
@@ -580,18 +574,13 @@ ssl_servername_cb(SSL *ssl, int *ad, void *arg)
580
574
 
581
575
  return SSL_TLSEXT_ERR_OK;
582
576
  }
583
- #endif
584
577
 
585
578
  static void
586
579
  ssl_renegotiation_cb(const SSL *ssl)
587
580
  {
588
581
  VALUE ssl_obj, sslctx_obj, cb;
589
- void *ptr;
590
-
591
- if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
592
- ossl_raise(eSSLError, "SSL object could not be retrieved");
593
- ssl_obj = (VALUE)ptr;
594
582
 
583
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
595
584
  sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
596
585
  cb = rb_attr_get(sslctx_obj, id_i_renegotiation_cb);
597
586
  if (NIL_P(cb)) return;
@@ -599,7 +588,7 @@ ssl_renegotiation_cb(const SSL *ssl)
599
588
  (void) rb_funcall(cb, rb_intern("call"), 1, ssl_obj);
600
589
  }
601
590
 
602
- #if defined(HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB) || \
591
+ #if !defined(OPENSSL_NO_NEXTPROTONEG) || \
603
592
  defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
604
593
  static VALUE
605
594
  ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
@@ -684,7 +673,7 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
684
673
  }
685
674
  #endif
686
675
 
687
- #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
676
+ #ifndef OPENSSL_NO_NEXTPROTONEG
688
677
  static int
689
678
  ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
690
679
  void *arg)
@@ -744,7 +733,11 @@ ossl_sslctx_get_options(VALUE self)
744
733
  {
745
734
  SSL_CTX *ctx;
746
735
  GetSSLCTX(self, ctx);
747
- return LONG2NUM(SSL_CTX_get_options(ctx));
736
+ /*
737
+ * Do explicit cast because SSL_CTX_get_options() returned (signed) long in
738
+ * OpenSSL before 1.1.0.
739
+ */
740
+ return ULONG2NUM((unsigned long)SSL_CTX_get_options(ctx));
748
741
  }
749
742
 
750
743
  /*
@@ -763,7 +756,7 @@ ossl_sslctx_set_options(VALUE self, VALUE options)
763
756
  if (NIL_P(options)) {
764
757
  SSL_CTX_set_options(ctx, SSL_OP_ALL);
765
758
  } else {
766
- SSL_CTX_set_options(ctx, NUM2LONG(options));
759
+ SSL_CTX_set_options(ctx, NUM2ULONG(options));
767
760
  }
768
761
 
769
762
  return self;
@@ -827,7 +820,7 @@ ossl_sslctx_setup(VALUE self)
827
820
  * X509_STORE_free() doesn't care it.
828
821
  * So we won't increment it but mark it by ex_data.
829
822
  */
830
- SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void *)1);
823
+ SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
831
824
  #else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
832
825
  X509_STORE_up_ref(store);
833
826
  #endif
@@ -898,7 +891,7 @@ ossl_sslctx_setup(VALUE self)
898
891
  val = rb_attr_get(self, id_i_verify_depth);
899
892
  if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
900
893
 
901
- #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
894
+ #ifndef OPENSSL_NO_NEXTPROTONEG
902
895
  val = rb_attr_get(self, id_i_npn_protocols);
903
896
  if (!NIL_P(val)) {
904
897
  VALUE encoded = ssl_encode_npn_protocols(val);
@@ -953,13 +946,11 @@ ossl_sslctx_setup(VALUE self)
953
946
  OSSL_Debug("SSL SESSION remove callback added");
954
947
  }
955
948
 
956
- #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
957
949
  val = rb_attr_get(self, id_i_servername_cb);
958
950
  if (!NIL_P(val)) {
959
951
  SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
960
952
  OSSL_Debug("SSL TLSEXT servername callback added");
961
953
  }
962
- #endif
963
954
 
964
955
  return Qtrue;
965
956
  }
@@ -1044,6 +1035,10 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1044
1035
  }
1045
1036
 
1046
1037
  GetSSLCTX(self, ctx);
1038
+ if(!ctx){
1039
+ ossl_raise(eSSLError, "SSL_CTX is not initialized.");
1040
+ return Qnil;
1041
+ }
1047
1042
  if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) {
1048
1043
  ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
1049
1044
  }
@@ -1202,7 +1197,7 @@ ossl_sslctx_set_security_level(VALUE self, VALUE value)
1202
1197
  * call-seq:
1203
1198
  * ctx.session_add(session) -> true | false
1204
1199
  *
1205
- * Adds +session+ to the session cache.
1200
+ * Adds _session_ to the session cache.
1206
1201
  */
1207
1202
  static VALUE
1208
1203
  ossl_sslctx_session_add(VALUE self, VALUE arg)
@@ -1211,7 +1206,7 @@ ossl_sslctx_session_add(VALUE self, VALUE arg)
1211
1206
  SSL_SESSION *sess;
1212
1207
 
1213
1208
  GetSSLCTX(self, ctx);
1214
- SafeGetSSLSession(arg, sess);
1209
+ GetSSLSession(arg, sess);
1215
1210
 
1216
1211
  return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse;
1217
1212
  }
@@ -1220,7 +1215,7 @@ ossl_sslctx_session_add(VALUE self, VALUE arg)
1220
1215
  * call-seq:
1221
1216
  * ctx.session_remove(session) -> true | false
1222
1217
  *
1223
- * Removes +session+ from the session cache.
1218
+ * Removes _session_ from the session cache.
1224
1219
  */
1225
1220
  static VALUE
1226
1221
  ossl_sslctx_session_remove(VALUE self, VALUE arg)
@@ -1229,7 +1224,7 @@ ossl_sslctx_session_remove(VALUE self, VALUE arg)
1229
1224
  SSL_SESSION *sess;
1230
1225
 
1231
1226
  GetSSLCTX(self, ctx);
1232
- SafeGetSSLSession(arg, sess);
1227
+ GetSSLSession(arg, sess);
1233
1228
 
1234
1229
  return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse;
1235
1230
  }
@@ -1356,9 +1351,9 @@ ossl_sslctx_get_session_cache_stats(VALUE self)
1356
1351
 
1357
1352
  /*
1358
1353
  * call-seq:
1359
- * ctx.flush_sessions(time | nil) -> self
1354
+ * ctx.flush_sessions(time) -> self
1360
1355
  *
1361
- * Removes sessions in the internal cache that have expired at +time+.
1356
+ * Removes sessions in the internal cache that have expired at _time_.
1362
1357
  */
1363
1358
  static VALUE
1364
1359
  ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
@@ -1420,10 +1415,10 @@ ossl_ssl_s_alloc(VALUE klass)
1420
1415
  * SSLSocket.new(io) => aSSLSocket
1421
1416
  * SSLSocket.new(io, ctx) => aSSLSocket
1422
1417
  *
1423
- * Creates a new SSL socket from +io+ which must be a real IO object (not an
1418
+ * Creates a new SSL socket from _io_ which must be a real IO object (not an
1424
1419
  * IO-like object that responds to read/write).
1425
1420
  *
1426
- * If +ctx+ is provided the SSL Sockets initial params will be taken from
1421
+ * If _ctx_ is provided the SSL Sockets initial params will be taken from
1427
1422
  * the context.
1428
1423
  *
1429
1424
  * The OpenSSL::Buffering module provides additional IO methods.
@@ -1483,7 +1478,7 @@ ossl_ssl_setup(VALUE self)
1483
1478
  GetOpenFile(io, fptr);
1484
1479
  rb_io_check_readable(fptr);
1485
1480
  rb_io_check_writable(fptr);
1486
- if (!SSL_set_fd(ssl, TO_SOCKET(FPTR_TO_FD(fptr))))
1481
+ if (!SSL_set_fd(ssl, TO_SOCKET(fptr->fd)))
1487
1482
  ossl_raise(eSSLError, "SSL_set_fd");
1488
1483
 
1489
1484
  return Qtrue;
@@ -1526,6 +1521,9 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1526
1521
  int ret, ret2;
1527
1522
  VALUE cb_state;
1528
1523
  int nonblock = opts != Qfalse;
1524
+ #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1525
+ unsigned long err;
1526
+ #endif
1529
1527
 
1530
1528
  rb_ivar_set(self, ID_callback_state, Qnil);
1531
1529
 
@@ -1549,16 +1547,33 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1549
1547
  case SSL_ERROR_WANT_WRITE:
1550
1548
  if (no_exception_p(opts)) { return sym_wait_writable; }
1551
1549
  write_would_block(nonblock);
1552
- rb_io_wait_writable(FPTR_TO_FD(fptr));
1550
+ rb_io_wait_writable(fptr->fd);
1553
1551
  continue;
1554
1552
  case SSL_ERROR_WANT_READ:
1555
1553
  if (no_exception_p(opts)) { return sym_wait_readable; }
1556
1554
  read_would_block(nonblock);
1557
- rb_io_wait_readable(FPTR_TO_FD(fptr));
1555
+ rb_io_wait_readable(fptr->fd);
1558
1556
  continue;
1559
1557
  case SSL_ERROR_SYSCALL:
1560
1558
  if (errno) rb_sys_fail(funcname);
1561
1559
  ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1560
+ #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1561
+ case SSL_ERROR_SSL:
1562
+ err = ERR_peek_last_error();
1563
+ if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
1564
+ ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1565
+ const char *err_msg = ERR_reason_error_string(err),
1566
+ *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1567
+ if (!err_msg)
1568
+ err_msg = "(null)";
1569
+ if (!verify_msg)
1570
+ verify_msg = "(null)";
1571
+ ossl_clear_error(); /* let ossl_raise() not append message */
1572
+ ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s: %s (%s)",
1573
+ funcname, ret2, errno, SSL_state_string_long(ssl),
1574
+ err_msg, verify_msg);
1575
+ }
1576
+ #endif
1562
1577
  default:
1563
1578
  ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1564
1579
  }
@@ -1599,10 +1614,10 @@ ossl_ssl_connect(VALUE self)
1599
1614
  * retry
1600
1615
  * end
1601
1616
  *
1602
- * By specifying `exception: false`, the options hash allows you to indicate
1617
+ * By specifying a keyword argument _exception_ to +false+, you can indicate
1603
1618
  * that connect_nonblock should not raise an IO::WaitReadable or
1604
- * IO::WaitWritable exception, but return the symbol :wait_readable or
1605
- * :wait_writable instead.
1619
+ * IO::WaitWritable exception, but return the symbol +:wait_readable+ or
1620
+ * +:wait_writable+ instead.
1606
1621
  */
1607
1622
  static VALUE
1608
1623
  ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
@@ -1647,10 +1662,10 @@ ossl_ssl_accept(VALUE self)
1647
1662
  * retry
1648
1663
  * end
1649
1664
  *
1650
- * By specifying `exception: false`, the options hash allows you to indicate
1665
+ * By specifying a keyword argument _exception_ to +false+, you can indicate
1651
1666
  * that accept_nonblock should not raise an IO::WaitReadable or
1652
- * IO::WaitWritable exception, but return the symbol :wait_readable or
1653
- * :wait_writable instead.
1667
+ * IO::WaitWritable exception, but return the symbol +:wait_readable+ or
1668
+ * +:wait_writable+ instead.
1654
1669
  */
1655
1670
  static VALUE
1656
1671
  ossl_ssl_accept_nonblock(int argc, VALUE *argv, VALUE self)
@@ -1679,26 +1694,20 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1679
1694
  }
1680
1695
 
1681
1696
  ilen = NUM2INT(len);
1682
- if (NIL_P(str))
1683
- str = rb_str_new(0, ilen);
1684
- else {
1685
- StringValue(str);
1686
- if (RSTRING_LEN(str) >= ilen)
1687
- rb_str_modify(str);
1688
- else
1689
- rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
1697
+ if(NIL_P(str)) str = rb_str_new(0, ilen);
1698
+ else{
1699
+ StringValue(str);
1700
+ rb_str_modify(str);
1701
+ rb_str_resize(str, ilen);
1690
1702
  }
1691
- OBJ_TAINT(str);
1692
- rb_str_set_len(str, 0);
1693
- if (ilen == 0)
1694
- return str;
1703
+ if(ilen == 0) return str;
1695
1704
 
1696
1705
  GetSSL(self, ssl);
1697
1706
  io = rb_attr_get(self, id_i_io);
1698
1707
  GetOpenFile(io, fptr);
1699
1708
  if (ssl_started(ssl)) {
1700
1709
  for (;;){
1701
- nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1710
+ nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
1702
1711
  switch(ssl_get_error(ssl, nread)){
1703
1712
  case SSL_ERROR_NONE:
1704
1713
  goto end;
@@ -1708,12 +1717,12 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1708
1717
  case SSL_ERROR_WANT_WRITE:
1709
1718
  if (no_exception_p(opts)) { return sym_wait_writable; }
1710
1719
  write_would_block(nonblock);
1711
- rb_io_wait_writable(FPTR_TO_FD(fptr));
1720
+ rb_io_wait_writable(fptr->fd);
1712
1721
  continue;
1713
1722
  case SSL_ERROR_WANT_READ:
1714
1723
  if (no_exception_p(opts)) { return sym_wait_readable; }
1715
1724
  read_would_block(nonblock);
1716
- rb_io_wait_readable(FPTR_TO_FD(fptr));
1725
+ rb_io_wait_readable(fptr->fd);
1717
1726
  continue;
1718
1727
  case SSL_ERROR_SYSCALL:
1719
1728
  if (!ERR_peek_error()) {
@@ -1748,6 +1757,8 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1748
1757
 
1749
1758
  end:
1750
1759
  rb_str_set_len(str, nread);
1760
+ OBJ_TAINT(str);
1761
+
1751
1762
  return str;
1752
1763
  }
1753
1764
 
@@ -1756,7 +1767,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1756
1767
  * ssl.sysread(length) => string
1757
1768
  * ssl.sysread(length, buffer) => buffer
1758
1769
  *
1759
- * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+
1770
+ * Reads _length_ bytes from the SSL connection. If a pre-allocated _buffer_
1760
1771
  * is provided the data will be written into it.
1761
1772
  */
1762
1773
  static VALUE
@@ -1775,7 +1786,7 @@ ossl_ssl_read(int argc, VALUE *argv, VALUE self)
1775
1786
  * block. If "exception: false" is passed, this method returns a symbol of
1776
1787
  * :wait_readable, :wait_writable, or nil, rather than raising an exception.
1777
1788
  *
1778
- * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+
1789
+ * Reads _length_ bytes from the SSL connection. If a pre-allocated _buffer_
1779
1790
  * is provided the data will be written into it.
1780
1791
  */
1781
1792
  static VALUE
@@ -1812,12 +1823,12 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1812
1823
  case SSL_ERROR_WANT_WRITE:
1813
1824
  if (no_exception_p(opts)) { return sym_wait_writable; }
1814
1825
  write_would_block(nonblock);
1815
- rb_io_wait_writable(FPTR_TO_FD(fptr));
1826
+ rb_io_wait_writable(fptr->fd);
1816
1827
  continue;
1817
1828
  case SSL_ERROR_WANT_READ:
1818
1829
  if (no_exception_p(opts)) { return sym_wait_readable; }
1819
1830
  read_would_block(nonblock);
1820
- rb_io_wait_readable(FPTR_TO_FD(fptr));
1831
+ rb_io_wait_readable(fptr->fd);
1821
1832
  continue;
1822
1833
  case SSL_ERROR_SYSCALL:
1823
1834
  if (errno) rb_sys_fail(0);
@@ -1845,7 +1856,7 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1845
1856
  * call-seq:
1846
1857
  * ssl.syswrite(string) => Integer
1847
1858
  *
1848
- * Writes +string+ to the SSL connection.
1859
+ * Writes _string_ to the SSL connection.
1849
1860
  */
1850
1861
  static VALUE
1851
1862
  ossl_ssl_write(VALUE self, VALUE str)
@@ -1857,7 +1868,7 @@ ossl_ssl_write(VALUE self, VALUE str)
1857
1868
  * call-seq:
1858
1869
  * ssl.syswrite_nonblock(string) => Integer
1859
1870
  *
1860
- * Writes +string+ to the SSL connection in a non-blocking manner. Raises an
1871
+ * Writes _string_ to the SSL connection in a non-blocking manner. Raises an
1861
1872
  * SSLError if writing would block.
1862
1873
  */
1863
1874
  static VALUE
@@ -2001,22 +2012,21 @@ ossl_ssl_get_version(VALUE self)
2001
2012
  }
2002
2013
 
2003
2014
  /*
2004
- * call-seq:
2005
- * ssl.cipher => [name, version, bits, alg_bits]
2006
- *
2007
- * The cipher being used for the current connection
2008
- */
2015
+ * call-seq:
2016
+ * ssl.cipher -> nil or [name, version, bits, alg_bits]
2017
+ *
2018
+ * Returns the cipher suite actually used in the current session, or nil if
2019
+ * no session has been established.
2020
+ */
2009
2021
  static VALUE
2010
2022
  ossl_ssl_get_cipher(VALUE self)
2011
2023
  {
2012
2024
  SSL *ssl;
2013
- SSL_CIPHER *cipher;
2025
+ const SSL_CIPHER *cipher;
2014
2026
 
2015
2027
  GetSSL(self, ssl);
2016
-
2017
- cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl);
2018
-
2019
- return ossl_ssl_cipher_to_ary(cipher);
2028
+ cipher = SSL_get_current_cipher(ssl);
2029
+ return cipher ? ossl_ssl_cipher_to_ary(cipher) : Qnil;
2020
2030
  }
2021
2031
 
2022
2032
  /*
@@ -2062,7 +2072,7 @@ ossl_ssl_pending(VALUE self)
2062
2072
  * call-seq:
2063
2073
  * ssl.session_reused? -> true | false
2064
2074
  *
2065
- * Returns true if a reused session was negotiated during the handshake.
2075
+ * Returns +true+ if a reused session was negotiated during the handshake.
2066
2076
  */
2067
2077
  static VALUE
2068
2078
  ossl_ssl_session_reused(VALUE self)
@@ -2087,7 +2097,7 @@ ossl_ssl_set_session(VALUE self, VALUE arg1)
2087
2097
  SSL_SESSION *sess;
2088
2098
 
2089
2099
  GetSSL(self, ssl);
2090
- SafeGetSSLSession(arg1, sess);
2100
+ GetSSLSession(arg1, sess);
2091
2101
 
2092
2102
  if (SSL_set_session(ssl, sess) != 1)
2093
2103
  ossl_raise(eSSLError, "SSL_set_session");
@@ -2095,7 +2105,6 @@ ossl_ssl_set_session(VALUE self, VALUE arg1)
2095
2105
  return arg1;
2096
2106
  }
2097
2107
 
2098
- #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
2099
2108
  /*
2100
2109
  * call-seq:
2101
2110
  * ssl.hostname = hostname -> hostname
@@ -2122,7 +2131,6 @@ ossl_ssl_set_hostname(VALUE self, VALUE arg)
2122
2131
 
2123
2132
  return arg;
2124
2133
  }
2125
- #endif
2126
2134
 
2127
2135
  /*
2128
2136
  * call-seq:
@@ -2166,7 +2174,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
2166
2174
  return ossl_x509name_sk2ary(ca);
2167
2175
  }
2168
2176
 
2169
- # ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
2177
+ # ifndef OPENSSL_NO_NEXTPROTONEG
2170
2178
  /*
2171
2179
  * call-seq:
2172
2180
  * ssl.npn_protocol => String | nil
@@ -2242,9 +2250,6 @@ ossl_ssl_tmp_key(VALUE self)
2242
2250
  void
2243
2251
  Init_ossl_ssl(void)
2244
2252
  {
2245
- int i;
2246
- VALUE ary;
2247
-
2248
2253
  #if 0
2249
2254
  mOSSL = rb_define_module("OpenSSL");
2250
2255
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
@@ -2254,9 +2259,20 @@ Init_ossl_ssl(void)
2254
2259
 
2255
2260
  ID_callback_state = rb_intern("callback_state");
2256
2261
 
2257
- ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0);
2258
- ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0);
2259
- ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_ptr_idx",0,0,0);
2262
+ ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0);
2263
+ if (ossl_ssl_ex_vcb_idx < 0)
2264
+ ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
2265
+ ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_ptr_idx", 0, 0, 0);
2266
+ if (ossl_ssl_ex_ptr_idx < 0)
2267
+ ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
2268
+ ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2269
+ if (ossl_sslctx_ex_ptr_idx < 0)
2270
+ ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2271
+ #if !defined(HAVE_X509_STORE_UP_REF)
2272
+ ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_store_p", 0, 0, 0);
2273
+ if (ossl_sslctx_ex_store_p < 0)
2274
+ ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2275
+ #endif
2260
2276
 
2261
2277
  /* Document-module: OpenSSL::SSL
2262
2278
  *
@@ -2272,7 +2288,7 @@ Init_ossl_ssl(void)
2272
2288
  * This module contains configuration information about the SSL extension,
2273
2289
  * for example if socket support is enabled, or the host name TLS extension
2274
2290
  * is enabled. Constants in this module will always be defined, but contain
2275
- * `true` or `false` values depending on the configuration of your OpenSSL
2291
+ * +true+ or +false+ values depending on the configuration of your OpenSSL
2276
2292
  * installation.
2277
2293
  */
2278
2294
  mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig");
@@ -2356,12 +2372,12 @@ Init_ossl_ssl(void)
2356
2372
  * A callback for additional certificate verification. The callback is
2357
2373
  * invoked for each certificate in the chain.
2358
2374
  *
2359
- * The callback is invoked with two values. +preverify_ok+ indicates
2360
- * indicates if the verification was passed (true) or not (false).
2361
- * +store_context+ is an OpenSSL::X509::StoreContext containing the
2375
+ * The callback is invoked with two values. _preverify_ok_ indicates
2376
+ * indicates if the verification was passed (+true+) or not (+false+).
2377
+ * _store_context_ is an OpenSSL::X509::StoreContext containing the
2362
2378
  * context used for certificate verification.
2363
2379
  *
2364
- * If the callback returns false, the chain verification is immediately
2380
+ * If the callback returns +false+, the chain verification is immediately
2365
2381
  * stopped and a bad_certificate alert is then sent.
2366
2382
  */
2367
2383
  rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
@@ -2428,7 +2444,7 @@ Init_ossl_ssl(void)
2428
2444
  /*
2429
2445
  * A callback invoked when a new session was negotiated.
2430
2446
  *
2431
- * The callback is invoked with an SSLSocket. If false is returned the
2447
+ * The callback is invoked with an SSLSocket. If +false+ is returned the
2432
2448
  * session will be removed from the internal cache.
2433
2449
  */
2434
2450
  rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse);
@@ -2437,24 +2453,10 @@ Init_ossl_ssl(void)
2437
2453
  * A callback invoked when a session is removed from the internal cache.
2438
2454
  *
2439
2455
  * The callback is invoked with an SSLContext and a Session.
2440
- *
2441
- * IMPORTANT NOTE: It is currently not possible to use this safely in a
2442
- * multi-threaded application. The callback is called inside a global lock
2443
- * and it can randomly cause deadlock on Ruby thread switching.
2444
2456
  */
2445
2457
  rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
2446
2458
 
2447
- #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
2448
2459
  rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
2449
- #else
2450
- rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qfalse);
2451
- #endif
2452
-
2453
- #ifdef TLS_DH_anon_WITH_AES_256_GCM_SHA384
2454
- rb_define_const(mSSLExtConfig, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", Qtrue);
2455
- #else
2456
- rb_define_const(mSSLExtConfig, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", Qfalse);
2457
- #endif
2458
2460
 
2459
2461
  /*
2460
2462
  * A callback invoked whenever a new handshake is initiated. May be used
@@ -2478,7 +2480,7 @@ Init_ossl_ssl(void)
2478
2480
  * end
2479
2481
  */
2480
2482
  rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse);
2481
- #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
2483
+ #ifndef OPENSSL_NO_NEXTPROTONEG
2482
2484
  /*
2483
2485
  * An Enumerable of Strings. Each String represents a protocol to be
2484
2486
  * advertised as the list of supported protocols for Next Protocol
@@ -2544,7 +2546,8 @@ Init_ossl_ssl(void)
2544
2546
 
2545
2547
  rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2546
2548
  rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
2547
- rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1);
2549
+ rb_define_private_method(cSSLContext, "set_minmax_proto_version",
2550
+ ossl_sslctx_set_minmax_proto_version, 2);
2548
2551
  rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2549
2552
  rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
2550
2553
  rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
@@ -2612,14 +2615,6 @@ Init_ossl_ssl(void)
2612
2615
  rb_define_method(cSSLContext, "options", ossl_sslctx_get_options, 0);
2613
2616
  rb_define_method(cSSLContext, "options=", ossl_sslctx_set_options, 1);
2614
2617
 
2615
- ary = rb_ary_new2(numberof(ossl_ssl_method_tab));
2616
- for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
2617
- rb_ary_push(ary, ID2SYM(rb_intern(ossl_ssl_method_tab[i].name)));
2618
- }
2619
- rb_obj_freeze(ary);
2620
- /* The list of available SSL/TLS methods */
2621
- rb_define_const(cSSLContext, "METHODS", ary);
2622
-
2623
2618
  /*
2624
2619
  * Document-class: OpenSSL::SSL::SSLSocket
2625
2620
  */
@@ -2653,67 +2648,120 @@ Init_ossl_ssl(void)
2653
2648
  rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1);
2654
2649
  rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
2655
2650
  rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
2656
- #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
2657
2651
  /* #hostname is defined in lib/openssl/ssl.rb */
2658
2652
  rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
2659
- #endif
2660
2653
  # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2661
2654
  rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
2662
2655
  # endif
2663
2656
  # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2664
2657
  rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
2665
2658
  # endif
2666
- # ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
2659
+ # ifndef OPENSSL_NO_NEXTPROTONEG
2667
2660
  rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2668
2661
  # endif
2669
2662
  #endif
2670
2663
 
2671
- #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, LONG2NUM(SSL_##x))
2664
+ rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
2665
+ rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
2666
+ rb_define_const(mSSL, "VERIFY_FAIL_IF_NO_PEER_CERT", INT2NUM(SSL_VERIFY_FAIL_IF_NO_PEER_CERT));
2667
+ rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
2672
2668
 
2673
- ossl_ssl_def_const(VERIFY_NONE);
2674
- ossl_ssl_def_const(VERIFY_PEER);
2675
- ossl_ssl_def_const(VERIFY_FAIL_IF_NO_PEER_CERT);
2676
- ossl_ssl_def_const(VERIFY_CLIENT_ONCE);
2677
- /* Introduce constants included in OP_ALL. These constants are mostly for
2678
- * unset some bits in OP_ALL such as;
2679
- * ctx.options = OP_ALL & ~OP_DONT_INSERT_EMPTY_FRAGMENTS
2680
- */
2681
- ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG);
2682
- ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG);
2683
- ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
2684
- ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG);
2685
- ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER);
2686
- ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING);
2687
- ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG);
2688
- ossl_ssl_def_const(OP_TLS_D5_BUG);
2689
- ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG);
2690
- ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS);
2691
- ossl_ssl_def_const(OP_ALL);
2692
- ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
2693
- ossl_ssl_def_const(OP_SINGLE_ECDH_USE);
2694
- ossl_ssl_def_const(OP_SINGLE_DH_USE);
2695
- ossl_ssl_def_const(OP_EPHEMERAL_RSA);
2696
- ossl_ssl_def_const(OP_CIPHER_SERVER_PREFERENCE);
2697
- ossl_ssl_def_const(OP_TLS_ROLLBACK_BUG);
2698
- ossl_ssl_def_const(OP_NO_SSLv2);
2699
- ossl_ssl_def_const(OP_NO_SSLv3);
2700
- ossl_ssl_def_const(OP_NO_TLSv1);
2701
- #if defined(SSL_OP_NO_TLSv1_1)
2702
- ossl_ssl_def_const(OP_NO_TLSv1_1);
2669
+ rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL));
2670
+ rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
2671
+ #ifdef SSL_OP_TLSEXT_PADDING /* OpenSSL 1.0.1h and OpenSSL 1.0.2 */
2672
+ rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
2703
2673
  #endif
2704
- #if defined(SSL_OP_NO_TLSv1_2)
2705
- ossl_ssl_def_const(OP_NO_TLSv1_2);
2674
+ #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG /* OpenSSL 1.0.1f and OpenSSL 1.0.2 */
2675
+ rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG));
2706
2676
  #endif
2707
- #if defined(SSL_OP_NO_TICKET)
2708
- ossl_ssl_def_const(OP_NO_TICKET);
2677
+ #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
2678
+ rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
2709
2679
  #endif
2710
- #if defined(SSL_OP_NO_COMPRESSION)
2711
- ossl_ssl_def_const(OP_NO_COMPRESSION);
2680
+ rb_define_const(mSSL, "OP_DONT_INSERT_EMPTY_FRAGMENTS", ULONG2NUM(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
2681
+ rb_define_const(mSSL, "OP_NO_TICKET", ULONG2NUM(SSL_OP_NO_TICKET));
2682
+ rb_define_const(mSSL, "OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION));
2683
+ rb_define_const(mSSL, "OP_NO_COMPRESSION", ULONG2NUM(SSL_OP_NO_COMPRESSION));
2684
+ rb_define_const(mSSL, "OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
2685
+ #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
2686
+ rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
2712
2687
  #endif
2713
- ossl_ssl_def_const(OP_PKCS1_CHECK_1);
2714
- ossl_ssl_def_const(OP_PKCS1_CHECK_2);
2715
- ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG);
2716
- ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
2688
+ rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
2689
+ rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
2690
+ #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
2691
+ rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
2692
+ #endif
2693
+ rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
2694
+
2695
+ rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
2696
+ rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
2697
+ rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
2698
+ rb_define_const(mSSL, "OP_NO_TLSv1_2", ULONG2NUM(SSL_OP_NO_TLSv1_2));
2699
+ #ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
2700
+ rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
2701
+ #endif
2702
+
2703
+ /* SSL_OP_* flags for DTLS */
2704
+ #if 0
2705
+ rb_define_const(mSSL, "OP_NO_QUERY_MTU", ULONG2NUM(SSL_OP_NO_QUERY_MTU));
2706
+ rb_define_const(mSSL, "OP_COOKIE_EXCHANGE", ULONG2NUM(SSL_OP_COOKIE_EXCHANGE));
2707
+ rb_define_const(mSSL, "OP_CISCO_ANYCONNECT", ULONG2NUM(SSL_OP_CISCO_ANYCONNECT));
2708
+ #endif
2709
+
2710
+ /* Deprecated in OpenSSL 1.1.0. */
2711
+ rb_define_const(mSSL, "OP_MICROSOFT_SESS_ID_BUG", ULONG2NUM(SSL_OP_MICROSOFT_SESS_ID_BUG));
2712
+ /* Deprecated in OpenSSL 1.1.0. */
2713
+ rb_define_const(mSSL, "OP_NETSCAPE_CHALLENGE_BUG", ULONG2NUM(SSL_OP_NETSCAPE_CHALLENGE_BUG));
2714
+ /* Deprecated in OpenSSL 0.9.8q and 1.0.0c. */
2715
+ rb_define_const(mSSL, "OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", ULONG2NUM(SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG));
2716
+ /* Deprecated in OpenSSL 1.0.1h and 1.0.2. */
2717
+ rb_define_const(mSSL, "OP_SSLREF2_REUSE_CERT_TYPE_BUG", ULONG2NUM(SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG));
2718
+ /* Deprecated in OpenSSL 1.1.0. */
2719
+ rb_define_const(mSSL, "OP_MICROSOFT_BIG_SSLV3_BUFFER", ULONG2NUM(SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER));
2720
+ /* Deprecated in OpenSSL 0.9.7h and 0.9.8b. */
2721
+ rb_define_const(mSSL, "OP_MSIE_SSLV2_RSA_PADDING", ULONG2NUM(SSL_OP_MSIE_SSLV2_RSA_PADDING));
2722
+ /* Deprecated in OpenSSL 1.1.0. */
2723
+ rb_define_const(mSSL, "OP_SSLEAY_080_CLIENT_DH_BUG", ULONG2NUM(SSL_OP_SSLEAY_080_CLIENT_DH_BUG));
2724
+ /* Deprecated in OpenSSL 1.1.0. */
2725
+ rb_define_const(mSSL, "OP_TLS_D5_BUG", ULONG2NUM(SSL_OP_TLS_D5_BUG));
2726
+ /* Deprecated in OpenSSL 1.1.0. */
2727
+ rb_define_const(mSSL, "OP_TLS_BLOCK_PADDING_BUG", ULONG2NUM(SSL_OP_TLS_BLOCK_PADDING_BUG));
2728
+ /* Deprecated in OpenSSL 1.1.0. */
2729
+ rb_define_const(mSSL, "OP_SINGLE_ECDH_USE", ULONG2NUM(SSL_OP_SINGLE_ECDH_USE));
2730
+ /* Deprecated in OpenSSL 1.1.0. */
2731
+ rb_define_const(mSSL, "OP_SINGLE_DH_USE", ULONG2NUM(SSL_OP_SINGLE_DH_USE));
2732
+ /* Deprecated in OpenSSL 1.0.1k and 1.0.2. */
2733
+ rb_define_const(mSSL, "OP_EPHEMERAL_RSA", ULONG2NUM(SSL_OP_EPHEMERAL_RSA));
2734
+ /* Deprecated in OpenSSL 1.1.0. */
2735
+ rb_define_const(mSSL, "OP_NO_SSLv2", ULONG2NUM(SSL_OP_NO_SSLv2));
2736
+ /* Deprecated in OpenSSL 1.0.1. */
2737
+ rb_define_const(mSSL, "OP_PKCS1_CHECK_1", ULONG2NUM(SSL_OP_PKCS1_CHECK_1));
2738
+ /* Deprecated in OpenSSL 1.0.1. */
2739
+ rb_define_const(mSSL, "OP_PKCS1_CHECK_2", ULONG2NUM(SSL_OP_PKCS1_CHECK_2));
2740
+ /* Deprecated in OpenSSL 1.1.0. */
2741
+ rb_define_const(mSSL, "OP_NETSCAPE_CA_DN_BUG", ULONG2NUM(SSL_OP_NETSCAPE_CA_DN_BUG));
2742
+ /* Deprecated in OpenSSL 1.1.0. */
2743
+ rb_define_const(mSSL, "OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", ULONG2NUM(SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG));
2744
+
2745
+
2746
+ /*
2747
+ * SSL/TLS version constants. Used by SSLContext#min_version= and
2748
+ * #max_version=
2749
+ */
2750
+ /* SSL 2.0 */
2751
+ rb_define_const(mSSL, "SSL2_VERSION", INT2NUM(SSL2_VERSION));
2752
+ /* SSL 3.0 */
2753
+ rb_define_const(mSSL, "SSL3_VERSION", INT2NUM(SSL3_VERSION));
2754
+ /* TLS 1.0 */
2755
+ rb_define_const(mSSL, "TLS1_VERSION", INT2NUM(TLS1_VERSION));
2756
+ /* TLS 1.1 */
2757
+ rb_define_const(mSSL, "TLS1_1_VERSION", INT2NUM(TLS1_1_VERSION));
2758
+ /* TLS 1.2 */
2759
+ rb_define_const(mSSL, "TLS1_2_VERSION", INT2NUM(TLS1_2_VERSION));
2760
+ #ifdef TLS1_3_VERSION /* OpenSSL 1.1.1 */
2761
+ /* TLS 1.3 */
2762
+ rb_define_const(mSSL, "TLS1_3_VERSION", INT2NUM(TLS1_3_VERSION));
2763
+ #endif
2764
+
2717
2765
 
2718
2766
  sym_exception = ID2SYM(rb_intern("exception"));
2719
2767
  sym_wait_readable = ID2SYM(rb_intern("wait_readable"));