openssl 2.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +426 -0
  4. data/README.md +38 -21
  5. data/ext/openssl/extconf.rb +132 -72
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +62 -46
  8. data/ext/openssl/ossl.c +177 -252
  9. data/ext/openssl/ossl.h +39 -17
  10. data/ext/openssl/ossl_asn1.c +53 -14
  11. data/ext/openssl/ossl_bn.c +288 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +42 -32
  14. data/ext/openssl/ossl_config.c +412 -41
  15. data/ext/openssl/ossl_config.h +4 -7
  16. data/ext/openssl/ossl_digest.c +32 -63
  17. data/ext/openssl/ossl_engine.c +19 -28
  18. data/ext/openssl/ossl_hmac.c +61 -146
  19. data/ext/openssl/ossl_kdf.c +15 -23
  20. data/ext/openssl/ossl_ns_spki.c +2 -2
  21. data/ext/openssl/ossl_ocsp.c +17 -70
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +23 -4
  24. data/ext/openssl/ossl_pkcs7.c +49 -81
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1508 -195
  27. data/ext/openssl/ossl_pkey.h +41 -78
  28. data/ext/openssl/ossl_pkey_dh.c +153 -348
  29. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  30. data/ext/openssl/ossl_pkey_ec.c +257 -343
  31. data/ext/openssl/ossl_pkey_rsa.c +166 -490
  32. data/ext/openssl/ossl_provider.c +211 -0
  33. data/ext/openssl/ossl_provider.h +5 -0
  34. data/ext/openssl/ossl_rand.c +2 -40
  35. data/ext/openssl/ossl_ssl.c +666 -456
  36. data/ext/openssl/ossl_ssl_session.c +29 -30
  37. data/ext/openssl/ossl_ts.c +1539 -0
  38. data/ext/openssl/ossl_ts.h +16 -0
  39. data/ext/openssl/ossl_x509.c +86 -1
  40. data/ext/openssl/ossl_x509attr.c +1 -1
  41. data/ext/openssl/ossl_x509cert.c +170 -14
  42. data/ext/openssl/ossl_x509crl.c +14 -11
  43. data/ext/openssl/ossl_x509ext.c +29 -9
  44. data/ext/openssl/ossl_x509name.c +24 -12
  45. data/ext/openssl/ossl_x509req.c +14 -11
  46. data/ext/openssl/ossl_x509revoked.c +4 -4
  47. data/ext/openssl/ossl_x509store.c +205 -96
  48. data/lib/openssl/bn.rb +1 -1
  49. data/lib/openssl/buffering.rb +42 -20
  50. data/lib/openssl/cipher.rb +1 -1
  51. data/lib/openssl/digest.rb +10 -16
  52. data/lib/openssl/hmac.rb +78 -0
  53. data/lib/openssl/marshal.rb +30 -0
  54. data/lib/openssl/pkcs5.rb +1 -1
  55. data/lib/openssl/pkey.rb +447 -1
  56. data/lib/openssl/ssl.rb +68 -24
  57. data/lib/openssl/version.rb +5 -0
  58. data/lib/openssl/x509.rb +177 -1
  59. data/lib/openssl.rb +24 -9
  60. metadata +18 -71
  61. data/ext/openssl/deprecation.rb +0 -23
  62. data/ext/openssl/ossl_version.h +0 -15
  63. data/ext/openssl/ruby_missing.h +0 -24
  64. data/lib/openssl/config.rb +0 -474
@@ -11,8 +11,18 @@
11
11
  */
12
12
  #include "ossl.h"
13
13
 
14
+ #ifndef OPENSSL_NO_SOCK
14
15
  #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
15
16
 
17
+ #if !defined(OPENSSL_NO_NEXTPROTONEG) && !OSSL_IS_LIBRESSL
18
+ # define OSSL_USE_NEXTPROTONEG
19
+ #endif
20
+
21
+ #if !defined(TLS1_3_VERSION) && \
22
+ OSSL_LIBRESSL_PREREQ(3, 2, 0) && !OSSL_LIBRESSL_PREREQ(3, 4, 0)
23
+ # define TLS1_3_VERSION 0x0304
24
+ #endif
25
+
16
26
  #ifdef _WIN32
17
27
  # define TO_SOCKET(s) _get_osfhandle(s)
18
28
  #else
@@ -24,7 +34,6 @@
24
34
  } while (0)
25
35
 
26
36
  VALUE mSSL;
27
- static VALUE mSSLExtConfig;
28
37
  static VALUE eSSLError;
29
38
  VALUE cSSLContext;
30
39
  VALUE cSSLSocket;
@@ -32,44 +41,43 @@ VALUE cSSLSocket;
32
41
  static VALUE eSSLErrorWaitReadable;
33
42
  static VALUE eSSLErrorWaitWritable;
34
43
 
35
- static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
36
- id_npn_protocols_encoded;
44
+ static ID id_call, ID_callback_state, id_tmp_dh_callback,
45
+ id_npn_protocols_encoded, id_each;
37
46
  static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
38
47
 
39
48
  static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
40
49
  id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
41
50
  id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
42
- id_i_client_cert_cb, id_i_tmp_ecdh_callback, id_i_timeout,
51
+ id_i_client_cert_cb, id_i_timeout,
43
52
  id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
44
53
  id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
45
54
  id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
46
- id_i_verify_hostname;
55
+ id_i_verify_hostname, id_i_keylog_cb;
47
56
  static ID id_i_io, id_i_context, id_i_hostname;
48
57
 
49
58
  static int ossl_ssl_ex_vcb_idx;
50
59
  static int ossl_ssl_ex_ptr_idx;
51
60
  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
55
61
 
56
62
  static void
57
- ossl_sslctx_free(void *ptr)
63
+ ossl_sslctx_mark(void *ptr)
58
64
  {
59
65
  SSL_CTX *ctx = ptr;
60
- #if !defined(HAVE_X509_STORE_UP_REF)
61
- if (ctx && SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_store_p))
62
- ctx->cert_store = NULL;
63
- #endif
64
- SSL_CTX_free(ctx);
66
+ rb_gc_mark((VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx));
67
+ }
68
+
69
+ static void
70
+ ossl_sslctx_free(void *ptr)
71
+ {
72
+ SSL_CTX_free(ptr);
65
73
  }
66
74
 
67
75
  static const rb_data_type_t ossl_sslctx_type = {
68
76
  "OpenSSL/SSL/CTX",
69
77
  {
70
- 0, ossl_sslctx_free,
78
+ ossl_sslctx_mark, ossl_sslctx_free,
71
79
  },
72
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
80
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
73
81
  };
74
82
 
75
83
  static VALUE
@@ -83,7 +91,7 @@ ossl_sslctx_s_alloc(VALUE klass)
83
91
  VALUE obj;
84
92
 
85
93
  obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
86
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
94
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
87
95
  ctx = SSL_CTX_new(TLS_method());
88
96
  #else
89
97
  ctx = SSL_CTX_new(SSLv23_method());
@@ -95,14 +103,15 @@ ossl_sslctx_s_alloc(VALUE klass)
95
103
  RTYPEDDATA_DATA(obj) = ctx;
96
104
  SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj);
97
105
 
98
- #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
106
+ #if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER < 0x10100000 && \
107
+ !defined(LIBRESSL_VERSION_NUMBER)
99
108
  /* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
100
109
  * allows to specify multiple curve names and OpenSSL will select
101
110
  * automatically from them. In OpenSSL 1.0.2, the automatic selection has to
102
- * be enabled explicitly. But OpenSSL 1.1.0 removed the knob and it is
103
- * always enabled. To uniform the behavior, we enable the automatic
104
- * selection also in 1.0.2. Users can still disable ECDH by removing ECDH
105
- * cipher suites by SSLContext#ciphers=. */
111
+ * be enabled explicitly. OpenSSL 1.1.0 and LibreSSL 2.6.1 removed the knob
112
+ * and it is always enabled. To uniform the behavior, we enable the
113
+ * automatic selection also in 1.0.2. Users can still disable ECDH by
114
+ * removing ECDH cipher suites by SSLContext#ciphers=. */
106
115
  if (!SSL_CTX_set_ecdh_auto(ctx, 1))
107
116
  ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
108
117
  #endif
@@ -184,8 +193,10 @@ ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
184
193
 
185
194
  for (i = 0; i < numberof(options_map); i++) {
186
195
  sum |= options_map[i].opts;
187
- if (min && min > options_map[i].ver || max && max < options_map[i].ver)
196
+ if ((min && min > options_map[i].ver) ||
197
+ (max && max < options_map[i].ver)) {
188
198
  opts |= options_map[i].opts;
199
+ }
189
200
  }
190
201
  SSL_CTX_clear_options(ctx, sum);
191
202
  SSL_CTX_set_options(ctx, opts);
@@ -229,8 +240,7 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
229
240
  return 1;
230
241
  }
231
242
 
232
- #if !defined(OPENSSL_NO_DH) || \
233
- !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
243
+ #if !defined(OPENSSL_NO_DH)
234
244
  struct tmp_dh_callback_args {
235
245
  VALUE ssl_obj;
236
246
  ID id;
@@ -239,22 +249,23 @@ struct tmp_dh_callback_args {
239
249
  int keylength;
240
250
  };
241
251
 
242
- static EVP_PKEY *
243
- ossl_call_tmp_dh_callback(struct tmp_dh_callback_args *args)
252
+ static VALUE
253
+ ossl_call_tmp_dh_callback(VALUE arg)
244
254
  {
255
+ struct tmp_dh_callback_args *args = (struct tmp_dh_callback_args *)arg;
245
256
  VALUE cb, dh;
246
257
  EVP_PKEY *pkey;
247
258
 
248
259
  cb = rb_funcall(args->ssl_obj, args->id, 0);
249
260
  if (NIL_P(cb))
250
- return NULL;
261
+ return (VALUE)NULL;
251
262
  dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
252
263
  INT2NUM(args->keylength));
253
264
  pkey = GetPKeyPtr(dh);
254
265
  if (EVP_PKEY_base_id(pkey) != args->type)
255
- return NULL;
266
+ return (VALUE)NULL;
256
267
 
257
- return pkey;
268
+ return (VALUE)pkey;
258
269
  }
259
270
  #endif
260
271
 
@@ -274,7 +285,7 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
274
285
  args.keylength = keylength;
275
286
  args.type = EVP_PKEY_DH;
276
287
 
277
- pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
288
+ pkey = (EVP_PKEY *)rb_protect(ossl_call_tmp_dh_callback,
278
289
  (VALUE)&args, &state);
279
290
  if (state) {
280
291
  rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
@@ -283,39 +294,10 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
283
294
  if (!pkey)
284
295
  return NULL;
285
296
 
286
- return EVP_PKEY_get0_DH(pkey);
297
+ return (DH *)EVP_PKEY_get0_DH(pkey);
287
298
  }
288
299
  #endif /* OPENSSL_NO_DH */
289
300
 
290
- #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
291
- static EC_KEY *
292
- ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
293
- {
294
- VALUE rb_ssl;
295
- EVP_PKEY *pkey;
296
- struct tmp_dh_callback_args args;
297
- int state;
298
-
299
- rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
300
- args.ssl_obj = rb_ssl;
301
- args.id = id_tmp_ecdh_callback;
302
- args.is_export = is_export;
303
- args.keylength = keylength;
304
- args.type = EVP_PKEY_EC;
305
-
306
- pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
307
- (VALUE)&args, &state);
308
- if (state) {
309
- rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
310
- return NULL;
311
- }
312
- if (!pkey)
313
- return NULL;
314
-
315
- return EVP_PKEY_get0_EC_KEY(pkey);
316
- }
317
- #endif
318
-
319
301
  static VALUE
320
302
  call_verify_certificate_identity(VALUE ctx_v)
321
303
  {
@@ -357,7 +339,14 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
357
339
  rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
358
340
  return 0;
359
341
  }
360
- preverify_ok = ret == Qtrue;
342
+ if (ret != Qtrue) {
343
+ preverify_ok = 0;
344
+ #if defined(X509_V_ERR_HOSTNAME_MISMATCH)
345
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
346
+ #else
347
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
348
+ #endif
349
+ }
361
350
  }
362
351
 
363
352
  return ossl_verify_cb_call(cb, preverify_ok, ctx);
@@ -378,7 +367,7 @@ ossl_call_session_get_cb(VALUE ary)
378
367
  }
379
368
 
380
369
  static SSL_SESSION *
381
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
370
+ #if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
382
371
  ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
383
372
  #else
384
373
  ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
@@ -455,6 +444,54 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
455
444
  return 0;
456
445
  }
457
446
 
447
+ #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
448
+ /*
449
+ * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
450
+ * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
451
+ * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
452
+ */
453
+
454
+ struct ossl_call_keylog_cb_args {
455
+ VALUE ssl_obj;
456
+ const char * line;
457
+ };
458
+
459
+ static VALUE
460
+ ossl_call_keylog_cb(VALUE args_v)
461
+ {
462
+ VALUE sslctx_obj, cb, line_v;
463
+ struct ossl_call_keylog_cb_args *args = (struct ossl_call_keylog_cb_args *) args_v;
464
+
465
+ sslctx_obj = rb_attr_get(args->ssl_obj, id_i_context);
466
+
467
+ cb = rb_attr_get(sslctx_obj, id_i_keylog_cb);
468
+ if (NIL_P(cb)) return Qnil;
469
+
470
+ line_v = rb_str_new_cstr(args->line);
471
+
472
+ return rb_funcall(cb, id_call, 2, args->ssl_obj, line_v);
473
+ }
474
+
475
+ static void
476
+ ossl_sslctx_keylog_cb(const SSL *ssl, const char *line)
477
+ {
478
+ VALUE ssl_obj;
479
+ struct ossl_call_keylog_cb_args args;
480
+ int state = 0;
481
+
482
+ OSSL_Debug("SSL keylog callback entered");
483
+
484
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
485
+ args.ssl_obj = ssl_obj;
486
+ args.line = line;
487
+
488
+ rb_protect(ossl_call_keylog_cb, (VALUE)&args, &state);
489
+ if (state) {
490
+ rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
491
+ }
492
+ }
493
+ #endif
494
+
458
495
  static VALUE
459
496
  ossl_call_session_remove_cb(VALUE ary)
460
497
  {
@@ -587,10 +624,8 @@ ssl_renegotiation_cb(const SSL *ssl)
587
624
  rb_funcallv(cb, id_call, 1, &ssl_obj);
588
625
  }
589
626
 
590
- #if !defined(OPENSSL_NO_NEXTPROTONEG) || \
591
- defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
592
627
  static VALUE
593
- ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
628
+ ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
594
629
  {
595
630
  int len = RSTRING_LENINT(cur);
596
631
  char len_byte;
@@ -607,7 +642,7 @@ static VALUE
607
642
  ssl_encode_npn_protocols(VALUE protocols)
608
643
  {
609
644
  VALUE encoded = rb_str_new(NULL, 0);
610
- rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded);
645
+ rb_block_call(protocols, id_each, 0, 0, ssl_npn_encode_protocol_i, encoded);
611
646
  return encoded;
612
647
  }
613
648
 
@@ -670,14 +705,13 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
670
705
 
671
706
  return SSL_TLSEXT_ERR_OK;
672
707
  }
673
- #endif
674
708
 
675
- #ifndef OPENSSL_NO_NEXTPROTONEG
709
+ #ifdef OSSL_USE_NEXTPROTONEG
676
710
  static int
677
711
  ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
678
712
  void *arg)
679
713
  {
680
- VALUE protocols = (VALUE)arg;
714
+ VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded);
681
715
 
682
716
  *out = (const unsigned char *) RSTRING_PTR(protocols);
683
717
  *outlen = RSTRING_LENINT(protocols);
@@ -699,7 +733,6 @@ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
699
733
  }
700
734
  #endif
701
735
 
702
- #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
703
736
  static int
704
737
  ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
705
738
  const unsigned char *in, unsigned int inlen, void *arg)
@@ -711,7 +744,6 @@ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
711
744
 
712
745
  return ssl_npn_select_cb_common(ssl, cb, out, outlen, in, inlen);
713
746
  }
714
- #endif
715
747
 
716
748
  /* This function may serve as the entry point to support further callbacks. */
717
749
  static void
@@ -788,41 +820,15 @@ ossl_sslctx_setup(VALUE self)
788
820
  SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
789
821
  #endif
790
822
 
791
- #if !defined(OPENSSL_NO_EC)
792
- /* We added SSLContext#tmp_ecdh_callback= in Ruby 2.3.0,
793
- * but SSL_CTX_set_tmp_ecdh_callback() was removed in OpenSSL 1.1.0. */
794
- if (RTEST(rb_attr_get(self, id_i_tmp_ecdh_callback))) {
795
- # if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
796
- rb_warn("#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
797
- SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
798
- # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
799
- /* tmp_ecdh_callback and ecdh_auto conflict; OpenSSL ignores
800
- * tmp_ecdh_callback. So disable ecdh_auto. */
801
- if (!SSL_CTX_set_ecdh_auto(ctx, 0))
802
- ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
803
- # endif
804
- # else
805
- ossl_raise(eSSLError, "OpenSSL does not support tmp_ecdh_callback; "
806
- "use #ecdh_curves= instead");
807
- # endif
808
- }
809
- #endif /* OPENSSL_NO_EC */
823
+ #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
824
+ SSL_CTX_set_post_handshake_auth(ctx, 1);
825
+ #endif
810
826
 
811
827
  val = rb_attr_get(self, id_i_cert_store);
812
828
  if (!NIL_P(val)) {
813
829
  X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
814
830
  SSL_CTX_set_cert_store(ctx, store);
815
- #if !defined(HAVE_X509_STORE_UP_REF)
816
- /*
817
- * WORKAROUND:
818
- * X509_STORE can count references, but
819
- * X509_STORE_free() doesn't care it.
820
- * So we won't increment it but mark it by ex_data.
821
- */
822
- SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
823
- #else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
824
831
  X509_STORE_up_ref(store);
825
- #endif
826
832
  }
827
833
 
828
834
  val = rb_attr_get(self, id_i_extra_chain_cert);
@@ -873,10 +879,17 @@ ossl_sslctx_setup(VALUE self)
873
879
  ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
874
880
  val = rb_attr_get(self, id_i_ca_path);
875
881
  ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
876
- if(ca_file || ca_path){
877
- if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
878
- rb_warning("can't set verify locations");
882
+ #ifdef HAVE_SSL_CTX_LOAD_VERIFY_FILE
883
+ if (ca_file && !SSL_CTX_load_verify_file(ctx, ca_file))
884
+ ossl_raise(eSSLError, "SSL_CTX_load_verify_file");
885
+ if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path))
886
+ ossl_raise(eSSLError, "SSL_CTX_load_verify_dir");
887
+ #else
888
+ if (ca_file || ca_path) {
889
+ if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
890
+ ossl_raise(eSSLError, "SSL_CTX_load_verify_locations");
879
891
  }
892
+ #endif
880
893
 
881
894
  val = rb_attr_get(self, id_i_verify_mode);
882
895
  verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
@@ -890,12 +903,12 @@ ossl_sslctx_setup(VALUE self)
890
903
  val = rb_attr_get(self, id_i_verify_depth);
891
904
  if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
892
905
 
893
- #ifndef OPENSSL_NO_NEXTPROTONEG
906
+ #ifdef OSSL_USE_NEXTPROTONEG
894
907
  val = rb_attr_get(self, id_i_npn_protocols);
895
908
  if (!NIL_P(val)) {
896
909
  VALUE encoded = ssl_encode_npn_protocols(val);
897
910
  rb_ivar_set(self, id_npn_protocols_encoded, encoded);
898
- SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)encoded);
911
+ SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
899
912
  OSSL_Debug("SSL NPN advertise callback added");
900
913
  }
901
914
  if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
@@ -904,7 +917,6 @@ ossl_sslctx_setup(VALUE self)
904
917
  }
905
918
  #endif
906
919
 
907
- #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
908
920
  val = rb_attr_get(self, id_i_alpn_protocols);
909
921
  if (!NIL_P(val)) {
910
922
  VALUE rprotos = ssl_encode_npn_protocols(val);
@@ -919,7 +931,6 @@ ossl_sslctx_setup(VALUE self)
919
931
  SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
920
932
  OSSL_Debug("SSL ALPN select callback added");
921
933
  }
922
- #endif
923
934
 
924
935
  rb_obj_freeze(self);
925
936
 
@@ -951,6 +962,18 @@ ossl_sslctx_setup(VALUE self)
951
962
  OSSL_Debug("SSL TLSEXT servername callback added");
952
963
  }
953
964
 
965
+ #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
966
+ /*
967
+ * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
968
+ * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
969
+ * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
970
+ */
971
+ if (RTEST(rb_attr_get(self, id_i_keylog_cb))) {
972
+ SSL_CTX_set_keylog_callback(ctx, ossl_sslctx_keylog_cb);
973
+ OSSL_Debug("SSL keylog callback added");
974
+ }
975
+ #endif
976
+
954
977
  return Qtrue;
955
978
  }
956
979
 
@@ -999,27 +1022,13 @@ ossl_sslctx_get_ciphers(VALUE self)
999
1022
  return ary;
1000
1023
  }
1001
1024
 
1002
- /*
1003
- * call-seq:
1004
- * ctx.ciphers = "cipher1:cipher2:..."
1005
- * ctx.ciphers = [name, ...]
1006
- * ctx.ciphers = [[name, version, bits, alg_bits], ...]
1007
- *
1008
- * Sets the list of available cipher suites for this context. Note in a server
1009
- * context some ciphers require the appropriate certificates. For example, an
1010
- * RSA cipher suite can only be chosen when an RSA certificate is available.
1011
- */
1012
1025
  static VALUE
1013
- ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1026
+ build_cipher_string(VALUE v)
1014
1027
  {
1015
- SSL_CTX *ctx;
1016
1028
  VALUE str, elem;
1017
1029
  int i;
1018
1030
 
1019
- rb_check_frozen(self);
1020
- if (NIL_P(v))
1021
- return v;
1022
- else if (RB_TYPE_P(v, T_ARRAY)) {
1031
+ if (RB_TYPE_P(v, T_ARRAY)) {
1023
1032
  str = rb_str_new(0, 0);
1024
1033
  for (i = 0; i < RARRAY_LEN(v); i++) {
1025
1034
  elem = rb_ary_entry(v, i);
@@ -1033,14 +1042,113 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1033
1042
  StringValue(str);
1034
1043
  }
1035
1044
 
1045
+ return str;
1046
+ }
1047
+
1048
+ /*
1049
+ * call-seq:
1050
+ * ctx.ciphers = "cipher1:cipher2:..."
1051
+ * ctx.ciphers = [name, ...]
1052
+ * ctx.ciphers = [[name, version, bits, alg_bits], ...]
1053
+ *
1054
+ * Sets the list of available cipher suites for this context. Note in a server
1055
+ * context some ciphers require the appropriate certificates. For example, an
1056
+ * RSA cipher suite can only be chosen when an RSA certificate is available.
1057
+ */
1058
+ static VALUE
1059
+ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1060
+ {
1061
+ SSL_CTX *ctx;
1062
+ VALUE str;
1063
+
1064
+ rb_check_frozen(self);
1065
+ if (NIL_P(v))
1066
+ return v;
1067
+
1068
+ str = build_cipher_string(v);
1069
+
1036
1070
  GetSSLCTX(self, ctx);
1037
- if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) {
1071
+ if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
1038
1072
  ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
1039
- }
1040
1073
 
1041
1074
  return v;
1042
1075
  }
1043
1076
 
1077
+ #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
1078
+ /*
1079
+ * call-seq:
1080
+ * ctx.ciphersuites = "cipher1:cipher2:..."
1081
+ * ctx.ciphersuites = [name, ...]
1082
+ * ctx.ciphersuites = [[name, version, bits, alg_bits], ...]
1083
+ *
1084
+ * Sets the list of available TLSv1.3 cipher suites for this context.
1085
+ */
1086
+ static VALUE
1087
+ ossl_sslctx_set_ciphersuites(VALUE self, VALUE v)
1088
+ {
1089
+ SSL_CTX *ctx;
1090
+ VALUE str;
1091
+
1092
+ rb_check_frozen(self);
1093
+ if (NIL_P(v))
1094
+ return v;
1095
+
1096
+ str = build_cipher_string(v);
1097
+
1098
+ GetSSLCTX(self, ctx);
1099
+ if (!SSL_CTX_set_ciphersuites(ctx, StringValueCStr(str)))
1100
+ ossl_raise(eSSLError, "SSL_CTX_set_ciphersuites");
1101
+
1102
+ return v;
1103
+ }
1104
+ #endif
1105
+
1106
+ #ifndef OPENSSL_NO_DH
1107
+ /*
1108
+ * call-seq:
1109
+ * ctx.tmp_dh = pkey
1110
+ *
1111
+ * Sets DH parameters used for ephemeral DH key exchange. This is relevant for
1112
+ * servers only.
1113
+ *
1114
+ * +pkey+ is an instance of OpenSSL::PKey::DH. Note that key components
1115
+ * contained in the key object, if any, are ignored. The server will always
1116
+ * generate a new key pair for each handshake.
1117
+ *
1118
+ * Added in version 3.0. See also the man page SSL_set0_tmp_dh_pkey(3).
1119
+ *
1120
+ * Example:
1121
+ * ctx = OpenSSL::SSL::SSLContext.new
1122
+ * ctx.tmp_dh = OpenSSL::DH.generate(2048)
1123
+ * svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx)
1124
+ * Thread.new { svr.accept }
1125
+ */
1126
+ static VALUE
1127
+ ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg)
1128
+ {
1129
+ SSL_CTX *ctx;
1130
+ EVP_PKEY *pkey;
1131
+
1132
+ rb_check_frozen(self);
1133
+ GetSSLCTX(self, ctx);
1134
+ pkey = GetPKeyPtr(arg);
1135
+
1136
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH)
1137
+ rb_raise(eSSLError, "invalid pkey type %s (expected DH)",
1138
+ OBJ_nid2sn(EVP_PKEY_base_id(pkey)));
1139
+ #ifdef HAVE_SSL_SET0_TMP_DH_PKEY
1140
+ if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkey))
1141
+ ossl_raise(eSSLError, "SSL_CTX_set0_tmp_dh_pkey");
1142
+ EVP_PKEY_up_ref(pkey);
1143
+ #else
1144
+ if (!SSL_CTX_set_tmp_dh(ctx, EVP_PKEY_get0_DH(pkey)))
1145
+ ossl_raise(eSSLError, "SSL_CTX_set_tmp_dh");
1146
+ #endif
1147
+
1148
+ return arg;
1149
+ }
1150
+ #endif
1151
+
1044
1152
  #if !defined(OPENSSL_NO_EC)
1045
1153
  /*
1046
1154
  * call-seq:
@@ -1052,9 +1160,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1052
1160
  * Extension. For a server, the list is used by OpenSSL to determine the set of
1053
1161
  * shared curves. OpenSSL will pick the most appropriate one from it.
1054
1162
  *
1055
- * Note that this works differently with old OpenSSL (<= 1.0.1). Only one curve
1056
- * can be set, and this has no effect for TLS clients.
1057
- *
1058
1163
  * === Example
1059
1164
  * ctx1 = OpenSSL::SSL::SSLContext.new
1060
1165
  * ctx1.ecdh_curves = "X25519:P-256:P-224"
@@ -1078,48 +1183,8 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
1078
1183
  GetSSLCTX(self, ctx);
1079
1184
  StringValueCStr(arg);
1080
1185
 
1081
- #if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
1082
1186
  if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
1083
1187
  ossl_raise(eSSLError, NULL);
1084
- #else
1085
- /* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to
1086
- * SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */
1087
- {
1088
- VALUE curve, splitted;
1089
- EC_KEY *ec;
1090
- int nid;
1091
-
1092
- splitted = rb_str_split(arg, ":");
1093
- if (!RARRAY_LEN(splitted))
1094
- ossl_raise(eSSLError, "invalid input format");
1095
- curve = RARRAY_AREF(splitted, 0);
1096
- StringValueCStr(curve);
1097
-
1098
- /* SSL_CTX_set1_curves_list() accepts NIST names */
1099
- nid = EC_curve_nist2nid(RSTRING_PTR(curve));
1100
- if (nid == NID_undef)
1101
- nid = OBJ_txt2nid(RSTRING_PTR(curve));
1102
- if (nid == NID_undef)
1103
- ossl_raise(eSSLError, "unknown curve name");
1104
-
1105
- ec = EC_KEY_new_by_curve_name(nid);
1106
- if (!ec)
1107
- ossl_raise(eSSLError, NULL);
1108
- EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
1109
- if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
1110
- EC_KEY_free(ec);
1111
- ossl_raise(eSSLError, "SSL_CTX_set_tmp_ecdh");
1112
- }
1113
- EC_KEY_free(ec);
1114
- # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
1115
- /* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto
1116
- * is enabled. So disable ecdh_auto. */
1117
- if (!SSL_CTX_set_ecdh_auto(ctx, 0))
1118
- ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
1119
- # endif
1120
- }
1121
- #endif
1122
-
1123
1188
  return arg;
1124
1189
  }
1125
1190
  #else
@@ -1210,7 +1275,7 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
1210
1275
 
1211
1276
  /*
1212
1277
  * call-seq:
1213
- * ctx.add_certificate(certiticate, pkey [, extra_certs]) -> self
1278
+ * ctx.add_certificate(certificate, pkey [, extra_certs]) -> self
1214
1279
  *
1215
1280
  * Adds a certificate to the context. _pkey_ must be a corresponding private
1216
1281
  * key with _certificate_.
@@ -1242,10 +1307,6 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
1242
1307
  * ecdsa_pkey = ...
1243
1308
  * another_ca_cert = ...
1244
1309
  * ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])
1245
- *
1246
- * === Note
1247
- * OpenSSL before the version 1.0.2 could handle only one extra chain across
1248
- * all key types. Calling this method discards the chain set previously.
1249
1310
  */
1250
1311
  static VALUE
1251
1312
  ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
@@ -1270,7 +1331,7 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
1270
1331
  EVP_PKEY_free(pub_pkey);
1271
1332
  if (!pub_pkey)
1272
1333
  rb_raise(rb_eArgError, "certificate does not contain public key");
1273
- if (EVP_PKEY_cmp(pub_pkey, pkey) != 1)
1334
+ if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
1274
1335
  rb_raise(rb_eArgError, "public key mismatch");
1275
1336
 
1276
1337
  if (argc >= 3)
@@ -1284,34 +1345,9 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
1284
1345
  sk_X509_pop_free(extra_chain, X509_free);
1285
1346
  ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
1286
1347
  }
1287
-
1288
- if (extra_chain) {
1289
- #if OPENSSL_VERSION_NUMBER >= 0x10002000 && !defined(LIBRESSL_VERSION_NUMBER)
1290
- if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
1291
- sk_X509_pop_free(extra_chain, X509_free);
1292
- ossl_raise(eSSLError, "SSL_CTX_set0_chain");
1293
- }
1294
- #else
1295
- STACK_OF(X509) *orig_extra_chain;
1296
- X509 *x509_tmp;
1297
-
1298
- /* First, clear the existing chain */
1299
- SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
1300
- if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
1301
- rb_warning("SSL_CTX_set0_chain() is not available; " \
1302
- "clearing previously set certificate chain");
1303
- SSL_CTX_clear_extra_chain_certs(ctx);
1304
- }
1305
- while ((x509_tmp = sk_X509_shift(extra_chain))) {
1306
- /* Transfers ownership */
1307
- if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
1308
- X509_free(x509_tmp);
1309
- sk_X509_pop_free(extra_chain, X509_free);
1310
- ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert");
1311
- }
1312
- }
1313
- sk_X509_free(extra_chain);
1314
- #endif
1348
+ if (extra_chain && !SSL_CTX_set0_chain(ctx, extra_chain)) {
1349
+ sk_X509_pop_free(extra_chain, X509_free);
1350
+ ossl_raise(eSSLError, "SSL_CTX_set0_chain");
1315
1351
  }
1316
1352
  return self;
1317
1353
  }
@@ -1505,12 +1541,23 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
1505
1541
  /*
1506
1542
  * SSLSocket class
1507
1543
  */
1508
- #ifndef OPENSSL_NO_SOCK
1509
1544
  static inline int
1510
1545
  ssl_started(SSL *ssl)
1511
1546
  {
1512
- /* the FD is set in ossl_ssl_setup(), called by #connect or #accept */
1513
- return SSL_get_fd(ssl) >= 0;
1547
+ /* BIO is created through ossl_ssl_setup(), called by #connect or #accept */
1548
+ return SSL_get_rbio(ssl) != NULL;
1549
+ }
1550
+
1551
+ static void
1552
+ ossl_ssl_mark(void *ptr)
1553
+ {
1554
+ SSL *ssl = ptr;
1555
+ rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
1556
+
1557
+ // Note: this reference is stored as @verify_callback so we don't need to mark it.
1558
+ // However we do need to ensure GC compaction won't move it, hence why
1559
+ // we call rb_gc_mark here.
1560
+ rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
1514
1561
  }
1515
1562
 
1516
1563
  static void
@@ -1522,9 +1569,9 @@ ossl_ssl_free(void *ssl)
1522
1569
  const rb_data_type_t ossl_ssl_type = {
1523
1570
  "OpenSSL/SSL",
1524
1571
  {
1525
- 0, ossl_ssl_free,
1572
+ ossl_ssl_mark, ossl_ssl_free,
1526
1573
  },
1527
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
1574
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1528
1575
  };
1529
1576
 
1530
1577
  static VALUE
@@ -1533,6 +1580,29 @@ ossl_ssl_s_alloc(VALUE klass)
1533
1580
  return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
1534
1581
  }
1535
1582
 
1583
+ static VALUE
1584
+ peer_ip_address(VALUE self)
1585
+ {
1586
+ VALUE remote_address = rb_funcall(rb_attr_get(self, id_i_io), rb_intern("remote_address"), 0);
1587
+
1588
+ return rb_funcall(remote_address, rb_intern("inspect_sockaddr"), 0);
1589
+ }
1590
+
1591
+ static VALUE
1592
+ fallback_peer_ip_address(VALUE self, VALUE args)
1593
+ {
1594
+ return rb_str_new_cstr("(null)");
1595
+ }
1596
+
1597
+ static VALUE
1598
+ peeraddr_ip_str(VALUE self)
1599
+ {
1600
+ VALUE rb_mErrno = rb_const_get(rb_cObject, rb_intern("Errno"));
1601
+ VALUE rb_eSystemCallError = rb_const_get(rb_mErrno, rb_intern("SystemCallError"));
1602
+
1603
+ return rb_rescue2(peer_ip_address, self, fallback_peer_ip_address, (VALUE)0, rb_eSystemCallError, NULL);
1604
+ }
1605
+
1536
1606
  /*
1537
1607
  * call-seq:
1538
1608
  * SSLSocket.new(io) => aSSLSocket
@@ -1569,6 +1639,7 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1569
1639
 
1570
1640
  if (rb_respond_to(io, rb_intern("nonblock=")))
1571
1641
  rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
1642
+ Check_Type(io, T_FILE);
1572
1643
  rb_ivar_set(self, id_i_io, io);
1573
1644
 
1574
1645
  ssl = SSL_new(ctx);
@@ -1579,6 +1650,8 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1579
1650
  SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
1580
1651
  SSL_set_info_callback(ssl, ssl_info_cb);
1581
1652
  verify_cb = rb_attr_get(v_ctx, id_i_verify_callback);
1653
+ // We don't need to trigger a write barrier because it's already
1654
+ // an instance variable of this object.
1582
1655
  SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
1583
1656
 
1584
1657
  rb_call_super(0, NULL);
@@ -1586,6 +1659,17 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1586
1659
  return self;
1587
1660
  }
1588
1661
 
1662
+ #ifndef HAVE_RB_IO_DESCRIPTOR
1663
+ static int
1664
+ io_descriptor_fallback(VALUE io)
1665
+ {
1666
+ rb_io_t *fptr;
1667
+ GetOpenFile(io, fptr);
1668
+ return fptr->fd;
1669
+ }
1670
+ #define rb_io_descriptor io_descriptor_fallback
1671
+ #endif
1672
+
1589
1673
  static VALUE
1590
1674
  ossl_ssl_setup(VALUE self)
1591
1675
  {
@@ -1601,8 +1685,8 @@ ossl_ssl_setup(VALUE self)
1601
1685
  GetOpenFile(io, fptr);
1602
1686
  rb_io_check_readable(fptr);
1603
1687
  rb_io_check_writable(fptr);
1604
- if (!SSL_set_fd(ssl, TO_SOCKET(fptr->fd)))
1605
- ossl_raise(eSSLError, "SSL_set_fd");
1688
+ if (!SSL_set_fd(ssl, TO_SOCKET(rb_io_descriptor(io))))
1689
+ ossl_raise(eSSLError, "SSL_set_fd");
1606
1690
 
1607
1691
  return Qtrue;
1608
1692
  }
@@ -1636,70 +1720,107 @@ no_exception_p(VALUE opts)
1636
1720
  return 0;
1637
1721
  }
1638
1722
 
1723
+ // Provided by Ruby 3.2.0 and later in order to support the default IO#timeout.
1724
+ #ifndef RUBY_IO_TIMEOUT_DEFAULT
1725
+ #define RUBY_IO_TIMEOUT_DEFAULT Qnil
1726
+ #endif
1727
+
1728
+ static void
1729
+ io_wait_writable(VALUE io)
1730
+ {
1731
+ #ifdef HAVE_RB_IO_MAYBE_WAIT
1732
+ rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
1733
+ #else
1734
+ rb_io_t *fptr;
1735
+ GetOpenFile(io, fptr);
1736
+ rb_io_wait_writable(fptr->fd);
1737
+ #endif
1738
+ }
1739
+
1740
+ static void
1741
+ io_wait_readable(VALUE io)
1742
+ {
1743
+ #ifdef HAVE_RB_IO_MAYBE_WAIT
1744
+ rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
1745
+ #else
1746
+ rb_io_t *fptr;
1747
+ GetOpenFile(io, fptr);
1748
+ rb_io_wait_readable(fptr->fd);
1749
+ #endif
1750
+ }
1751
+
1639
1752
  static VALUE
1640
- ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1753
+ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
1641
1754
  {
1642
1755
  SSL *ssl;
1643
- rb_io_t *fptr;
1644
1756
  int ret, ret2;
1645
1757
  VALUE cb_state;
1646
1758
  int nonblock = opts != Qfalse;
1647
- #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1648
- unsigned long err;
1649
- #endif
1650
1759
 
1651
1760
  rb_ivar_set(self, ID_callback_state, Qnil);
1652
1761
 
1653
1762
  GetSSL(self, ssl);
1654
1763
 
1655
- GetOpenFile(rb_attr_get(self, id_i_io), fptr);
1656
- for(;;){
1657
- ret = func(ssl);
1764
+ VALUE io = rb_attr_get(self, id_i_io);
1765
+ for (;;) {
1766
+ ret = func(ssl);
1658
1767
 
1659
- cb_state = rb_attr_get(self, ID_callback_state);
1768
+ cb_state = rb_attr_get(self, ID_callback_state);
1660
1769
  if (!NIL_P(cb_state)) {
1661
- /* must cleanup OpenSSL error stack before re-raising */
1662
- ossl_clear_error();
1663
- rb_jump_tag(NUM2INT(cb_state));
1664
- }
1770
+ /* must cleanup OpenSSL error stack before re-raising */
1771
+ ossl_clear_error();
1772
+ rb_jump_tag(NUM2INT(cb_state));
1773
+ }
1665
1774
 
1666
- if (ret > 0)
1667
- break;
1775
+ if (ret > 0)
1776
+ break;
1668
1777
 
1669
- switch((ret2 = ssl_get_error(ssl, ret))){
1670
- case SSL_ERROR_WANT_WRITE:
1778
+ switch ((ret2 = ssl_get_error(ssl, ret))) {
1779
+ case SSL_ERROR_WANT_WRITE:
1671
1780
  if (no_exception_p(opts)) { return sym_wait_writable; }
1672
1781
  write_would_block(nonblock);
1673
- rb_io_wait_writable(fptr->fd);
1782
+ io_wait_writable(io);
1674
1783
  continue;
1675
- case SSL_ERROR_WANT_READ:
1784
+ case SSL_ERROR_WANT_READ:
1676
1785
  if (no_exception_p(opts)) { return sym_wait_readable; }
1677
1786
  read_would_block(nonblock);
1678
- rb_io_wait_readable(fptr->fd);
1787
+ io_wait_readable(io);
1679
1788
  continue;
1680
- case SSL_ERROR_SYSCALL:
1681
- if (errno) rb_sys_fail(funcname);
1682
- ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1789
+ case SSL_ERROR_SYSCALL:
1790
+ #ifdef __APPLE__
1791
+ /* See ossl_ssl_write_internal() */
1792
+ if (errno == EPROTOTYPE)
1793
+ continue;
1794
+ #endif
1795
+ if (errno) rb_sys_fail(funcname);
1796
+ /* fallthrough */
1797
+ default: {
1798
+ VALUE error_append = Qnil;
1683
1799
  #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1684
- case SSL_ERROR_SSL:
1685
- err = ERR_peek_last_error();
1686
- if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
1687
- ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1688
- const char *err_msg = ERR_reason_error_string(err),
1689
- *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1690
- if (!err_msg)
1691
- err_msg = "(null)";
1692
- if (!verify_msg)
1693
- verify_msg = "(null)";
1694
- ossl_clear_error(); /* let ossl_raise() not append message */
1695
- ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s: %s (%s)",
1696
- funcname, ret2, errno, SSL_state_string_long(ssl),
1697
- err_msg, verify_msg);
1698
- }
1800
+ unsigned long err = ERR_peek_last_error();
1801
+ if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
1802
+ ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1803
+ const char *err_msg = ERR_reason_error_string(err),
1804
+ *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1805
+ if (!err_msg)
1806
+ err_msg = "(null)";
1807
+ if (!verify_msg)
1808
+ verify_msg = "(null)";
1809
+ ossl_clear_error(); /* let ossl_raise() not append message */
1810
+ error_append = rb_sprintf(": %s (%s)", err_msg, verify_msg);
1811
+ }
1699
1812
  #endif
1700
- default:
1701
- ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1702
- }
1813
+ ossl_raise(eSSLError,
1814
+ "%s%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s%"PRIsVALUE,
1815
+ funcname,
1816
+ ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "",
1817
+ ret2,
1818
+ errno,
1819
+ peeraddr_ip_str(self),
1820
+ SSL_state_string_long(ssl),
1821
+ error_append);
1822
+ }
1823
+ }
1703
1824
  }
1704
1825
 
1705
1826
  return self;
@@ -1709,8 +1830,7 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1709
1830
  * call-seq:
1710
1831
  * ssl.connect => self
1711
1832
  *
1712
- * Initiates an SSL/TLS handshake with a server. The handshake may be started
1713
- * after unencrypted data has been sent over the socket.
1833
+ * Initiates an SSL/TLS handshake with a server.
1714
1834
  */
1715
1835
  static VALUE
1716
1836
  ossl_ssl_connect(VALUE self)
@@ -1757,8 +1877,7 @@ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
1757
1877
  * call-seq:
1758
1878
  * ssl.accept => self
1759
1879
  *
1760
- * Waits for a SSL/TLS client to initiate a handshake. The handshake may be
1761
- * started after unencrypted data has been sent over the socket.
1880
+ * Waits for a SSL/TLS client to initiate a handshake.
1762
1881
  */
1763
1882
  static VALUE
1764
1883
  ossl_ssl_accept(VALUE self)
@@ -1805,16 +1924,18 @@ static VALUE
1805
1924
  ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1806
1925
  {
1807
1926
  SSL *ssl;
1808
- int ilen, nread = 0;
1927
+ int ilen;
1809
1928
  VALUE len, str;
1810
- rb_io_t *fptr;
1811
- VALUE io, opts = Qnil;
1929
+ VALUE opts = Qnil;
1812
1930
 
1813
1931
  if (nonblock) {
1814
1932
  rb_scan_args(argc, argv, "11:", &len, &str, &opts);
1815
1933
  } else {
1816
1934
  rb_scan_args(argc, argv, "11", &len, &str);
1817
1935
  }
1936
+ GetSSL(self, ssl);
1937
+ if (!ssl_started(ssl))
1938
+ rb_raise(eSSLError, "SSL session is not started yet");
1818
1939
 
1819
1940
  ilen = NUM2INT(len);
1820
1941
  if (NIL_P(str))
@@ -1826,67 +1947,63 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1826
1947
  else
1827
1948
  rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
1828
1949
  }
1829
- OBJ_TAINT(str);
1830
1950
  rb_str_set_len(str, 0);
1831
1951
  if (ilen == 0)
1832
1952
  return str;
1833
1953
 
1834
- GetSSL(self, ssl);
1835
- io = rb_attr_get(self, id_i_io);
1836
- GetOpenFile(io, fptr);
1837
- if (ssl_started(ssl)) {
1838
- for (;;){
1839
- nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1840
- switch(ssl_get_error(ssl, nread)){
1841
- case SSL_ERROR_NONE:
1842
- goto end;
1843
- case SSL_ERROR_ZERO_RETURN:
1844
- if (no_exception_p(opts)) { return Qnil; }
1845
- rb_eof_error();
1846
- case SSL_ERROR_WANT_WRITE:
1847
- if (no_exception_p(opts)) { return sym_wait_writable; }
1954
+ VALUE io = rb_attr_get(self, id_i_io);
1955
+
1956
+ rb_str_locktmp(str);
1957
+ for (;;) {
1958
+ int nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1959
+ switch (ssl_get_error(ssl, nread)) {
1960
+ case SSL_ERROR_NONE:
1961
+ rb_str_unlocktmp(str);
1962
+ rb_str_set_len(str, nread);
1963
+ return str;
1964
+ case SSL_ERROR_ZERO_RETURN:
1965
+ rb_str_unlocktmp(str);
1966
+ if (no_exception_p(opts)) { return Qnil; }
1967
+ rb_eof_error();
1968
+ case SSL_ERROR_WANT_WRITE:
1969
+ if (nonblock) {
1970
+ rb_str_unlocktmp(str);
1971
+ if (no_exception_p(opts)) { return sym_wait_writable; }
1848
1972
  write_would_block(nonblock);
1849
- rb_io_wait_writable(fptr->fd);
1850
- continue;
1851
- case SSL_ERROR_WANT_READ:
1852
- if (no_exception_p(opts)) { return sym_wait_readable; }
1973
+ }
1974
+ io_wait_writable(io);
1975
+ continue;
1976
+ case SSL_ERROR_WANT_READ:
1977
+ if (nonblock) {
1978
+ rb_str_unlocktmp(str);
1979
+ if (no_exception_p(opts)) { return sym_wait_readable; }
1853
1980
  read_would_block(nonblock);
1854
- rb_io_wait_readable(fptr->fd);
1855
- continue;
1856
- case SSL_ERROR_SYSCALL:
1857
- if (!ERR_peek_error()) {
1858
- if (errno)
1859
- rb_sys_fail(0);
1860
- else {
1861
- /*
1862
- * The underlying BIO returned 0. This is actually a
1863
- * protocol error. But unfortunately, not all
1864
- * implementations cleanly shutdown the TLS connection
1865
- * but just shutdown/close the TCP connection. So report
1866
- * EOF for now...
1867
- */
1868
- if (no_exception_p(opts)) { return Qnil; }
1869
- rb_eof_error();
1870
- }
1871
- }
1872
- default:
1873
- ossl_raise(eSSLError, "SSL_read");
1874
- }
1981
+ }
1982
+ io_wait_readable(io);
1983
+ continue;
1984
+ case SSL_ERROR_SYSCALL:
1985
+ if (!ERR_peek_error()) {
1986
+ rb_str_unlocktmp(str);
1987
+ if (errno)
1988
+ rb_sys_fail(0);
1989
+ else {
1990
+ /*
1991
+ * The underlying BIO returned 0. This is actually a
1992
+ * protocol error. But unfortunately, not all
1993
+ * implementations cleanly shutdown the TLS connection
1994
+ * but just shutdown/close the TCP connection. So report
1995
+ * EOF for now...
1996
+ */
1997
+ if (no_exception_p(opts)) { return Qnil; }
1998
+ rb_eof_error();
1999
+ }
2000
+ }
2001
+ /* fall through */
2002
+ default:
2003
+ rb_str_unlocktmp(str);
2004
+ ossl_raise(eSSLError, "SSL_read");
1875
2005
  }
1876
2006
  }
1877
- else {
1878
- ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
1879
-
1880
- rb_warning("SSL session is not started yet.");
1881
- if (nonblock)
1882
- return rb_funcall(io, meth, 3, len, str, opts);
1883
- else
1884
- return rb_funcall(io, meth, 2, len, str);
1885
- }
1886
-
1887
- end:
1888
- rb_str_set_len(str, nread);
1889
- return str;
1890
2007
  }
1891
2008
 
1892
2009
  /*
@@ -1926,57 +2043,55 @@ static VALUE
1926
2043
  ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1927
2044
  {
1928
2045
  SSL *ssl;
1929
- int nwrite = 0;
1930
2046
  rb_io_t *fptr;
1931
- int nonblock = opts != Qfalse;
1932
- VALUE io;
2047
+ int num, nonblock = opts != Qfalse;
2048
+ VALUE tmp;
1933
2049
 
1934
- StringValue(str);
1935
2050
  GetSSL(self, ssl);
1936
- io = rb_attr_get(self, id_i_io);
2051
+ if (!ssl_started(ssl))
2052
+ rb_raise(eSSLError, "SSL session is not started yet");
2053
+
2054
+ tmp = rb_str_new_frozen(StringValue(str));
2055
+ VALUE io = rb_attr_get(self, id_i_io);
1937
2056
  GetOpenFile(io, fptr);
1938
- if (ssl_started(ssl)) {
1939
- for (;;){
1940
- int num = RSTRING_LENINT(str);
1941
-
1942
- /* SSL_write(3ssl) manpage states num == 0 is undefined */
1943
- if (num == 0)
1944
- goto end;
1945
-
1946
- nwrite = SSL_write(ssl, RSTRING_PTR(str), num);
1947
- switch(ssl_get_error(ssl, nwrite)){
1948
- case SSL_ERROR_NONE:
1949
- goto end;
1950
- case SSL_ERROR_WANT_WRITE:
1951
- if (no_exception_p(opts)) { return sym_wait_writable; }
1952
- write_would_block(nonblock);
1953
- rb_io_wait_writable(fptr->fd);
1954
- continue;
1955
- case SSL_ERROR_WANT_READ:
1956
- if (no_exception_p(opts)) { return sym_wait_readable; }
1957
- read_would_block(nonblock);
1958
- rb_io_wait_readable(fptr->fd);
2057
+
2058
+ /* SSL_write(3ssl) manpage states num == 0 is undefined */
2059
+ num = RSTRING_LENINT(tmp);
2060
+ if (num == 0)
2061
+ return INT2FIX(0);
2062
+
2063
+ for (;;) {
2064
+ int nwritten = SSL_write(ssl, RSTRING_PTR(tmp), num);
2065
+ switch (ssl_get_error(ssl, nwritten)) {
2066
+ case SSL_ERROR_NONE:
2067
+ return INT2NUM(nwritten);
2068
+ case SSL_ERROR_WANT_WRITE:
2069
+ if (no_exception_p(opts)) { return sym_wait_writable; }
2070
+ write_would_block(nonblock);
2071
+ io_wait_writable(io);
2072
+ continue;
2073
+ case SSL_ERROR_WANT_READ:
2074
+ if (no_exception_p(opts)) { return sym_wait_readable; }
2075
+ read_would_block(nonblock);
2076
+ io_wait_readable(io);
2077
+ continue;
2078
+ case SSL_ERROR_SYSCALL:
2079
+ #ifdef __APPLE__
2080
+ /*
2081
+ * It appears that send syscall can return EPROTOTYPE if the
2082
+ * socket is being torn down. Retry to get a proper errno to
2083
+ * make the error handling in line with the socket library.
2084
+ * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
2085
+ */
2086
+ if (errno == EPROTOTYPE)
1959
2087
  continue;
1960
- case SSL_ERROR_SYSCALL:
1961
- if (errno) rb_sys_fail(0);
1962
- default:
1963
- ossl_raise(eSSLError, "SSL_write");
1964
- }
2088
+ #endif
2089
+ if (errno) rb_sys_fail(0);
2090
+ /* fallthrough */
2091
+ default:
2092
+ ossl_raise(eSSLError, "SSL_write");
1965
2093
  }
1966
2094
  }
1967
- else {
1968
- ID meth = nonblock ?
1969
- rb_intern("write_nonblock") : rb_intern("syswrite");
1970
-
1971
- rb_warning("SSL session is not started yet.");
1972
- if (nonblock)
1973
- return rb_funcall(io, meth, 2, str, opts);
1974
- else
1975
- return rb_funcall(io, meth, 1, str);
1976
- }
1977
-
1978
- end:
1979
- return INT2NUM(nwrite);
1980
2095
  }
1981
2096
 
1982
2097
  /*
@@ -2275,7 +2390,57 @@ ossl_ssl_get_verify_result(VALUE self)
2275
2390
 
2276
2391
  GetSSL(self, ssl);
2277
2392
 
2278
- return INT2NUM(SSL_get_verify_result(ssl));
2393
+ return LONG2NUM(SSL_get_verify_result(ssl));
2394
+ }
2395
+
2396
+ /*
2397
+ * call-seq:
2398
+ * ssl.finished_message => "finished message"
2399
+ *
2400
+ * Returns the last *Finished* message sent
2401
+ *
2402
+ */
2403
+ static VALUE
2404
+ ossl_ssl_get_finished(VALUE self)
2405
+ {
2406
+ SSL *ssl;
2407
+ char sizer[1], *buf;
2408
+ size_t len;
2409
+
2410
+ GetSSL(self, ssl);
2411
+
2412
+ len = SSL_get_finished(ssl, sizer, 0);
2413
+ if (len == 0)
2414
+ return Qnil;
2415
+
2416
+ buf = ALLOCA_N(char, len);
2417
+ SSL_get_finished(ssl, buf, len);
2418
+ return rb_str_new(buf, len);
2419
+ }
2420
+
2421
+ /*
2422
+ * call-seq:
2423
+ * ssl.peer_finished_message => "peer finished message"
2424
+ *
2425
+ * Returns the last *Finished* message received
2426
+ *
2427
+ */
2428
+ static VALUE
2429
+ ossl_ssl_get_peer_finished(VALUE self)
2430
+ {
2431
+ SSL *ssl;
2432
+ char sizer[1], *buf;
2433
+ size_t len;
2434
+
2435
+ GetSSL(self, ssl);
2436
+
2437
+ len = SSL_get_peer_finished(ssl, sizer, 0);
2438
+ if (len == 0)
2439
+ return Qnil;
2440
+
2441
+ buf = ALLOCA_N(char, len);
2442
+ SSL_get_peer_finished(ssl, buf, len);
2443
+ return rb_str_new(buf, len);
2279
2444
  }
2280
2445
 
2281
2446
  /*
@@ -2301,7 +2466,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
2301
2466
  return ossl_x509name_sk2ary(ca);
2302
2467
  }
2303
2468
 
2304
- # ifndef OPENSSL_NO_NEXTPROTONEG
2469
+ # ifdef OSSL_USE_NEXTPROTONEG
2305
2470
  /*
2306
2471
  * call-seq:
2307
2472
  * ssl.npn_protocol => String | nil
@@ -2326,7 +2491,6 @@ ossl_ssl_npn_protocol(VALUE self)
2326
2491
  }
2327
2492
  # endif
2328
2493
 
2329
- # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2330
2494
  /*
2331
2495
  * call-seq:
2332
2496
  * ssl.alpn_protocol => String | nil
@@ -2349,9 +2513,50 @@ ossl_ssl_alpn_protocol(VALUE self)
2349
2513
  else
2350
2514
  return rb_str_new((const char *) out, outlen);
2351
2515
  }
2352
- # endif
2353
2516
 
2354
- # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2517
+ /*
2518
+ * call-seq:
2519
+ * session.export_keying_material(label, length) -> String
2520
+ *
2521
+ * Enables use of shared session key material in accordance with RFC 5705.
2522
+ */
2523
+ static VALUE
2524
+ ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self)
2525
+ {
2526
+ SSL *ssl;
2527
+ VALUE str;
2528
+ VALUE label;
2529
+ VALUE length;
2530
+ VALUE context;
2531
+ unsigned char *p;
2532
+ size_t len;
2533
+ int use_ctx = 0;
2534
+ unsigned char *ctx = NULL;
2535
+ size_t ctx_len = 0;
2536
+ int ret;
2537
+
2538
+ rb_scan_args(argc, argv, "21", &label, &length, &context);
2539
+ StringValue(label);
2540
+
2541
+ GetSSL(self, ssl);
2542
+
2543
+ len = (size_t)NUM2LONG(length);
2544
+ str = rb_str_new(0, len);
2545
+ p = (unsigned char *)RSTRING_PTR(str);
2546
+ if (!NIL_P(context)) {
2547
+ use_ctx = 1;
2548
+ StringValue(context);
2549
+ ctx = (unsigned char *)RSTRING_PTR(context);
2550
+ ctx_len = RSTRING_LEN(context);
2551
+ }
2552
+ ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label),
2553
+ RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
2554
+ if (ret == 0 || ret == -1) {
2555
+ ossl_raise(eSSLError, "SSL_export_keying_material");
2556
+ }
2557
+ return str;
2558
+ }
2559
+
2355
2560
  /*
2356
2561
  * call-seq:
2357
2562
  * ssl.tmp_key => PKey or nil
@@ -2369,11 +2574,8 @@ ossl_ssl_tmp_key(VALUE self)
2369
2574
  return Qnil;
2370
2575
  return ossl_pkey_new(key);
2371
2576
  }
2372
- # endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */
2373
2577
  #endif /* !defined(OPENSSL_NO_SOCK) */
2374
2578
 
2375
- #undef rb_intern
2376
- #define rb_intern(s) rb_intern_const(s)
2377
2579
  void
2378
2580
  Init_ossl_ssl(void)
2379
2581
  {
@@ -2384,8 +2586,9 @@ Init_ossl_ssl(void)
2384
2586
  rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
2385
2587
  #endif
2386
2588
 
2387
- id_call = rb_intern("call");
2388
- ID_callback_state = rb_intern("callback_state");
2589
+ #ifndef OPENSSL_NO_SOCK
2590
+ id_call = rb_intern_const("call");
2591
+ ID_callback_state = rb_intern_const("callback_state");
2389
2592
 
2390
2593
  ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0);
2391
2594
  if (ossl_ssl_ex_vcb_idx < 0)
@@ -2396,11 +2599,6 @@ Init_ossl_ssl(void)
2396
2599
  ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2397
2600
  if (ossl_sslctx_ex_ptr_idx < 0)
2398
2601
  ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2399
- #if !defined(HAVE_X509_STORE_UP_REF)
2400
- ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_store_p", 0, 0, 0);
2401
- if (ossl_sslctx_ex_store_p < 0)
2402
- ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2403
- #endif
2404
2602
 
2405
2603
  /* Document-module: OpenSSL::SSL
2406
2604
  *
@@ -2411,16 +2609,6 @@ Init_ossl_ssl(void)
2411
2609
  */
2412
2610
  mSSL = rb_define_module_under(mOSSL, "SSL");
2413
2611
 
2414
- /* Document-module: OpenSSL::ExtConfig
2415
- *
2416
- * This module contains configuration information about the SSL extension,
2417
- * for example if socket support is enabled, or the host name TLS extension
2418
- * is enabled. Constants in this module will always be defined, but contain
2419
- * +true+ or +false+ values depending on the configuration of your OpenSSL
2420
- * installation.
2421
- */
2422
- mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig");
2423
-
2424
2612
  /* Document-class: OpenSSL::SSL::SSLError
2425
2613
  *
2426
2614
  * Generic error class raised by SSLSocket and SSLContext.
@@ -2452,7 +2640,7 @@ Init_ossl_ssl(void)
2452
2640
  * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2453
2641
  * It is recommended to use #add_certificate instead.
2454
2642
  */
2455
- rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse);
2643
+ rb_attr(cSSLContext, rb_intern_const("cert"), 1, 1, Qfalse);
2456
2644
 
2457
2645
  /*
2458
2646
  * Context private key
@@ -2460,29 +2648,29 @@ Init_ossl_ssl(void)
2460
2648
  * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2461
2649
  * It is recommended to use #add_certificate instead.
2462
2650
  */
2463
- rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse);
2651
+ rb_attr(cSSLContext, rb_intern_const("key"), 1, 1, Qfalse);
2464
2652
 
2465
2653
  /*
2466
2654
  * A certificate or Array of certificates that will be sent to the client.
2467
2655
  */
2468
- rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse);
2656
+ rb_attr(cSSLContext, rb_intern_const("client_ca"), 1, 1, Qfalse);
2469
2657
 
2470
2658
  /*
2471
2659
  * The path to a file containing a PEM-format CA certificate
2472
2660
  */
2473
- rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse);
2661
+ rb_attr(cSSLContext, rb_intern_const("ca_file"), 1, 1, Qfalse);
2474
2662
 
2475
2663
  /*
2476
2664
  * The path to a directory containing CA certificates in PEM format.
2477
2665
  *
2478
2666
  * Files are looked up by subject's X509 name's hash value.
2479
2667
  */
2480
- rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse);
2668
+ rb_attr(cSSLContext, rb_intern_const("ca_path"), 1, 1, Qfalse);
2481
2669
 
2482
2670
  /*
2483
2671
  * Maximum session lifetime in seconds.
2484
2672
  */
2485
- rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse);
2673
+ rb_attr(cSSLContext, rb_intern_const("timeout"), 1, 1, Qfalse);
2486
2674
 
2487
2675
  /*
2488
2676
  * Session verification mode.
@@ -2495,12 +2683,12 @@ Init_ossl_ssl(void)
2495
2683
  *
2496
2684
  * See SSL_CTX_set_verify(3) for details.
2497
2685
  */
2498
- rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse);
2686
+ rb_attr(cSSLContext, rb_intern_const("verify_mode"), 1, 1, Qfalse);
2499
2687
 
2500
2688
  /*
2501
2689
  * Number of CA certificates to walk when verifying a certificate chain.
2502
2690
  */
2503
- rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse);
2691
+ rb_attr(cSSLContext, rb_intern_const("verify_depth"), 1, 1, Qfalse);
2504
2692
 
2505
2693
  /*
2506
2694
  * A callback for additional certificate verification. The callback is
@@ -2514,7 +2702,7 @@ Init_ossl_ssl(void)
2514
2702
  * If the callback returns +false+, the chain verification is immediately
2515
2703
  * stopped and a bad_certificate alert is then sent.
2516
2704
  */
2517
- rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
2705
+ rb_attr(cSSLContext, rb_intern_const("verify_callback"), 1, 1, Qfalse);
2518
2706
 
2519
2707
  /*
2520
2708
  * Whether to check the server certificate is valid for the hostname.
@@ -2522,12 +2710,12 @@ Init_ossl_ssl(void)
2522
2710
  * In order to make this work, verify_mode must be set to VERIFY_PEER and
2523
2711
  * the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=.
2524
2712
  */
2525
- rb_attr(cSSLContext, rb_intern("verify_hostname"), 1, 1, Qfalse);
2713
+ rb_attr(cSSLContext, rb_intern_const("verify_hostname"), 1, 1, Qfalse);
2526
2714
 
2527
2715
  /*
2528
2716
  * An OpenSSL::X509::Store used for certificate verification.
2529
2717
  */
2530
- rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse);
2718
+ rb_attr(cSSLContext, rb_intern_const("cert_store"), 1, 1, Qfalse);
2531
2719
 
2532
2720
  /*
2533
2721
  * An Array of extra X509 certificates to be added to the certificate
@@ -2536,7 +2724,7 @@ Init_ossl_ssl(void)
2536
2724
  * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2537
2725
  * It is recommended to use #add_certificate instead.
2538
2726
  */
2539
- rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse);
2727
+ rb_attr(cSSLContext, rb_intern_const("extra_chain_cert"), 1, 1, Qfalse);
2540
2728
 
2541
2729
  /*
2542
2730
  * A callback invoked when a client certificate is requested by a server
@@ -2546,28 +2734,14 @@ Init_ossl_ssl(void)
2546
2734
  * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any
2547
2735
  * other value is returned the handshake is suspended.
2548
2736
  */
2549
- rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
2550
-
2551
- #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
2552
- /*
2553
- * A callback invoked when ECDH parameters are required.
2554
- *
2555
- * The callback is invoked with the Session for the key exchange, an
2556
- * flag indicating the use of an export cipher and the keylength
2557
- * required.
2558
- *
2559
- * The callback is deprecated. This does not work with recent versions of
2560
- * OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead.
2561
- */
2562
- rb_attr(cSSLContext, rb_intern("tmp_ecdh_callback"), 1, 1, Qfalse);
2563
- #endif
2737
+ rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
2564
2738
 
2565
2739
  /*
2566
2740
  * Sets the context in which a session can be reused. This allows
2567
2741
  * sessions for multiple applications to be distinguished, for example, by
2568
2742
  * name.
2569
2743
  */
2570
- rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse);
2744
+ rb_attr(cSSLContext, rb_intern_const("session_id_context"), 1, 1, Qfalse);
2571
2745
 
2572
2746
  /*
2573
2747
  * A callback invoked on a server when a session is proposed by the client
@@ -2576,7 +2750,7 @@ Init_ossl_ssl(void)
2576
2750
  * The callback is invoked with the SSLSocket and session id. The
2577
2751
  * callback may return a Session from an external cache.
2578
2752
  */
2579
- rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse);
2753
+ rb_attr(cSSLContext, rb_intern_const("session_get_cb"), 1, 1, Qfalse);
2580
2754
 
2581
2755
  /*
2582
2756
  * A callback invoked when a new session was negotiated.
@@ -2584,7 +2758,7 @@ Init_ossl_ssl(void)
2584
2758
  * The callback is invoked with an SSLSocket. If +false+ is returned the
2585
2759
  * session will be removed from the internal cache.
2586
2760
  */
2587
- rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse);
2761
+ rb_attr(cSSLContext, rb_intern_const("session_new_cb"), 1, 1, Qfalse);
2588
2762
 
2589
2763
  /*
2590
2764
  * A callback invoked when a session is removed from the internal cache.
@@ -2595,18 +2769,16 @@ Init_ossl_ssl(void)
2595
2769
  * multi-threaded application. The callback is called inside a global lock
2596
2770
  * and it can randomly cause deadlock on Ruby thread switching.
2597
2771
  */
2598
- rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
2599
-
2600
- rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
2772
+ rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
2601
2773
 
2602
2774
  /*
2603
- * A callback invoked whenever a new handshake is initiated. May be used
2604
- * to disable renegotiation entirely.
2775
+ * A callback invoked whenever a new handshake is initiated on an
2776
+ * established connection. May be used to disable renegotiation entirely.
2605
2777
  *
2606
2778
  * The callback is invoked with the active SSLSocket. The callback's
2607
- * return value is irrelevant, normal return indicates "approval" of the
2779
+ * return value is ignored. A normal return indicates "approval" of the
2608
2780
  * renegotiation and will continue the process. To forbid renegotiation
2609
- * and to cancel the process, an Error may be raised within the callback.
2781
+ * and to cancel the process, raise an exception within the callback.
2610
2782
  *
2611
2783
  * === Disable client renegotiation
2612
2784
  *
@@ -2614,14 +2786,12 @@ Init_ossl_ssl(void)
2614
2786
  * renegotiation entirely. You may use a callback as follows to implement
2615
2787
  * this feature:
2616
2788
  *
2617
- * num_handshakes = 0
2618
2789
  * ctx.renegotiation_cb = lambda do |ssl|
2619
- * num_handshakes += 1
2620
- * raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
2790
+ * raise RuntimeError, "Client renegotiation disabled"
2621
2791
  * end
2622
2792
  */
2623
- rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse);
2624
- #ifndef OPENSSL_NO_NEXTPROTONEG
2793
+ rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
2794
+ #ifdef OSSL_USE_NEXTPROTONEG
2625
2795
  /*
2626
2796
  * An Enumerable of Strings. Each String represents a protocol to be
2627
2797
  * advertised as the list of supported protocols for Next Protocol
@@ -2633,7 +2803,7 @@ Init_ossl_ssl(void)
2633
2803
  *
2634
2804
  * ctx.npn_protocols = ["http/1.1", "spdy/2"]
2635
2805
  */
2636
- rb_attr(cSSLContext, rb_intern("npn_protocols"), 1, 1, Qfalse);
2806
+ rb_attr(cSSLContext, rb_intern_const("npn_protocols"), 1, 1, Qfalse);
2637
2807
  /*
2638
2808
  * A callback invoked on the client side when the client needs to select
2639
2809
  * a protocol from the list sent by the server. Supported in OpenSSL 1.0.1
@@ -2650,10 +2820,9 @@ Init_ossl_ssl(void)
2650
2820
  * protocols.first
2651
2821
  * end
2652
2822
  */
2653
- rb_attr(cSSLContext, rb_intern("npn_select_cb"), 1, 1, Qfalse);
2823
+ rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse);
2654
2824
  #endif
2655
2825
 
2656
- #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2657
2826
  /*
2658
2827
  * An Enumerable of Strings. Each String represents a protocol to be
2659
2828
  * advertised as the list of supported protocols for Application-Layer
@@ -2665,7 +2834,7 @@ Init_ossl_ssl(void)
2665
2834
  *
2666
2835
  * ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"]
2667
2836
  */
2668
- rb_attr(cSSLContext, rb_intern("alpn_protocols"), 1, 1, Qfalse);
2837
+ rb_attr(cSSLContext, rb_intern_const("alpn_protocols"), 1, 1, Qfalse);
2669
2838
  /*
2670
2839
  * A callback invoked on the server side when the server needs to select
2671
2840
  * a protocol from the list sent by the client. Supported in OpenSSL 1.0.2
@@ -2682,8 +2851,30 @@ Init_ossl_ssl(void)
2682
2851
  * protocols.first
2683
2852
  * end
2684
2853
  */
2685
- rb_attr(cSSLContext, rb_intern("alpn_select_cb"), 1, 1, Qfalse);
2686
- #endif
2854
+ rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
2855
+
2856
+ /*
2857
+ * A callback invoked when TLS key material is generated or received, in
2858
+ * order to allow applications to store this keying material for debugging
2859
+ * purposes.
2860
+ *
2861
+ * The callback is invoked with an SSLSocket and a string containing the
2862
+ * key material in the format used by NSS for its SSLKEYLOGFILE debugging
2863
+ * output.
2864
+ *
2865
+ * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
2866
+ * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
2867
+ * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
2868
+ *
2869
+ * === Example
2870
+ *
2871
+ * context.keylog_cb = proc do |_sock, line|
2872
+ * File.open('ssl_keylog_file', "a") do |f|
2873
+ * f.write("#{line}\n")
2874
+ * end
2875
+ * end
2876
+ */
2877
+ rb_attr(cSSLContext, rb_intern_const("keylog_cb"), 1, 1, Qfalse);
2687
2878
 
2688
2879
  rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2689
2880
  rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
@@ -2691,6 +2882,12 @@ Init_ossl_ssl(void)
2691
2882
  ossl_sslctx_set_minmax_proto_version, 2);
2692
2883
  rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2693
2884
  rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
2885
+ #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
2886
+ rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1);
2887
+ #endif
2888
+ #ifndef OPENSSL_NO_DH
2889
+ rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
2890
+ #endif
2694
2891
  rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
2695
2892
  rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
2696
2893
  rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
@@ -2764,11 +2961,6 @@ Init_ossl_ssl(void)
2764
2961
  * Document-class: OpenSSL::SSL::SSLSocket
2765
2962
  */
2766
2963
  cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
2767
- #ifdef OPENSSL_NO_SOCK
2768
- rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue);
2769
- rb_define_method(cSSLSocket, "initialize", rb_f_notimplement, -1);
2770
- #else
2771
- rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse);
2772
2964
  rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
2773
2965
  rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
2774
2966
  rb_undef_method(cSSLSocket, "initialize_copy");
@@ -2795,16 +2987,14 @@ Init_ossl_ssl(void)
2795
2987
  rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
2796
2988
  /* #hostname is defined in lib/openssl/ssl.rb */
2797
2989
  rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
2798
- # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2990
+ rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0);
2991
+ rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
2799
2992
  rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
2800
- # endif
2801
- # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2802
2993
  rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
2803
- # endif
2804
- # ifndef OPENSSL_NO_NEXTPROTONEG
2994
+ rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1);
2995
+ # ifdef OSSL_USE_NEXTPROTONEG
2805
2996
  rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2806
2997
  # endif
2807
- #endif
2808
2998
 
2809
2999
  rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
2810
3000
  rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
@@ -2812,12 +3002,23 @@ Init_ossl_ssl(void)
2812
3002
  rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
2813
3003
 
2814
3004
  rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL));
3005
+ #ifdef SSL_OP_CLEANSE_PLAINTEXT /* OpenSSL 3.0 */
3006
+ rb_define_const(mSSL, "OP_CLEANSE_PLAINTEXT", ULONG2NUM(SSL_OP_CLEANSE_PLAINTEXT));
3007
+ #endif
2815
3008
  rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
2816
- #ifdef SSL_OP_TLSEXT_PADDING /* OpenSSL 1.0.1h and OpenSSL 1.0.2 */
2817
- rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
3009
+ #ifdef SSL_OP_ENABLE_KTLS /* OpenSSL 3.0 */
3010
+ rb_define_const(mSSL, "OP_ENABLE_KTLS", ULONG2NUM(SSL_OP_ENABLE_KTLS));
2818
3011
  #endif
2819
- #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG /* OpenSSL 1.0.1f and OpenSSL 1.0.2 */
3012
+ rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
2820
3013
  rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG));
3014
+ #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* OpenSSL 3.0 */
3015
+ rb_define_const(mSSL, "OP_IGNORE_UNEXPECTED_EOF", ULONG2NUM(SSL_OP_IGNORE_UNEXPECTED_EOF));
3016
+ #endif
3017
+ #ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION /* OpenSSL 3.0 */
3018
+ rb_define_const(mSSL, "OP_ALLOW_CLIENT_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_CLIENT_RENEGOTIATION));
3019
+ #endif
3020
+ #ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */
3021
+ rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES));
2821
3022
  #endif
2822
3023
  #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
2823
3024
  rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
@@ -2830,13 +3031,15 @@ Init_ossl_ssl(void)
2830
3031
  #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
2831
3032
  rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
2832
3033
  #endif
2833
- rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
2834
- rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
2835
- #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
2836
- rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
3034
+ #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */
3035
+ rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT));
3036
+ #endif
3037
+ #ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */
3038
+ rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA));
3039
+ #endif
3040
+ #ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */
3041
+ rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY));
2837
3042
  #endif
2838
- rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
2839
-
2840
3043
  rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
2841
3044
  rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
2842
3045
  rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
@@ -2844,6 +3047,12 @@ Init_ossl_ssl(void)
2844
3047
  #ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
2845
3048
  rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
2846
3049
  #endif
3050
+ rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
3051
+ rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
3052
+ #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
3053
+ rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
3054
+ #endif
3055
+ rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
2847
3056
 
2848
3057
  /* SSL_OP_* flags for DTLS */
2849
3058
  #if 0
@@ -2908,16 +3117,16 @@ Init_ossl_ssl(void)
2908
3117
  #endif
2909
3118
 
2910
3119
 
2911
- sym_exception = ID2SYM(rb_intern("exception"));
2912
- sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
2913
- sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
3120
+ sym_exception = ID2SYM(rb_intern_const("exception"));
3121
+ sym_wait_readable = ID2SYM(rb_intern_const("wait_readable"));
3122
+ sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
2914
3123
 
2915
- id_tmp_dh_callback = rb_intern("tmp_dh_callback");
2916
- id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
2917
- id_npn_protocols_encoded = rb_intern("npn_protocols_encoded");
3124
+ id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
3125
+ id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
3126
+ id_each = rb_intern_const("each");
2918
3127
 
2919
3128
  #define DefIVarID(name) do \
2920
- id_i_##name = rb_intern("@"#name); while (0)
3129
+ id_i_##name = rb_intern_const("@"#name); while (0)
2921
3130
 
2922
3131
  DefIVarID(cert_store);
2923
3132
  DefIVarID(ca_file);
@@ -2931,7 +3140,6 @@ Init_ossl_ssl(void)
2931
3140
  DefIVarID(key);
2932
3141
  DefIVarID(extra_chain_cert);
2933
3142
  DefIVarID(client_cert_cb);
2934
- DefIVarID(tmp_ecdh_callback);
2935
3143
  DefIVarID(timeout);
2936
3144
  DefIVarID(session_id_context);
2937
3145
  DefIVarID(session_get_cb);
@@ -2943,8 +3151,10 @@ Init_ossl_ssl(void)
2943
3151
  DefIVarID(alpn_select_cb);
2944
3152
  DefIVarID(servername_cb);
2945
3153
  DefIVarID(verify_hostname);
3154
+ DefIVarID(keylog_cb);
2946
3155
 
2947
3156
  DefIVarID(io);
2948
3157
  DefIVarID(context);
2949
3158
  DefIVarID(hostname);
3159
+ #endif /* !defined(OPENSSL_NO_SOCK) */
2950
3160
  }