openssl 2.2.1 → 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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +33 -45
  3. data/History.md +248 -1
  4. data/README.md +36 -19
  5. data/ext/openssl/extconf.rb +101 -68
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +26 -45
  8. data/ext/openssl/ossl.c +128 -237
  9. data/ext/openssl/ossl.h +31 -12
  10. data/ext/openssl/ossl_asn1.c +26 -13
  11. data/ext/openssl/ossl_bn.c +213 -139
  12. data/ext/openssl/ossl_cipher.c +13 -14
  13. data/ext/openssl/ossl_config.c +412 -41
  14. data/ext/openssl/ossl_config.h +4 -7
  15. data/ext/openssl/ossl_digest.c +10 -10
  16. data/ext/openssl/ossl_engine.c +17 -16
  17. data/ext/openssl/ossl_hmac.c +57 -136
  18. data/ext/openssl/ossl_kdf.c +12 -4
  19. data/ext/openssl/ossl_ns_spki.c +1 -1
  20. data/ext/openssl/ossl_ocsp.c +11 -59
  21. data/ext/openssl/ossl_pkcs12.c +22 -4
  22. data/ext/openssl/ossl_pkcs7.c +45 -62
  23. data/ext/openssl/ossl_pkey.c +1320 -196
  24. data/ext/openssl/ossl_pkey.h +36 -73
  25. data/ext/openssl/ossl_pkey_dh.c +152 -347
  26. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  27. data/ext/openssl/ossl_pkey_ec.c +227 -343
  28. data/ext/openssl/ossl_pkey_rsa.c +159 -491
  29. data/ext/openssl/ossl_provider.c +211 -0
  30. data/ext/openssl/ossl_provider.h +5 -0
  31. data/ext/openssl/ossl_ssl.c +530 -450
  32. data/ext/openssl/ossl_ssl_session.c +29 -30
  33. data/ext/openssl/ossl_ts.c +38 -23
  34. data/ext/openssl/ossl_x509.c +0 -6
  35. data/ext/openssl/ossl_x509attr.c +1 -1
  36. data/ext/openssl/ossl_x509cert.c +168 -12
  37. data/ext/openssl/ossl_x509crl.c +14 -11
  38. data/ext/openssl/ossl_x509ext.c +14 -9
  39. data/ext/openssl/ossl_x509name.c +10 -3
  40. data/ext/openssl/ossl_x509req.c +14 -11
  41. data/ext/openssl/ossl_x509revoked.c +4 -4
  42. data/ext/openssl/ossl_x509store.c +166 -75
  43. data/lib/openssl/buffering.rb +9 -3
  44. data/lib/openssl/digest.rb +1 -5
  45. data/lib/openssl/hmac.rb +65 -0
  46. data/lib/openssl/pkey.rb +429 -0
  47. data/lib/openssl/ssl.rb +22 -17
  48. data/lib/openssl/version.rb +1 -1
  49. data/lib/openssl/x509.rb +22 -0
  50. data/lib/openssl.rb +0 -1
  51. metadata +10 -79
  52. data/ext/openssl/ruby_missing.h +0 -24
  53. data/lib/openssl/config.rb +0 -501
@@ -11,11 +11,15 @@
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
+
16
21
  #if !defined(TLS1_3_VERSION) && \
17
- defined(LIBRESSL_VERSION_NUMBER) && \
18
- LIBRESSL_VERSION_NUMBER >= 0x3020000fL
22
+ OSSL_LIBRESSL_PREREQ(3, 2, 0) && !OSSL_LIBRESSL_PREREQ(3, 4, 0)
19
23
  # define TLS1_3_VERSION 0x0304
20
24
  #endif
21
25
 
@@ -30,7 +34,6 @@
30
34
  } while (0)
31
35
 
32
36
  VALUE mSSL;
33
- static VALUE mSSLExtConfig;
34
37
  static VALUE eSSLError;
35
38
  VALUE cSSLContext;
36
39
  VALUE cSSLSocket;
@@ -38,26 +41,23 @@ VALUE cSSLSocket;
38
41
  static VALUE eSSLErrorWaitReadable;
39
42
  static VALUE eSSLErrorWaitWritable;
40
43
 
41
- static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
44
+ static ID id_call, ID_callback_state, id_tmp_dh_callback,
42
45
  id_npn_protocols_encoded, id_each;
43
46
  static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
44
47
 
45
48
  static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
46
49
  id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
47
50
  id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
48
- id_i_client_cert_cb, id_i_tmp_ecdh_callback, id_i_timeout,
51
+ id_i_client_cert_cb, id_i_timeout,
49
52
  id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
50
53
  id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
51
54
  id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
52
- id_i_verify_hostname;
55
+ id_i_verify_hostname, id_i_keylog_cb;
53
56
  static ID id_i_io, id_i_context, id_i_hostname;
54
57
 
55
58
  static int ossl_ssl_ex_vcb_idx;
56
59
  static int ossl_ssl_ex_ptr_idx;
57
60
  static int ossl_sslctx_ex_ptr_idx;
58
- #if !defined(HAVE_X509_STORE_UP_REF)
59
- static int ossl_sslctx_ex_store_p;
60
- #endif
61
61
 
62
62
  static void
63
63
  ossl_sslctx_mark(void *ptr)
@@ -69,12 +69,7 @@ ossl_sslctx_mark(void *ptr)
69
69
  static void
70
70
  ossl_sslctx_free(void *ptr)
71
71
  {
72
- SSL_CTX *ctx = ptr;
73
- #if !defined(HAVE_X509_STORE_UP_REF)
74
- if (ctx && SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_store_p))
75
- ctx->cert_store = NULL;
76
- #endif
77
- SSL_CTX_free(ctx);
72
+ SSL_CTX_free(ptr);
78
73
  }
79
74
 
80
75
  static const rb_data_type_t ossl_sslctx_type = {
@@ -82,7 +77,7 @@ static const rb_data_type_t ossl_sslctx_type = {
82
77
  {
83
78
  ossl_sslctx_mark, ossl_sslctx_free,
84
79
  },
85
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
80
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
86
81
  };
87
82
 
88
83
  static VALUE
@@ -96,7 +91,7 @@ ossl_sslctx_s_alloc(VALUE klass)
96
91
  VALUE obj;
97
92
 
98
93
  obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
99
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
94
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
100
95
  ctx = SSL_CTX_new(TLS_method());
101
96
  #else
102
97
  ctx = SSL_CTX_new(SSLv23_method());
@@ -108,14 +103,15 @@ ossl_sslctx_s_alloc(VALUE klass)
108
103
  RTYPEDDATA_DATA(obj) = ctx;
109
104
  SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj);
110
105
 
111
- #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)
112
108
  /* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
113
109
  * allows to specify multiple curve names and OpenSSL will select
114
110
  * automatically from them. In OpenSSL 1.0.2, the automatic selection has to
115
- * be enabled explicitly. But OpenSSL 1.1.0 removed the knob and it is
116
- * always enabled. To uniform the behavior, we enable the automatic
117
- * selection also in 1.0.2. Users can still disable ECDH by removing ECDH
118
- * 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=. */
119
115
  if (!SSL_CTX_set_ecdh_auto(ctx, 1))
120
116
  ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
121
117
  #endif
@@ -244,8 +240,7 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
244
240
  return 1;
245
241
  }
246
242
 
247
- #if !defined(OPENSSL_NO_DH) || \
248
- !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
243
+ #if !defined(OPENSSL_NO_DH)
249
244
  struct tmp_dh_callback_args {
250
245
  VALUE ssl_obj;
251
246
  ID id;
@@ -254,22 +249,23 @@ struct tmp_dh_callback_args {
254
249
  int keylength;
255
250
  };
256
251
 
257
- static EVP_PKEY *
258
- ossl_call_tmp_dh_callback(struct tmp_dh_callback_args *args)
252
+ static VALUE
253
+ ossl_call_tmp_dh_callback(VALUE arg)
259
254
  {
255
+ struct tmp_dh_callback_args *args = (struct tmp_dh_callback_args *)arg;
260
256
  VALUE cb, dh;
261
257
  EVP_PKEY *pkey;
262
258
 
263
259
  cb = rb_funcall(args->ssl_obj, args->id, 0);
264
260
  if (NIL_P(cb))
265
- return NULL;
261
+ return (VALUE)NULL;
266
262
  dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
267
263
  INT2NUM(args->keylength));
268
264
  pkey = GetPKeyPtr(dh);
269
265
  if (EVP_PKEY_base_id(pkey) != args->type)
270
- return NULL;
266
+ return (VALUE)NULL;
271
267
 
272
- return pkey;
268
+ return (VALUE)pkey;
273
269
  }
274
270
  #endif
275
271
 
@@ -289,7 +285,7 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
289
285
  args.keylength = keylength;
290
286
  args.type = EVP_PKEY_DH;
291
287
 
292
- pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
288
+ pkey = (EVP_PKEY *)rb_protect(ossl_call_tmp_dh_callback,
293
289
  (VALUE)&args, &state);
294
290
  if (state) {
295
291
  rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
@@ -298,39 +294,10 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
298
294
  if (!pkey)
299
295
  return NULL;
300
296
 
301
- return EVP_PKEY_get0_DH(pkey);
297
+ return (DH *)EVP_PKEY_get0_DH(pkey);
302
298
  }
303
299
  #endif /* OPENSSL_NO_DH */
304
300
 
305
- #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
306
- static EC_KEY *
307
- ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
308
- {
309
- VALUE rb_ssl;
310
- EVP_PKEY *pkey;
311
- struct tmp_dh_callback_args args;
312
- int state;
313
-
314
- rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
315
- args.ssl_obj = rb_ssl;
316
- args.id = id_tmp_ecdh_callback;
317
- args.is_export = is_export;
318
- args.keylength = keylength;
319
- args.type = EVP_PKEY_EC;
320
-
321
- pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
322
- (VALUE)&args, &state);
323
- if (state) {
324
- rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
325
- return NULL;
326
- }
327
- if (!pkey)
328
- return NULL;
329
-
330
- return EVP_PKEY_get0_EC_KEY(pkey);
331
- }
332
- #endif
333
-
334
301
  static VALUE
335
302
  call_verify_certificate_identity(VALUE ctx_v)
336
303
  {
@@ -400,7 +367,7 @@ ossl_call_session_get_cb(VALUE ary)
400
367
  }
401
368
 
402
369
  static SSL_SESSION *
403
- #if (!defined(LIBRESSL_VERSION_NUMBER) ? OPENSSL_VERSION_NUMBER >= 0x10100000 : LIBRESSL_VERSION_NUMBER >= 0x2080000f)
370
+ #if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
404
371
  ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
405
372
  #else
406
373
  ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
@@ -477,6 +444,54 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
477
444
  return 0;
478
445
  }
479
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
+
480
495
  static VALUE
481
496
  ossl_call_session_remove_cb(VALUE ary)
482
497
  {
@@ -609,8 +624,6 @@ ssl_renegotiation_cb(const SSL *ssl)
609
624
  rb_funcallv(cb, id_call, 1, &ssl_obj);
610
625
  }
611
626
 
612
- #if !defined(OPENSSL_NO_NEXTPROTONEG) || \
613
- defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
614
627
  static VALUE
615
628
  ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
616
629
  {
@@ -692,9 +705,8 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
692
705
 
693
706
  return SSL_TLSEXT_ERR_OK;
694
707
  }
695
- #endif
696
708
 
697
- #ifndef OPENSSL_NO_NEXTPROTONEG
709
+ #ifdef OSSL_USE_NEXTPROTONEG
698
710
  static int
699
711
  ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
700
712
  void *arg)
@@ -721,7 +733,6 @@ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
721
733
  }
722
734
  #endif
723
735
 
724
- #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
725
736
  static int
726
737
  ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
727
738
  const unsigned char *in, unsigned int inlen, void *arg)
@@ -733,7 +744,6 @@ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
733
744
 
734
745
  return ssl_npn_select_cb_common(ssl, cb, out, outlen, in, inlen);
735
746
  }
736
- #endif
737
747
 
738
748
  /* This function may serve as the entry point to support further callbacks. */
739
749
  static void
@@ -810,26 +820,6 @@ ossl_sslctx_setup(VALUE self)
810
820
  SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
811
821
  #endif
812
822
 
813
- #if !defined(OPENSSL_NO_EC)
814
- /* We added SSLContext#tmp_ecdh_callback= in Ruby 2.3.0,
815
- * but SSL_CTX_set_tmp_ecdh_callback() was removed in OpenSSL 1.1.0. */
816
- if (RTEST(rb_attr_get(self, id_i_tmp_ecdh_callback))) {
817
- # if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
818
- rb_warn("#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
819
- SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
820
- # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
821
- /* tmp_ecdh_callback and ecdh_auto conflict; OpenSSL ignores
822
- * tmp_ecdh_callback. So disable ecdh_auto. */
823
- if (!SSL_CTX_set_ecdh_auto(ctx, 0))
824
- ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
825
- # endif
826
- # else
827
- ossl_raise(eSSLError, "OpenSSL does not support tmp_ecdh_callback; "
828
- "use #ecdh_curves= instead");
829
- # endif
830
- }
831
- #endif /* OPENSSL_NO_EC */
832
-
833
823
  #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
834
824
  SSL_CTX_set_post_handshake_auth(ctx, 1);
835
825
  #endif
@@ -838,17 +828,7 @@ ossl_sslctx_setup(VALUE self)
838
828
  if (!NIL_P(val)) {
839
829
  X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
840
830
  SSL_CTX_set_cert_store(ctx, store);
841
- #if !defined(HAVE_X509_STORE_UP_REF)
842
- /*
843
- * WORKAROUND:
844
- * X509_STORE can count references, but
845
- * X509_STORE_free() doesn't care it.
846
- * So we won't increment it but mark it by ex_data.
847
- */
848
- SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
849
- #else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
850
831
  X509_STORE_up_ref(store);
851
- #endif
852
832
  }
853
833
 
854
834
  val = rb_attr_get(self, id_i_extra_chain_cert);
@@ -899,10 +879,17 @@ ossl_sslctx_setup(VALUE self)
899
879
  ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
900
880
  val = rb_attr_get(self, id_i_ca_path);
901
881
  ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
902
- if(ca_file || ca_path){
903
- if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
904
- 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");
905
891
  }
892
+ #endif
906
893
 
907
894
  val = rb_attr_get(self, id_i_verify_mode);
908
895
  verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
@@ -916,7 +903,7 @@ ossl_sslctx_setup(VALUE self)
916
903
  val = rb_attr_get(self, id_i_verify_depth);
917
904
  if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
918
905
 
919
- #ifndef OPENSSL_NO_NEXTPROTONEG
906
+ #ifdef OSSL_USE_NEXTPROTONEG
920
907
  val = rb_attr_get(self, id_i_npn_protocols);
921
908
  if (!NIL_P(val)) {
922
909
  VALUE encoded = ssl_encode_npn_protocols(val);
@@ -930,7 +917,6 @@ ossl_sslctx_setup(VALUE self)
930
917
  }
931
918
  #endif
932
919
 
933
- #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
934
920
  val = rb_attr_get(self, id_i_alpn_protocols);
935
921
  if (!NIL_P(val)) {
936
922
  VALUE rprotos = ssl_encode_npn_protocols(val);
@@ -945,7 +931,6 @@ ossl_sslctx_setup(VALUE self)
945
931
  SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
946
932
  OSSL_Debug("SSL ALPN select callback added");
947
933
  }
948
- #endif
949
934
 
950
935
  rb_obj_freeze(self);
951
936
 
@@ -977,6 +962,18 @@ ossl_sslctx_setup(VALUE self)
977
962
  OSSL_Debug("SSL TLSEXT servername callback added");
978
963
  }
979
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
+
980
977
  return Qtrue;
981
978
  }
982
979
 
@@ -1025,27 +1022,13 @@ ossl_sslctx_get_ciphers(VALUE self)
1025
1022
  return ary;
1026
1023
  }
1027
1024
 
1028
- /*
1029
- * call-seq:
1030
- * ctx.ciphers = "cipher1:cipher2:..."
1031
- * ctx.ciphers = [name, ...]
1032
- * ctx.ciphers = [[name, version, bits, alg_bits], ...]
1033
- *
1034
- * Sets the list of available cipher suites for this context. Note in a server
1035
- * context some ciphers require the appropriate certificates. For example, an
1036
- * RSA cipher suite can only be chosen when an RSA certificate is available.
1037
- */
1038
1025
  static VALUE
1039
- ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1026
+ build_cipher_string(VALUE v)
1040
1027
  {
1041
- SSL_CTX *ctx;
1042
1028
  VALUE str, elem;
1043
1029
  int i;
1044
1030
 
1045
- rb_check_frozen(self);
1046
- if (NIL_P(v))
1047
- return v;
1048
- else if (RB_TYPE_P(v, T_ARRAY)) {
1031
+ if (RB_TYPE_P(v, T_ARRAY)) {
1049
1032
  str = rb_str_new(0, 0);
1050
1033
  for (i = 0; i < RARRAY_LEN(v); i++) {
1051
1034
  elem = rb_ary_entry(v, i);
@@ -1059,14 +1042,113 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1059
1042
  StringValue(str);
1060
1043
  }
1061
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
+
1062
1070
  GetSSLCTX(self, ctx);
1063
- if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) {
1071
+ if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
1064
1072
  ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
1065
- }
1066
1073
 
1067
1074
  return v;
1068
1075
  }
1069
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
+
1070
1152
  #if !defined(OPENSSL_NO_EC)
1071
1153
  /*
1072
1154
  * call-seq:
@@ -1078,9 +1160,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1078
1160
  * Extension. For a server, the list is used by OpenSSL to determine the set of
1079
1161
  * shared curves. OpenSSL will pick the most appropriate one from it.
1080
1162
  *
1081
- * Note that this works differently with old OpenSSL (<= 1.0.1). Only one curve
1082
- * can be set, and this has no effect for TLS clients.
1083
- *
1084
1163
  * === Example
1085
1164
  * ctx1 = OpenSSL::SSL::SSLContext.new
1086
1165
  * ctx1.ecdh_curves = "X25519:P-256:P-224"
@@ -1104,48 +1183,8 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
1104
1183
  GetSSLCTX(self, ctx);
1105
1184
  StringValueCStr(arg);
1106
1185
 
1107
- #if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
1108
1186
  if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
1109
1187
  ossl_raise(eSSLError, NULL);
1110
- #else
1111
- /* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to
1112
- * SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */
1113
- {
1114
- VALUE curve, splitted;
1115
- EC_KEY *ec;
1116
- int nid;
1117
-
1118
- splitted = rb_str_split(arg, ":");
1119
- if (!RARRAY_LEN(splitted))
1120
- ossl_raise(eSSLError, "invalid input format");
1121
- curve = RARRAY_AREF(splitted, 0);
1122
- StringValueCStr(curve);
1123
-
1124
- /* SSL_CTX_set1_curves_list() accepts NIST names */
1125
- nid = EC_curve_nist2nid(RSTRING_PTR(curve));
1126
- if (nid == NID_undef)
1127
- nid = OBJ_txt2nid(RSTRING_PTR(curve));
1128
- if (nid == NID_undef)
1129
- ossl_raise(eSSLError, "unknown curve name");
1130
-
1131
- ec = EC_KEY_new_by_curve_name(nid);
1132
- if (!ec)
1133
- ossl_raise(eSSLError, NULL);
1134
- EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
1135
- if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
1136
- EC_KEY_free(ec);
1137
- ossl_raise(eSSLError, "SSL_CTX_set_tmp_ecdh");
1138
- }
1139
- EC_KEY_free(ec);
1140
- # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
1141
- /* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto
1142
- * is enabled. So disable ecdh_auto. */
1143
- if (!SSL_CTX_set_ecdh_auto(ctx, 0))
1144
- ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
1145
- # endif
1146
- }
1147
- #endif
1148
-
1149
1188
  return arg;
1150
1189
  }
1151
1190
  #else
@@ -1236,7 +1275,7 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
1236
1275
 
1237
1276
  /*
1238
1277
  * call-seq:
1239
- * ctx.add_certificate(certiticate, pkey [, extra_certs]) -> self
1278
+ * ctx.add_certificate(certificate, pkey [, extra_certs]) -> self
1240
1279
  *
1241
1280
  * Adds a certificate to the context. _pkey_ must be a corresponding private
1242
1281
  * key with _certificate_.
@@ -1268,10 +1307,6 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
1268
1307
  * ecdsa_pkey = ...
1269
1308
  * another_ca_cert = ...
1270
1309
  * ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])
1271
- *
1272
- * === Note
1273
- * OpenSSL before the version 1.0.2 could handle only one extra chain across
1274
- * all key types. Calling this method discards the chain set previously.
1275
1310
  */
1276
1311
  static VALUE
1277
1312
  ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
@@ -1296,7 +1331,7 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
1296
1331
  EVP_PKEY_free(pub_pkey);
1297
1332
  if (!pub_pkey)
1298
1333
  rb_raise(rb_eArgError, "certificate does not contain public key");
1299
- if (EVP_PKEY_cmp(pub_pkey, pkey) != 1)
1334
+ if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
1300
1335
  rb_raise(rb_eArgError, "public key mismatch");
1301
1336
 
1302
1337
  if (argc >= 3)
@@ -1310,34 +1345,9 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
1310
1345
  sk_X509_pop_free(extra_chain, X509_free);
1311
1346
  ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
1312
1347
  }
1313
-
1314
- if (extra_chain) {
1315
- #if OPENSSL_VERSION_NUMBER >= 0x10002000 && !defined(LIBRESSL_VERSION_NUMBER)
1316
- if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
1317
- sk_X509_pop_free(extra_chain, X509_free);
1318
- ossl_raise(eSSLError, "SSL_CTX_set0_chain");
1319
- }
1320
- #else
1321
- STACK_OF(X509) *orig_extra_chain;
1322
- X509 *x509_tmp;
1323
-
1324
- /* First, clear the existing chain */
1325
- SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
1326
- if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
1327
- rb_warning("SSL_CTX_set0_chain() is not available; " \
1328
- "clearing previously set certificate chain");
1329
- SSL_CTX_clear_extra_chain_certs(ctx);
1330
- }
1331
- while ((x509_tmp = sk_X509_shift(extra_chain))) {
1332
- /* Transfers ownership */
1333
- if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
1334
- X509_free(x509_tmp);
1335
- sk_X509_pop_free(extra_chain, X509_free);
1336
- ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert");
1337
- }
1338
- }
1339
- sk_X509_free(extra_chain);
1340
- #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");
1341
1351
  }
1342
1352
  return self;
1343
1353
  }
@@ -1531,12 +1541,11 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
1531
1541
  /*
1532
1542
  * SSLSocket class
1533
1543
  */
1534
- #ifndef OPENSSL_NO_SOCK
1535
1544
  static inline int
1536
1545
  ssl_started(SSL *ssl)
1537
1546
  {
1538
- /* the FD is set in ossl_ssl_setup(), called by #connect or #accept */
1539
- 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;
1540
1549
  }
1541
1550
 
1542
1551
  static void
@@ -1544,6 +1553,10 @@ ossl_ssl_mark(void *ptr)
1544
1553
  {
1545
1554
  SSL *ssl = ptr;
1546
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.
1547
1560
  rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
1548
1561
  }
1549
1562
 
@@ -1558,7 +1571,7 @@ const rb_data_type_t ossl_ssl_type = {
1558
1571
  {
1559
1572
  ossl_ssl_mark, ossl_ssl_free,
1560
1573
  },
1561
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
1574
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1562
1575
  };
1563
1576
 
1564
1577
  static VALUE
@@ -1567,6 +1580,29 @@ ossl_ssl_s_alloc(VALUE klass)
1567
1580
  return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
1568
1581
  }
1569
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
+
1570
1606
  /*
1571
1607
  * call-seq:
1572
1608
  * SSLSocket.new(io) => aSSLSocket
@@ -1603,6 +1639,7 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1603
1639
 
1604
1640
  if (rb_respond_to(io, rb_intern("nonblock=")))
1605
1641
  rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
1642
+ Check_Type(io, T_FILE);
1606
1643
  rb_ivar_set(self, id_i_io, io);
1607
1644
 
1608
1645
  ssl = SSL_new(ctx);
@@ -1613,6 +1650,8 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1613
1650
  SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
1614
1651
  SSL_set_info_callback(ssl, ssl_info_cb);
1615
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.
1616
1655
  SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
1617
1656
 
1618
1657
  rb_call_super(0, NULL);
@@ -1620,6 +1659,17 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1620
1659
  return self;
1621
1660
  }
1622
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
+
1623
1673
  static VALUE
1624
1674
  ossl_ssl_setup(VALUE self)
1625
1675
  {
@@ -1635,8 +1685,8 @@ ossl_ssl_setup(VALUE self)
1635
1685
  GetOpenFile(io, fptr);
1636
1686
  rb_io_check_readable(fptr);
1637
1687
  rb_io_check_writable(fptr);
1638
- if (!SSL_set_fd(ssl, TO_SOCKET(fptr->fd)))
1639
- 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");
1640
1690
 
1641
1691
  return Qtrue;
1642
1692
  }
@@ -1670,75 +1720,107 @@ no_exception_p(VALUE opts)
1670
1720
  return 0;
1671
1721
  }
1672
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
+
1673
1752
  static VALUE
1674
- 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)
1675
1754
  {
1676
1755
  SSL *ssl;
1677
- rb_io_t *fptr;
1678
1756
  int ret, ret2;
1679
1757
  VALUE cb_state;
1680
1758
  int nonblock = opts != Qfalse;
1681
- #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1682
- unsigned long err;
1683
- #endif
1684
1759
 
1685
1760
  rb_ivar_set(self, ID_callback_state, Qnil);
1686
1761
 
1687
1762
  GetSSL(self, ssl);
1688
1763
 
1689
- GetOpenFile(rb_attr_get(self, id_i_io), fptr);
1690
- for(;;){
1691
- ret = func(ssl);
1764
+ VALUE io = rb_attr_get(self, id_i_io);
1765
+ for (;;) {
1766
+ ret = func(ssl);
1692
1767
 
1693
- cb_state = rb_attr_get(self, ID_callback_state);
1768
+ cb_state = rb_attr_get(self, ID_callback_state);
1694
1769
  if (!NIL_P(cb_state)) {
1695
- /* must cleanup OpenSSL error stack before re-raising */
1696
- ossl_clear_error();
1697
- rb_jump_tag(NUM2INT(cb_state));
1698
- }
1770
+ /* must cleanup OpenSSL error stack before re-raising */
1771
+ ossl_clear_error();
1772
+ rb_jump_tag(NUM2INT(cb_state));
1773
+ }
1699
1774
 
1700
- if (ret > 0)
1701
- break;
1775
+ if (ret > 0)
1776
+ break;
1702
1777
 
1703
- switch((ret2 = ssl_get_error(ssl, ret))){
1704
- case SSL_ERROR_WANT_WRITE:
1778
+ switch ((ret2 = ssl_get_error(ssl, ret))) {
1779
+ case SSL_ERROR_WANT_WRITE:
1705
1780
  if (no_exception_p(opts)) { return sym_wait_writable; }
1706
1781
  write_would_block(nonblock);
1707
- rb_io_wait_writable(fptr->fd);
1782
+ io_wait_writable(io);
1708
1783
  continue;
1709
- case SSL_ERROR_WANT_READ:
1784
+ case SSL_ERROR_WANT_READ:
1710
1785
  if (no_exception_p(opts)) { return sym_wait_readable; }
1711
1786
  read_would_block(nonblock);
1712
- rb_io_wait_readable(fptr->fd);
1787
+ io_wait_readable(io);
1713
1788
  continue;
1714
- case SSL_ERROR_SYSCALL:
1789
+ case SSL_ERROR_SYSCALL:
1715
1790
  #ifdef __APPLE__
1716
1791
  /* See ossl_ssl_write_internal() */
1717
1792
  if (errno == EPROTOTYPE)
1718
1793
  continue;
1719
1794
  #endif
1720
- if (errno) rb_sys_fail(funcname);
1721
- ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1795
+ if (errno) rb_sys_fail(funcname);
1796
+ /* fallthrough */
1797
+ default: {
1798
+ VALUE error_append = Qnil;
1722
1799
  #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1723
- case SSL_ERROR_SSL:
1724
- err = ERR_peek_last_error();
1725
- if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
1726
- ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1727
- const char *err_msg = ERR_reason_error_string(err),
1728
- *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1729
- if (!err_msg)
1730
- err_msg = "(null)";
1731
- if (!verify_msg)
1732
- verify_msg = "(null)";
1733
- ossl_clear_error(); /* let ossl_raise() not append message */
1734
- ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s: %s (%s)",
1735
- funcname, ret2, errno, SSL_state_string_long(ssl),
1736
- err_msg, verify_msg);
1737
- }
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
+ }
1738
1812
  #endif
1739
- default:
1740
- ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1741
- }
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
+ }
1742
1824
  }
1743
1825
 
1744
1826
  return self;
@@ -1748,8 +1830,7 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1748
1830
  * call-seq:
1749
1831
  * ssl.connect => self
1750
1832
  *
1751
- * Initiates an SSL/TLS handshake with a server. The handshake may be started
1752
- * after unencrypted data has been sent over the socket.
1833
+ * Initiates an SSL/TLS handshake with a server.
1753
1834
  */
1754
1835
  static VALUE
1755
1836
  ossl_ssl_connect(VALUE self)
@@ -1796,8 +1877,7 @@ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
1796
1877
  * call-seq:
1797
1878
  * ssl.accept => self
1798
1879
  *
1799
- * Waits for a SSL/TLS client to initiate a handshake. The handshake may be
1800
- * started after unencrypted data has been sent over the socket.
1880
+ * Waits for a SSL/TLS client to initiate a handshake.
1801
1881
  */
1802
1882
  static VALUE
1803
1883
  ossl_ssl_accept(VALUE self)
@@ -1844,16 +1924,18 @@ static VALUE
1844
1924
  ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1845
1925
  {
1846
1926
  SSL *ssl;
1847
- int ilen, nread = 0;
1927
+ int ilen;
1848
1928
  VALUE len, str;
1849
- rb_io_t *fptr;
1850
- VALUE io, opts = Qnil;
1929
+ VALUE opts = Qnil;
1851
1930
 
1852
1931
  if (nonblock) {
1853
1932
  rb_scan_args(argc, argv, "11:", &len, &str, &opts);
1854
1933
  } else {
1855
1934
  rb_scan_args(argc, argv, "11", &len, &str);
1856
1935
  }
1936
+ GetSSL(self, ssl);
1937
+ if (!ssl_started(ssl))
1938
+ rb_raise(eSSLError, "SSL session is not started yet");
1857
1939
 
1858
1940
  ilen = NUM2INT(len);
1859
1941
  if (NIL_P(str))
@@ -1869,85 +1951,59 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1869
1951
  if (ilen == 0)
1870
1952
  return str;
1871
1953
 
1872
- GetSSL(self, ssl);
1873
- io = rb_attr_get(self, id_i_io);
1874
- GetOpenFile(io, fptr);
1875
- if (ssl_started(ssl)) {
1876
- rb_str_locktmp(str);
1877
- for (;;) {
1878
- nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1879
- switch(ssl_get_error(ssl, nread)){
1880
- case SSL_ERROR_NONE:
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) {
1881
1970
  rb_str_unlocktmp(str);
1882
- goto end;
1883
- case SSL_ERROR_ZERO_RETURN:
1971
+ if (no_exception_p(opts)) { return sym_wait_writable; }
1972
+ write_would_block(nonblock);
1973
+ }
1974
+ io_wait_writable(io);
1975
+ continue;
1976
+ case SSL_ERROR_WANT_READ:
1977
+ if (nonblock) {
1884
1978
  rb_str_unlocktmp(str);
1885
- if (no_exception_p(opts)) { return Qnil; }
1886
- rb_eof_error();
1887
- case SSL_ERROR_WANT_WRITE:
1888
- if (nonblock) {
1889
- rb_str_unlocktmp(str);
1890
- if (no_exception_p(opts)) { return sym_wait_writable; }
1891
- write_would_block(nonblock);
1892
- }
1893
- rb_io_wait_writable(fptr->fd);
1894
- continue;
1895
- case SSL_ERROR_WANT_READ:
1896
- if (nonblock) {
1897
- rb_str_unlocktmp(str);
1898
- if (no_exception_p(opts)) { return sym_wait_readable; }
1899
- read_would_block(nonblock);
1900
- }
1901
- rb_io_wait_readable(fptr->fd);
1902
- continue;
1903
- case SSL_ERROR_SYSCALL:
1904
- if (!ERR_peek_error()) {
1905
- rb_str_unlocktmp(str);
1906
- if (errno)
1907
- rb_sys_fail(0);
1908
- else {
1909
- /*
1910
- * The underlying BIO returned 0. This is actually a
1911
- * protocol error. But unfortunately, not all
1912
- * implementations cleanly shutdown the TLS connection
1913
- * but just shutdown/close the TCP connection. So report
1914
- * EOF for now...
1915
- */
1916
- if (no_exception_p(opts)) { return Qnil; }
1917
- rb_eof_error();
1918
- }
1919
- }
1920
- /* fall through */
1921
- default:
1979
+ if (no_exception_p(opts)) { return sym_wait_readable; }
1980
+ read_would_block(nonblock);
1981
+ }
1982
+ io_wait_readable(io);
1983
+ continue;
1984
+ case SSL_ERROR_SYSCALL:
1985
+ if (!ERR_peek_error()) {
1922
1986
  rb_str_unlocktmp(str);
1923
- ossl_raise(eSSLError, "SSL_read");
1924
- }
1925
- }
1926
- }
1927
- else {
1928
- ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
1929
-
1930
- rb_warning("SSL session is not started yet.");
1931
- #if defined(RB_PASS_KEYWORDS)
1932
- if (nonblock) {
1933
- VALUE argv[3];
1934
- argv[0] = len;
1935
- argv[1] = str;
1936
- argv[2] = opts;
1937
- return rb_funcallv_kw(io, meth, 3, argv, RB_PASS_KEYWORDS);
1938
- }
1939
- #else
1940
- if (nonblock) {
1941
- return rb_funcall(io, meth, 3, len, str, opts);
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");
1942
2005
  }
1943
- #endif
1944
- else
1945
- return rb_funcall(io, meth, 2, len, str);
1946
2006
  }
1947
-
1948
- end:
1949
- rb_str_set_len(str, nread);
1950
- return str;
1951
2007
  }
1952
2008
 
1953
2009
  /*
@@ -1987,77 +2043,55 @@ static VALUE
1987
2043
  ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1988
2044
  {
1989
2045
  SSL *ssl;
1990
- int nwrite = 0;
1991
2046
  rb_io_t *fptr;
1992
- int nonblock = opts != Qfalse;
1993
- VALUE tmp, io;
2047
+ int num, nonblock = opts != Qfalse;
2048
+ VALUE tmp;
1994
2049
 
1995
- tmp = rb_str_new_frozen(StringValue(str));
1996
2050
  GetSSL(self, ssl);
1997
- 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);
1998
2056
  GetOpenFile(io, fptr);
1999
- if (ssl_started(ssl)) {
2000
- for (;;) {
2001
- int num = RSTRING_LENINT(tmp);
2002
-
2003
- /* SSL_write(3ssl) manpage states num == 0 is undefined */
2004
- if (num == 0)
2005
- goto end;
2006
-
2007
- nwrite = SSL_write(ssl, RSTRING_PTR(tmp), num);
2008
- switch(ssl_get_error(ssl, nwrite)){
2009
- case SSL_ERROR_NONE:
2010
- goto end;
2011
- case SSL_ERROR_WANT_WRITE:
2012
- if (no_exception_p(opts)) { return sym_wait_writable; }
2013
- write_would_block(nonblock);
2014
- rb_io_wait_writable(fptr->fd);
2015
- continue;
2016
- case SSL_ERROR_WANT_READ:
2017
- if (no_exception_p(opts)) { return sym_wait_readable; }
2018
- read_would_block(nonblock);
2019
- rb_io_wait_readable(fptr->fd);
2020
- continue;
2021
- case SSL_ERROR_SYSCALL:
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:
2022
2079
  #ifdef __APPLE__
2023
- /*
2024
- * It appears that send syscall can return EPROTOTYPE if the
2025
- * socket is being torn down. Retry to get a proper errno to
2026
- * make the error handling in line with the socket library.
2027
- * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
2028
- */
2029
- if (errno == EPROTOTYPE)
2030
- continue;
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)
2087
+ continue;
2031
2088
  #endif
2032
- if (errno) rb_sys_fail(0);
2033
- default:
2034
- ossl_raise(eSSLError, "SSL_write");
2035
- }
2089
+ if (errno) rb_sys_fail(0);
2090
+ /* fallthrough */
2091
+ default:
2092
+ ossl_raise(eSSLError, "SSL_write");
2036
2093
  }
2037
2094
  }
2038
- else {
2039
- ID meth = nonblock ?
2040
- rb_intern("write_nonblock") : rb_intern("syswrite");
2041
-
2042
- rb_warning("SSL session is not started yet.");
2043
- #if defined(RB_PASS_KEYWORDS)
2044
- if (nonblock) {
2045
- VALUE argv[2];
2046
- argv[0] = str;
2047
- argv[1] = opts;
2048
- return rb_funcallv_kw(io, meth, 2, argv, RB_PASS_KEYWORDS);
2049
- }
2050
- #else
2051
- if (nonblock) {
2052
- return rb_funcall(io, meth, 2, str, opts);
2053
- }
2054
- #endif
2055
- else
2056
- return rb_funcall(io, meth, 1, str);
2057
- }
2058
-
2059
- end:
2060
- return INT2NUM(nwrite);
2061
2095
  }
2062
2096
 
2063
2097
  /*
@@ -2432,7 +2466,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
2432
2466
  return ossl_x509name_sk2ary(ca);
2433
2467
  }
2434
2468
 
2435
- # ifndef OPENSSL_NO_NEXTPROTONEG
2469
+ # ifdef OSSL_USE_NEXTPROTONEG
2436
2470
  /*
2437
2471
  * call-seq:
2438
2472
  * ssl.npn_protocol => String | nil
@@ -2457,7 +2491,6 @@ ossl_ssl_npn_protocol(VALUE self)
2457
2491
  }
2458
2492
  # endif
2459
2493
 
2460
- # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2461
2494
  /*
2462
2495
  * call-seq:
2463
2496
  * ssl.alpn_protocol => String | nil
@@ -2480,9 +2513,50 @@ ossl_ssl_alpn_protocol(VALUE self)
2480
2513
  else
2481
2514
  return rb_str_new((const char *) out, outlen);
2482
2515
  }
2483
- # endif
2484
2516
 
2485
- # 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
+
2486
2560
  /*
2487
2561
  * call-seq:
2488
2562
  * ssl.tmp_key => PKey or nil
@@ -2500,7 +2574,6 @@ ossl_ssl_tmp_key(VALUE self)
2500
2574
  return Qnil;
2501
2575
  return ossl_pkey_new(key);
2502
2576
  }
2503
- # endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */
2504
2577
  #endif /* !defined(OPENSSL_NO_SOCK) */
2505
2578
 
2506
2579
  void
@@ -2513,6 +2586,7 @@ Init_ossl_ssl(void)
2513
2586
  rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
2514
2587
  #endif
2515
2588
 
2589
+ #ifndef OPENSSL_NO_SOCK
2516
2590
  id_call = rb_intern_const("call");
2517
2591
  ID_callback_state = rb_intern_const("callback_state");
2518
2592
 
@@ -2525,11 +2599,6 @@ Init_ossl_ssl(void)
2525
2599
  ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2526
2600
  if (ossl_sslctx_ex_ptr_idx < 0)
2527
2601
  ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2528
- #if !defined(HAVE_X509_STORE_UP_REF)
2529
- ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_store_p", 0, 0, 0);
2530
- if (ossl_sslctx_ex_store_p < 0)
2531
- ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2532
- #endif
2533
2602
 
2534
2603
  /* Document-module: OpenSSL::SSL
2535
2604
  *
@@ -2540,16 +2609,6 @@ Init_ossl_ssl(void)
2540
2609
  */
2541
2610
  mSSL = rb_define_module_under(mOSSL, "SSL");
2542
2611
 
2543
- /* Document-module: OpenSSL::ExtConfig
2544
- *
2545
- * This module contains configuration information about the SSL extension,
2546
- * for example if socket support is enabled, or the host name TLS extension
2547
- * is enabled. Constants in this module will always be defined, but contain
2548
- * +true+ or +false+ values depending on the configuration of your OpenSSL
2549
- * installation.
2550
- */
2551
- mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig");
2552
-
2553
2612
  /* Document-class: OpenSSL::SSL::SSLError
2554
2613
  *
2555
2614
  * Generic error class raised by SSLSocket and SSLContext.
@@ -2677,20 +2736,6 @@ Init_ossl_ssl(void)
2677
2736
  */
2678
2737
  rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
2679
2738
 
2680
- #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
2681
- /*
2682
- * A callback invoked when ECDH parameters are required.
2683
- *
2684
- * The callback is invoked with the Session for the key exchange, an
2685
- * flag indicating the use of an export cipher and the keylength
2686
- * required.
2687
- *
2688
- * The callback is deprecated. This does not work with recent versions of
2689
- * OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead.
2690
- */
2691
- rb_attr(cSSLContext, rb_intern_const("tmp_ecdh_callback"), 1, 1, Qfalse);
2692
- #endif
2693
-
2694
2739
  /*
2695
2740
  * Sets the context in which a session can be reused. This allows
2696
2741
  * sessions for multiple applications to be distinguished, for example, by
@@ -2726,8 +2771,6 @@ Init_ossl_ssl(void)
2726
2771
  */
2727
2772
  rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
2728
2773
 
2729
- rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
2730
-
2731
2774
  /*
2732
2775
  * A callback invoked whenever a new handshake is initiated on an
2733
2776
  * established connection. May be used to disable renegotiation entirely.
@@ -2748,7 +2791,7 @@ Init_ossl_ssl(void)
2748
2791
  * end
2749
2792
  */
2750
2793
  rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
2751
- #ifndef OPENSSL_NO_NEXTPROTONEG
2794
+ #ifdef OSSL_USE_NEXTPROTONEG
2752
2795
  /*
2753
2796
  * An Enumerable of Strings. Each String represents a protocol to be
2754
2797
  * advertised as the list of supported protocols for Next Protocol
@@ -2780,7 +2823,6 @@ Init_ossl_ssl(void)
2780
2823
  rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse);
2781
2824
  #endif
2782
2825
 
2783
- #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2784
2826
  /*
2785
2827
  * An Enumerable of Strings. Each String represents a protocol to be
2786
2828
  * advertised as the list of supported protocols for Application-Layer
@@ -2810,7 +2852,29 @@ Init_ossl_ssl(void)
2810
2852
  * end
2811
2853
  */
2812
2854
  rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
2813
- #endif
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);
2814
2878
 
2815
2879
  rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2816
2880
  rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
@@ -2818,6 +2882,12 @@ Init_ossl_ssl(void)
2818
2882
  ossl_sslctx_set_minmax_proto_version, 2);
2819
2883
  rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2820
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
2821
2891
  rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
2822
2892
  rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
2823
2893
  rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
@@ -2891,11 +2961,6 @@ Init_ossl_ssl(void)
2891
2961
  * Document-class: OpenSSL::SSL::SSLSocket
2892
2962
  */
2893
2963
  cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
2894
- #ifdef OPENSSL_NO_SOCK
2895
- rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue);
2896
- rb_define_method(cSSLSocket, "initialize", rb_f_notimplement, -1);
2897
- #else
2898
- rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse);
2899
2964
  rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
2900
2965
  rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
2901
2966
  rb_undef_method(cSSLSocket, "initialize_copy");
@@ -2924,16 +2989,12 @@ Init_ossl_ssl(void)
2924
2989
  rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
2925
2990
  rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0);
2926
2991
  rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
2927
- # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2928
2992
  rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
2929
- # endif
2930
- # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2931
2993
  rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
2932
- # endif
2933
- # ifndef OPENSSL_NO_NEXTPROTONEG
2994
+ rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1);
2995
+ # ifdef OSSL_USE_NEXTPROTONEG
2934
2996
  rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2935
2997
  # endif
2936
- #endif
2937
2998
 
2938
2999
  rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
2939
3000
  rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
@@ -2941,12 +3002,23 @@ Init_ossl_ssl(void)
2941
3002
  rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
2942
3003
 
2943
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
2944
3008
  rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
2945
- #ifdef SSL_OP_TLSEXT_PADDING /* OpenSSL 1.0.1h and OpenSSL 1.0.2 */
2946
- 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));
2947
3011
  #endif
2948
- #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));
2949
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));
2950
3022
  #endif
2951
3023
  #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
2952
3024
  rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
@@ -2959,13 +3031,15 @@ Init_ossl_ssl(void)
2959
3031
  #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
2960
3032
  rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
2961
3033
  #endif
2962
- rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
2963
- rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
2964
- #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
2965
- 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));
2966
3042
  #endif
2967
- rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
2968
-
2969
3043
  rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
2970
3044
  rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
2971
3045
  rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
@@ -2973,6 +3047,12 @@ Init_ossl_ssl(void)
2973
3047
  #ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
2974
3048
  rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
2975
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));
2976
3056
 
2977
3057
  /* SSL_OP_* flags for DTLS */
2978
3058
  #if 0
@@ -3042,7 +3122,6 @@ Init_ossl_ssl(void)
3042
3122
  sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
3043
3123
 
3044
3124
  id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
3045
- id_tmp_ecdh_callback = rb_intern_const("tmp_ecdh_callback");
3046
3125
  id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
3047
3126
  id_each = rb_intern_const("each");
3048
3127
 
@@ -3061,7 +3140,6 @@ Init_ossl_ssl(void)
3061
3140
  DefIVarID(key);
3062
3141
  DefIVarID(extra_chain_cert);
3063
3142
  DefIVarID(client_cert_cb);
3064
- DefIVarID(tmp_ecdh_callback);
3065
3143
  DefIVarID(timeout);
3066
3144
  DefIVarID(session_id_context);
3067
3145
  DefIVarID(session_get_cb);
@@ -3073,8 +3151,10 @@ Init_ossl_ssl(void)
3073
3151
  DefIVarID(alpn_select_cb);
3074
3152
  DefIVarID(servername_cb);
3075
3153
  DefIVarID(verify_hostname);
3154
+ DefIVarID(keylog_cb);
3076
3155
 
3077
3156
  DefIVarID(io);
3078
3157
  DefIVarID(context);
3079
3158
  DefIVarID(hostname);
3159
+ #endif /* !defined(OPENSSL_NO_SOCK) */
3080
3160
  }