openssl 2.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
  }