openssl 2.1.3 → 3.1.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +302 -1
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +77 -62
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +59 -43
  8. data/ext/openssl/ossl.c +110 -64
  9. data/ext/openssl/ossl.h +33 -10
  10. data/ext/openssl/ossl_asn1.c +51 -13
  11. data/ext/openssl/ossl_bn.c +275 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +39 -31
  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 +25 -60
  17. data/ext/openssl/ossl_engine.c +18 -27
  18. data/ext/openssl/ossl_hmac.c +60 -145
  19. data/ext/openssl/ossl_kdf.c +14 -22
  20. data/ext/openssl/ossl_ns_spki.c +1 -1
  21. data/ext/openssl/ossl_ocsp.c +11 -64
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +21 -3
  24. data/ext/openssl/ossl_pkcs7.c +45 -78
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1295 -178
  27. data/ext/openssl/ossl_pkey.h +36 -73
  28. data/ext/openssl/ossl_pkey_dh.c +130 -340
  29. data/ext/openssl/ossl_pkey_dsa.c +100 -405
  30. data/ext/openssl/ossl_pkey_ec.c +192 -335
  31. data/ext/openssl/ossl_pkey_rsa.c +110 -489
  32. data/ext/openssl/ossl_rand.c +2 -32
  33. data/ext/openssl/ossl_ssl.c +556 -442
  34. data/ext/openssl/ossl_ssl_session.c +28 -29
  35. data/ext/openssl/ossl_ts.c +1539 -0
  36. data/ext/openssl/ossl_ts.h +16 -0
  37. data/ext/openssl/ossl_x509.c +0 -6
  38. data/ext/openssl/ossl_x509cert.c +169 -13
  39. data/ext/openssl/ossl_x509crl.c +13 -10
  40. data/ext/openssl/ossl_x509ext.c +15 -2
  41. data/ext/openssl/ossl_x509name.c +15 -4
  42. data/ext/openssl/ossl_x509req.c +13 -10
  43. data/ext/openssl/ossl_x509revoked.c +3 -3
  44. data/ext/openssl/ossl_x509store.c +154 -70
  45. data/lib/openssl/bn.rb +1 -1
  46. data/lib/openssl/buffering.rb +37 -5
  47. data/lib/openssl/cipher.rb +1 -1
  48. data/lib/openssl/digest.rb +10 -12
  49. data/lib/openssl/hmac.rb +78 -0
  50. data/lib/openssl/marshal.rb +30 -0
  51. data/lib/openssl/pkcs5.rb +1 -1
  52. data/lib/openssl/pkey.rb +447 -1
  53. data/lib/openssl/ssl.rb +52 -9
  54. data/lib/openssl/version.rb +5 -0
  55. data/lib/openssl/x509.rb +177 -1
  56. data/lib/openssl.rb +24 -9
  57. metadata +10 -79
  58. data/ext/openssl/deprecation.rb +0 -27
  59. data/ext/openssl/ossl_version.h +0 -15
  60. data/ext/openssl/ruby_missing.h +0 -24
  61. data/lib/openssl/config.rb +0 -492
@@ -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 = {
@@ -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,41 +820,15 @@ 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 */
823
+ #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
824
+ SSL_CTX_set_post_handshake_auth(ctx, 1);
825
+ #endif
832
826
 
833
827
  val = rb_attr_get(self, id_i_cert_store);
834
828
  if (!NIL_P(val)) {
835
829
  X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
836
830
  SSL_CTX_set_cert_store(ctx, store);
837
- #if !defined(HAVE_X509_STORE_UP_REF)
838
- /*
839
- * WORKAROUND:
840
- * X509_STORE can count references, but
841
- * X509_STORE_free() doesn't care it.
842
- * So we won't increment it but mark it by ex_data.
843
- */
844
- SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
845
- #else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
846
831
  X509_STORE_up_ref(store);
847
- #endif
848
832
  }
849
833
 
850
834
  val = rb_attr_get(self, id_i_extra_chain_cert);
@@ -895,10 +879,17 @@ ossl_sslctx_setup(VALUE self)
895
879
  ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
896
880
  val = rb_attr_get(self, id_i_ca_path);
897
881
  ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
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
898
888
  if(ca_file || ca_path){
899
889
  if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
900
890
  rb_warning("can't set verify locations");
901
891
  }
892
+ #endif
902
893
 
903
894
  val = rb_attr_get(self, id_i_verify_mode);
904
895
  verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
@@ -912,7 +903,7 @@ ossl_sslctx_setup(VALUE self)
912
903
  val = rb_attr_get(self, id_i_verify_depth);
913
904
  if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
914
905
 
915
- #ifndef OPENSSL_NO_NEXTPROTONEG
906
+ #ifdef OSSL_USE_NEXTPROTONEG
916
907
  val = rb_attr_get(self, id_i_npn_protocols);
917
908
  if (!NIL_P(val)) {
918
909
  VALUE encoded = ssl_encode_npn_protocols(val);
@@ -926,7 +917,6 @@ ossl_sslctx_setup(VALUE self)
926
917
  }
927
918
  #endif
928
919
 
929
- #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
930
920
  val = rb_attr_get(self, id_i_alpn_protocols);
931
921
  if (!NIL_P(val)) {
932
922
  VALUE rprotos = ssl_encode_npn_protocols(val);
@@ -941,7 +931,6 @@ ossl_sslctx_setup(VALUE self)
941
931
  SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
942
932
  OSSL_Debug("SSL ALPN select callback added");
943
933
  }
944
- #endif
945
934
 
946
935
  rb_obj_freeze(self);
947
936
 
@@ -973,6 +962,18 @@ ossl_sslctx_setup(VALUE self)
973
962
  OSSL_Debug("SSL TLSEXT servername callback added");
974
963
  }
975
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
+
976
977
  return Qtrue;
977
978
  }
978
979
 
@@ -1021,27 +1022,13 @@ ossl_sslctx_get_ciphers(VALUE self)
1021
1022
  return ary;
1022
1023
  }
1023
1024
 
1024
- /*
1025
- * call-seq:
1026
- * ctx.ciphers = "cipher1:cipher2:..."
1027
- * ctx.ciphers = [name, ...]
1028
- * ctx.ciphers = [[name, version, bits, alg_bits], ...]
1029
- *
1030
- * Sets the list of available cipher suites for this context. Note in a server
1031
- * context some ciphers require the appropriate certificates. For example, an
1032
- * RSA cipher suite can only be chosen when an RSA certificate is available.
1033
- */
1034
1025
  static VALUE
1035
- ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1026
+ build_cipher_string(VALUE v)
1036
1027
  {
1037
- SSL_CTX *ctx;
1038
1028
  VALUE str, elem;
1039
1029
  int i;
1040
1030
 
1041
- rb_check_frozen(self);
1042
- if (NIL_P(v))
1043
- return v;
1044
- else if (RB_TYPE_P(v, T_ARRAY)) {
1031
+ if (RB_TYPE_P(v, T_ARRAY)) {
1045
1032
  str = rb_str_new(0, 0);
1046
1033
  for (i = 0; i < RARRAY_LEN(v); i++) {
1047
1034
  elem = rb_ary_entry(v, i);
@@ -1055,14 +1042,113 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1055
1042
  StringValue(str);
1056
1043
  }
1057
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
+
1058
1070
  GetSSLCTX(self, ctx);
1059
- if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) {
1071
+ if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
1060
1072
  ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
1061
- }
1062
1073
 
1063
1074
  return v;
1064
1075
  }
1065
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
+
1066
1152
  #if !defined(OPENSSL_NO_EC)
1067
1153
  /*
1068
1154
  * call-seq:
@@ -1074,9 +1160,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1074
1160
  * Extension. For a server, the list is used by OpenSSL to determine the set of
1075
1161
  * shared curves. OpenSSL will pick the most appropriate one from it.
1076
1162
  *
1077
- * Note that this works differently with old OpenSSL (<= 1.0.1). Only one curve
1078
- * can be set, and this has no effect for TLS clients.
1079
- *
1080
1163
  * === Example
1081
1164
  * ctx1 = OpenSSL::SSL::SSLContext.new
1082
1165
  * ctx1.ecdh_curves = "X25519:P-256:P-224"
@@ -1100,48 +1183,8 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
1100
1183
  GetSSLCTX(self, ctx);
1101
1184
  StringValueCStr(arg);
1102
1185
 
1103
- #if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
1104
1186
  if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
1105
1187
  ossl_raise(eSSLError, NULL);
1106
- #else
1107
- /* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to
1108
- * SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */
1109
- {
1110
- VALUE curve, splitted;
1111
- EC_KEY *ec;
1112
- int nid;
1113
-
1114
- splitted = rb_str_split(arg, ":");
1115
- if (!RARRAY_LEN(splitted))
1116
- ossl_raise(eSSLError, "invalid input format");
1117
- curve = RARRAY_AREF(splitted, 0);
1118
- StringValueCStr(curve);
1119
-
1120
- /* SSL_CTX_set1_curves_list() accepts NIST names */
1121
- nid = EC_curve_nist2nid(RSTRING_PTR(curve));
1122
- if (nid == NID_undef)
1123
- nid = OBJ_txt2nid(RSTRING_PTR(curve));
1124
- if (nid == NID_undef)
1125
- ossl_raise(eSSLError, "unknown curve name");
1126
-
1127
- ec = EC_KEY_new_by_curve_name(nid);
1128
- if (!ec)
1129
- ossl_raise(eSSLError, NULL);
1130
- EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
1131
- if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
1132
- EC_KEY_free(ec);
1133
- ossl_raise(eSSLError, "SSL_CTX_set_tmp_ecdh");
1134
- }
1135
- EC_KEY_free(ec);
1136
- # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
1137
- /* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto
1138
- * is enabled. So disable ecdh_auto. */
1139
- if (!SSL_CTX_set_ecdh_auto(ctx, 0))
1140
- ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
1141
- # endif
1142
- }
1143
- #endif
1144
-
1145
1188
  return arg;
1146
1189
  }
1147
1190
  #else
@@ -1232,7 +1275,7 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
1232
1275
 
1233
1276
  /*
1234
1277
  * call-seq:
1235
- * ctx.add_certificate(certiticate, pkey [, extra_certs]) -> self
1278
+ * ctx.add_certificate(certificate, pkey [, extra_certs]) -> self
1236
1279
  *
1237
1280
  * Adds a certificate to the context. _pkey_ must be a corresponding private
1238
1281
  * key with _certificate_.
@@ -1264,10 +1307,6 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
1264
1307
  * ecdsa_pkey = ...
1265
1308
  * another_ca_cert = ...
1266
1309
  * ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])
1267
- *
1268
- * === Note
1269
- * OpenSSL before the version 1.0.2 could handle only one extra chain across
1270
- * all key types. Calling this method discards the chain set previously.
1271
1310
  */
1272
1311
  static VALUE
1273
1312
  ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
@@ -1292,7 +1331,7 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
1292
1331
  EVP_PKEY_free(pub_pkey);
1293
1332
  if (!pub_pkey)
1294
1333
  rb_raise(rb_eArgError, "certificate does not contain public key");
1295
- if (EVP_PKEY_cmp(pub_pkey, pkey) != 1)
1334
+ if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
1296
1335
  rb_raise(rb_eArgError, "public key mismatch");
1297
1336
 
1298
1337
  if (argc >= 3)
@@ -1306,34 +1345,9 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
1306
1345
  sk_X509_pop_free(extra_chain, X509_free);
1307
1346
  ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
1308
1347
  }
1309
-
1310
- if (extra_chain) {
1311
- #if OPENSSL_VERSION_NUMBER >= 0x10002000 && !defined(LIBRESSL_VERSION_NUMBER)
1312
- if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
1313
- sk_X509_pop_free(extra_chain, X509_free);
1314
- ossl_raise(eSSLError, "SSL_CTX_set0_chain");
1315
- }
1316
- #else
1317
- STACK_OF(X509) *orig_extra_chain;
1318
- X509 *x509_tmp;
1319
-
1320
- /* First, clear the existing chain */
1321
- SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
1322
- if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
1323
- rb_warning("SSL_CTX_set0_chain() is not available; " \
1324
- "clearing previously set certificate chain");
1325
- SSL_CTX_clear_extra_chain_certs(ctx);
1326
- }
1327
- while ((x509_tmp = sk_X509_shift(extra_chain))) {
1328
- /* Transfers ownership */
1329
- if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
1330
- X509_free(x509_tmp);
1331
- sk_X509_pop_free(extra_chain, X509_free);
1332
- ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert");
1333
- }
1334
- }
1335
- sk_X509_free(extra_chain);
1336
- #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");
1337
1351
  }
1338
1352
  return self;
1339
1353
  }
@@ -1527,12 +1541,11 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
1527
1541
  /*
1528
1542
  * SSLSocket class
1529
1543
  */
1530
- #ifndef OPENSSL_NO_SOCK
1531
1544
  static inline int
1532
1545
  ssl_started(SSL *ssl)
1533
1546
  {
1534
- /* the FD is set in ossl_ssl_setup(), called by #connect or #accept */
1535
- 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;
1536
1549
  }
1537
1550
 
1538
1551
  static void
@@ -1563,6 +1576,29 @@ ossl_ssl_s_alloc(VALUE klass)
1563
1576
  return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
1564
1577
  }
1565
1578
 
1579
+ static VALUE
1580
+ peer_ip_address(VALUE self)
1581
+ {
1582
+ VALUE remote_address = rb_funcall(rb_attr_get(self, id_i_io), rb_intern("remote_address"), 0);
1583
+
1584
+ return rb_funcall(remote_address, rb_intern("inspect_sockaddr"), 0);
1585
+ }
1586
+
1587
+ static VALUE
1588
+ fallback_peer_ip_address(VALUE self, VALUE args)
1589
+ {
1590
+ return rb_str_new_cstr("(null)");
1591
+ }
1592
+
1593
+ static VALUE
1594
+ peeraddr_ip_str(VALUE self)
1595
+ {
1596
+ VALUE rb_mErrno = rb_const_get(rb_cObject, rb_intern("Errno"));
1597
+ VALUE rb_eSystemCallError = rb_const_get(rb_mErrno, rb_intern("SystemCallError"));
1598
+
1599
+ return rb_rescue2(peer_ip_address, self, fallback_peer_ip_address, (VALUE)0, rb_eSystemCallError, NULL);
1600
+ }
1601
+
1566
1602
  /*
1567
1603
  * call-seq:
1568
1604
  * SSLSocket.new(io) => aSSLSocket
@@ -1599,6 +1635,7 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1599
1635
 
1600
1636
  if (rb_respond_to(io, rb_intern("nonblock=")))
1601
1637
  rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
1638
+ Check_Type(io, T_FILE);
1602
1639
  rb_ivar_set(self, id_i_io, io);
1603
1640
 
1604
1641
  ssl = SSL_new(ctx);
@@ -1666,8 +1703,33 @@ no_exception_p(VALUE opts)
1666
1703
  return 0;
1667
1704
  }
1668
1705
 
1706
+ // Provided by Ruby 3.2.0 and later in order to support the default IO#timeout.
1707
+ #ifndef RUBY_IO_TIMEOUT_DEFAULT
1708
+ #define RUBY_IO_TIMEOUT_DEFAULT Qnil
1709
+ #endif
1710
+
1711
+ static void
1712
+ io_wait_writable(rb_io_t *fptr)
1713
+ {
1714
+ #ifdef HAVE_RB_IO_MAYBE_WAIT
1715
+ rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT);
1716
+ #else
1717
+ rb_io_wait_writable(fptr->fd);
1718
+ #endif
1719
+ }
1720
+
1721
+ static void
1722
+ io_wait_readable(rb_io_t *fptr)
1723
+ {
1724
+ #ifdef HAVE_RB_IO_MAYBE_WAIT
1725
+ rb_io_maybe_wait_readable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT);
1726
+ #else
1727
+ rb_io_wait_readable(fptr->fd);
1728
+ #endif
1729
+ }
1730
+
1669
1731
  static VALUE
1670
- ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1732
+ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
1671
1733
  {
1672
1734
  SSL *ssl;
1673
1735
  rb_io_t *fptr;
@@ -1700,12 +1762,12 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1700
1762
  case SSL_ERROR_WANT_WRITE:
1701
1763
  if (no_exception_p(opts)) { return sym_wait_writable; }
1702
1764
  write_would_block(nonblock);
1703
- rb_io_wait_writable(fptr->fd);
1765
+ io_wait_writable(fptr);
1704
1766
  continue;
1705
1767
  case SSL_ERROR_WANT_READ:
1706
1768
  if (no_exception_p(opts)) { return sym_wait_readable; }
1707
1769
  read_would_block(nonblock);
1708
- rb_io_wait_readable(fptr->fd);
1770
+ io_wait_readable(fptr);
1709
1771
  continue;
1710
1772
  case SSL_ERROR_SYSCALL:
1711
1773
  #ifdef __APPLE__
@@ -1714,7 +1776,9 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1714
1776
  continue;
1715
1777
  #endif
1716
1778
  if (errno) rb_sys_fail(funcname);
1717
- ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1779
+ ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
1780
+ funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
1781
+
1718
1782
  #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1719
1783
  case SSL_ERROR_SSL:
1720
1784
  err = ERR_peek_last_error();
@@ -1727,13 +1791,15 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1727
1791
  if (!verify_msg)
1728
1792
  verify_msg = "(null)";
1729
1793
  ossl_clear_error(); /* let ossl_raise() not append message */
1730
- ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s: %s (%s)",
1731
- funcname, ret2, errno, SSL_state_string_long(ssl),
1794
+ ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s: %s (%s)",
1795
+ funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl),
1732
1796
  err_msg, verify_msg);
1733
1797
  }
1734
1798
  #endif
1799
+ /* fallthrough */
1735
1800
  default:
1736
- ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1801
+ ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
1802
+ funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
1737
1803
  }
1738
1804
  }
1739
1805
 
@@ -1744,8 +1810,7 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1744
1810
  * call-seq:
1745
1811
  * ssl.connect => self
1746
1812
  *
1747
- * Initiates an SSL/TLS handshake with a server. The handshake may be started
1748
- * after unencrypted data has been sent over the socket.
1813
+ * Initiates an SSL/TLS handshake with a server.
1749
1814
  */
1750
1815
  static VALUE
1751
1816
  ossl_ssl_connect(VALUE self)
@@ -1792,8 +1857,7 @@ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
1792
1857
  * call-seq:
1793
1858
  * ssl.accept => self
1794
1859
  *
1795
- * Waits for a SSL/TLS client to initiate a handshake. The handshake may be
1796
- * started after unencrypted data has been sent over the socket.
1860
+ * Waits for a SSL/TLS client to initiate a handshake.
1797
1861
  */
1798
1862
  static VALUE
1799
1863
  ossl_ssl_accept(VALUE self)
@@ -1840,7 +1904,7 @@ static VALUE
1840
1904
  ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1841
1905
  {
1842
1906
  SSL *ssl;
1843
- int ilen, nread = 0;
1907
+ int ilen;
1844
1908
  VALUE len, str;
1845
1909
  rb_io_t *fptr;
1846
1910
  VALUE io, opts = Qnil;
@@ -1850,6 +1914,9 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1850
1914
  } else {
1851
1915
  rb_scan_args(argc, argv, "11", &len, &str);
1852
1916
  }
1917
+ GetSSL(self, ssl);
1918
+ if (!ssl_started(ssl))
1919
+ rb_raise(eSSLError, "SSL session is not started yet");
1853
1920
 
1854
1921
  ilen = NUM2INT(len);
1855
1922
  if (NIL_P(str))
@@ -1865,85 +1932,60 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1865
1932
  if (ilen == 0)
1866
1933
  return str;
1867
1934
 
1868
- GetSSL(self, ssl);
1869
1935
  io = rb_attr_get(self, id_i_io);
1870
1936
  GetOpenFile(io, fptr);
1871
- if (ssl_started(ssl)) {
1872
- rb_str_locktmp(str);
1873
- for (;;) {
1874
- nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1875
- switch(ssl_get_error(ssl, nread)){
1876
- case SSL_ERROR_NONE:
1937
+
1938
+ rb_str_locktmp(str);
1939
+ for (;;) {
1940
+ int nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1941
+ switch (ssl_get_error(ssl, nread)) {
1942
+ case SSL_ERROR_NONE:
1943
+ rb_str_unlocktmp(str);
1944
+ rb_str_set_len(str, nread);
1945
+ return str;
1946
+ case SSL_ERROR_ZERO_RETURN:
1947
+ rb_str_unlocktmp(str);
1948
+ if (no_exception_p(opts)) { return Qnil; }
1949
+ rb_eof_error();
1950
+ case SSL_ERROR_WANT_WRITE:
1951
+ if (nonblock) {
1877
1952
  rb_str_unlocktmp(str);
1878
- goto end;
1879
- case SSL_ERROR_ZERO_RETURN:
1953
+ if (no_exception_p(opts)) { return sym_wait_writable; }
1954
+ write_would_block(nonblock);
1955
+ }
1956
+ io_wait_writable(fptr);
1957
+ continue;
1958
+ case SSL_ERROR_WANT_READ:
1959
+ if (nonblock) {
1880
1960
  rb_str_unlocktmp(str);
1881
- if (no_exception_p(opts)) { return Qnil; }
1882
- rb_eof_error();
1883
- case SSL_ERROR_WANT_WRITE:
1884
- if (nonblock) {
1885
- rb_str_unlocktmp(str);
1886
- if (no_exception_p(opts)) { return sym_wait_writable; }
1887
- write_would_block(nonblock);
1888
- }
1889
- rb_io_wait_writable(fptr->fd);
1890
- continue;
1891
- case SSL_ERROR_WANT_READ:
1892
- if (nonblock) {
1893
- rb_str_unlocktmp(str);
1894
- if (no_exception_p(opts)) { return sym_wait_readable; }
1895
- read_would_block(nonblock);
1896
- }
1897
- rb_io_wait_readable(fptr->fd);
1898
- continue;
1899
- case SSL_ERROR_SYSCALL:
1900
- if (!ERR_peek_error()) {
1901
- rb_str_unlocktmp(str);
1902
- if (errno)
1903
- rb_sys_fail(0);
1904
- else {
1905
- /*
1906
- * The underlying BIO returned 0. This is actually a
1907
- * protocol error. But unfortunately, not all
1908
- * implementations cleanly shutdown the TLS connection
1909
- * but just shutdown/close the TCP connection. So report
1910
- * EOF for now...
1911
- */
1912
- if (no_exception_p(opts)) { return Qnil; }
1913
- rb_eof_error();
1914
- }
1915
- }
1916
- /* fall through */
1917
- default:
1961
+ if (no_exception_p(opts)) { return sym_wait_readable; }
1962
+ read_would_block(nonblock);
1963
+ }
1964
+ io_wait_readable(fptr);
1965
+ continue;
1966
+ case SSL_ERROR_SYSCALL:
1967
+ if (!ERR_peek_error()) {
1918
1968
  rb_str_unlocktmp(str);
1919
- ossl_raise(eSSLError, "SSL_read");
1920
- }
1921
- }
1922
- }
1923
- else {
1924
- ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
1925
-
1926
- rb_warning("SSL session is not started yet.");
1927
- #if defined(RB_PASS_KEYWORDS)
1928
- if (nonblock) {
1929
- VALUE argv[3];
1930
- argv[0] = len;
1931
- argv[1] = str;
1932
- argv[2] = opts;
1933
- return rb_funcallv_kw(io, meth, 3, argv, RB_PASS_KEYWORDS);
1934
- }
1935
- #else
1936
- if (nonblock) {
1937
- return rb_funcall(io, meth, 3, len, str, opts);
1969
+ if (errno)
1970
+ rb_sys_fail(0);
1971
+ else {
1972
+ /*
1973
+ * The underlying BIO returned 0. This is actually a
1974
+ * protocol error. But unfortunately, not all
1975
+ * implementations cleanly shutdown the TLS connection
1976
+ * but just shutdown/close the TCP connection. So report
1977
+ * EOF for now...
1978
+ */
1979
+ if (no_exception_p(opts)) { return Qnil; }
1980
+ rb_eof_error();
1981
+ }
1982
+ }
1983
+ /* fall through */
1984
+ default:
1985
+ rb_str_unlocktmp(str);
1986
+ ossl_raise(eSSLError, "SSL_read");
1938
1987
  }
1939
- #endif
1940
- else
1941
- return rb_funcall(io, meth, 2, len, str);
1942
1988
  }
1943
-
1944
- end:
1945
- rb_str_set_len(str, nread);
1946
- return str;
1947
1989
  }
1948
1990
 
1949
1991
  /*
@@ -1983,77 +2025,55 @@ static VALUE
1983
2025
  ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1984
2026
  {
1985
2027
  SSL *ssl;
1986
- int nwrite = 0;
1987
2028
  rb_io_t *fptr;
1988
- int nonblock = opts != Qfalse;
2029
+ int num, nonblock = opts != Qfalse;
1989
2030
  VALUE tmp, io;
1990
2031
 
1991
- tmp = rb_str_new_frozen(StringValue(str));
1992
2032
  GetSSL(self, ssl);
2033
+ if (!ssl_started(ssl))
2034
+ rb_raise(eSSLError, "SSL session is not started yet");
2035
+
2036
+ tmp = rb_str_new_frozen(StringValue(str));
1993
2037
  io = rb_attr_get(self, id_i_io);
1994
2038
  GetOpenFile(io, fptr);
1995
- if (ssl_started(ssl)) {
1996
- for (;;) {
1997
- int num = RSTRING_LENINT(tmp);
1998
-
1999
- /* SSL_write(3ssl) manpage states num == 0 is undefined */
2000
- if (num == 0)
2001
- goto end;
2002
-
2003
- nwrite = SSL_write(ssl, RSTRING_PTR(tmp), num);
2004
- switch(ssl_get_error(ssl, nwrite)){
2005
- case SSL_ERROR_NONE:
2006
- goto end;
2007
- case SSL_ERROR_WANT_WRITE:
2008
- if (no_exception_p(opts)) { return sym_wait_writable; }
2009
- write_would_block(nonblock);
2010
- rb_io_wait_writable(fptr->fd);
2011
- continue;
2012
- case SSL_ERROR_WANT_READ:
2013
- if (no_exception_p(opts)) { return sym_wait_readable; }
2014
- read_would_block(nonblock);
2015
- rb_io_wait_readable(fptr->fd);
2016
- continue;
2017
- case SSL_ERROR_SYSCALL:
2039
+
2040
+ /* SSL_write(3ssl) manpage states num == 0 is undefined */
2041
+ num = RSTRING_LENINT(tmp);
2042
+ if (num == 0)
2043
+ return INT2FIX(0);
2044
+
2045
+ for (;;) {
2046
+ int nwritten = SSL_write(ssl, RSTRING_PTR(tmp), num);
2047
+ switch (ssl_get_error(ssl, nwritten)) {
2048
+ case SSL_ERROR_NONE:
2049
+ return INT2NUM(nwritten);
2050
+ case SSL_ERROR_WANT_WRITE:
2051
+ if (no_exception_p(opts)) { return sym_wait_writable; }
2052
+ write_would_block(nonblock);
2053
+ io_wait_writable(fptr);
2054
+ continue;
2055
+ case SSL_ERROR_WANT_READ:
2056
+ if (no_exception_p(opts)) { return sym_wait_readable; }
2057
+ read_would_block(nonblock);
2058
+ io_wait_readable(fptr);
2059
+ continue;
2060
+ case SSL_ERROR_SYSCALL:
2018
2061
  #ifdef __APPLE__
2019
- /*
2020
- * It appears that send syscall can return EPROTOTYPE if the
2021
- * socket is being torn down. Retry to get a proper errno to
2022
- * make the error handling in line with the socket library.
2023
- * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
2024
- */
2025
- if (errno == EPROTOTYPE)
2026
- continue;
2062
+ /*
2063
+ * It appears that send syscall can return EPROTOTYPE if the
2064
+ * socket is being torn down. Retry to get a proper errno to
2065
+ * make the error handling in line with the socket library.
2066
+ * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
2067
+ */
2068
+ if (errno == EPROTOTYPE)
2069
+ continue;
2027
2070
  #endif
2028
- if (errno) rb_sys_fail(0);
2029
- default:
2030
- ossl_raise(eSSLError, "SSL_write");
2031
- }
2071
+ if (errno) rb_sys_fail(0);
2072
+ /* fallthrough */
2073
+ default:
2074
+ ossl_raise(eSSLError, "SSL_write");
2032
2075
  }
2033
2076
  }
2034
- else {
2035
- ID meth = nonblock ?
2036
- rb_intern("write_nonblock") : rb_intern("syswrite");
2037
-
2038
- rb_warning("SSL session is not started yet.");
2039
- #if defined(RB_PASS_KEYWORDS)
2040
- if (nonblock) {
2041
- VALUE argv[2];
2042
- argv[0] = str;
2043
- argv[1] = opts;
2044
- return rb_funcallv_kw(io, meth, 2, argv, RB_PASS_KEYWORDS);
2045
- }
2046
- #else
2047
- if (nonblock) {
2048
- return rb_funcall(io, meth, 2, str, opts);
2049
- }
2050
- #endif
2051
- else
2052
- return rb_funcall(io, meth, 1, str);
2053
- }
2054
-
2055
- end:
2056
- return INT2NUM(nwrite);
2057
2077
  }
2058
2078
 
2059
2079
  /*
@@ -2352,7 +2372,57 @@ ossl_ssl_get_verify_result(VALUE self)
2352
2372
 
2353
2373
  GetSSL(self, ssl);
2354
2374
 
2355
- return INT2NUM(SSL_get_verify_result(ssl));
2375
+ return LONG2NUM(SSL_get_verify_result(ssl));
2376
+ }
2377
+
2378
+ /*
2379
+ * call-seq:
2380
+ * ssl.finished_message => "finished message"
2381
+ *
2382
+ * Returns the last *Finished* message sent
2383
+ *
2384
+ */
2385
+ static VALUE
2386
+ ossl_ssl_get_finished(VALUE self)
2387
+ {
2388
+ SSL *ssl;
2389
+ char sizer[1], *buf;
2390
+ size_t len;
2391
+
2392
+ GetSSL(self, ssl);
2393
+
2394
+ len = SSL_get_finished(ssl, sizer, 0);
2395
+ if (len == 0)
2396
+ return Qnil;
2397
+
2398
+ buf = ALLOCA_N(char, len);
2399
+ SSL_get_finished(ssl, buf, len);
2400
+ return rb_str_new(buf, len);
2401
+ }
2402
+
2403
+ /*
2404
+ * call-seq:
2405
+ * ssl.peer_finished_message => "peer finished message"
2406
+ *
2407
+ * Returns the last *Finished* message received
2408
+ *
2409
+ */
2410
+ static VALUE
2411
+ ossl_ssl_get_peer_finished(VALUE self)
2412
+ {
2413
+ SSL *ssl;
2414
+ char sizer[1], *buf;
2415
+ size_t len;
2416
+
2417
+ GetSSL(self, ssl);
2418
+
2419
+ len = SSL_get_peer_finished(ssl, sizer, 0);
2420
+ if (len == 0)
2421
+ return Qnil;
2422
+
2423
+ buf = ALLOCA_N(char, len);
2424
+ SSL_get_peer_finished(ssl, buf, len);
2425
+ return rb_str_new(buf, len);
2356
2426
  }
2357
2427
 
2358
2428
  /*
@@ -2378,7 +2448,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
2378
2448
  return ossl_x509name_sk2ary(ca);
2379
2449
  }
2380
2450
 
2381
- # ifndef OPENSSL_NO_NEXTPROTONEG
2451
+ # ifdef OSSL_USE_NEXTPROTONEG
2382
2452
  /*
2383
2453
  * call-seq:
2384
2454
  * ssl.npn_protocol => String | nil
@@ -2403,7 +2473,6 @@ ossl_ssl_npn_protocol(VALUE self)
2403
2473
  }
2404
2474
  # endif
2405
2475
 
2406
- # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2407
2476
  /*
2408
2477
  * call-seq:
2409
2478
  * ssl.alpn_protocol => String | nil
@@ -2426,9 +2495,50 @@ ossl_ssl_alpn_protocol(VALUE self)
2426
2495
  else
2427
2496
  return rb_str_new((const char *) out, outlen);
2428
2497
  }
2429
- # endif
2430
2498
 
2431
- # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2499
+ /*
2500
+ * call-seq:
2501
+ * session.export_keying_material(label, length) -> String
2502
+ *
2503
+ * Enables use of shared session key material in accordance with RFC 5705.
2504
+ */
2505
+ static VALUE
2506
+ ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self)
2507
+ {
2508
+ SSL *ssl;
2509
+ VALUE str;
2510
+ VALUE label;
2511
+ VALUE length;
2512
+ VALUE context;
2513
+ unsigned char *p;
2514
+ size_t len;
2515
+ int use_ctx = 0;
2516
+ unsigned char *ctx = NULL;
2517
+ size_t ctx_len = 0;
2518
+ int ret;
2519
+
2520
+ rb_scan_args(argc, argv, "21", &label, &length, &context);
2521
+ StringValue(label);
2522
+
2523
+ GetSSL(self, ssl);
2524
+
2525
+ len = (size_t)NUM2LONG(length);
2526
+ str = rb_str_new(0, len);
2527
+ p = (unsigned char *)RSTRING_PTR(str);
2528
+ if (!NIL_P(context)) {
2529
+ use_ctx = 1;
2530
+ StringValue(context);
2531
+ ctx = (unsigned char *)RSTRING_PTR(context);
2532
+ ctx_len = RSTRING_LEN(context);
2533
+ }
2534
+ ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label),
2535
+ RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
2536
+ if (ret == 0 || ret == -1) {
2537
+ ossl_raise(eSSLError, "SSL_export_keying_material");
2538
+ }
2539
+ return str;
2540
+ }
2541
+
2432
2542
  /*
2433
2543
  * call-seq:
2434
2544
  * ssl.tmp_key => PKey or nil
@@ -2446,11 +2556,8 @@ ossl_ssl_tmp_key(VALUE self)
2446
2556
  return Qnil;
2447
2557
  return ossl_pkey_new(key);
2448
2558
  }
2449
- # endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */
2450
2559
  #endif /* !defined(OPENSSL_NO_SOCK) */
2451
2560
 
2452
- #undef rb_intern
2453
- #define rb_intern(s) rb_intern_const(s)
2454
2561
  void
2455
2562
  Init_ossl_ssl(void)
2456
2563
  {
@@ -2461,8 +2568,9 @@ Init_ossl_ssl(void)
2461
2568
  rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
2462
2569
  #endif
2463
2570
 
2464
- id_call = rb_intern("call");
2465
- ID_callback_state = rb_intern("callback_state");
2571
+ #ifndef OPENSSL_NO_SOCK
2572
+ id_call = rb_intern_const("call");
2573
+ ID_callback_state = rb_intern_const("callback_state");
2466
2574
 
2467
2575
  ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0);
2468
2576
  if (ossl_ssl_ex_vcb_idx < 0)
@@ -2473,11 +2581,6 @@ Init_ossl_ssl(void)
2473
2581
  ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2474
2582
  if (ossl_sslctx_ex_ptr_idx < 0)
2475
2583
  ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2476
- #if !defined(HAVE_X509_STORE_UP_REF)
2477
- ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_store_p", 0, 0, 0);
2478
- if (ossl_sslctx_ex_store_p < 0)
2479
- ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2480
- #endif
2481
2584
 
2482
2585
  /* Document-module: OpenSSL::SSL
2483
2586
  *
@@ -2488,16 +2591,6 @@ Init_ossl_ssl(void)
2488
2591
  */
2489
2592
  mSSL = rb_define_module_under(mOSSL, "SSL");
2490
2593
 
2491
- /* Document-module: OpenSSL::ExtConfig
2492
- *
2493
- * This module contains configuration information about the SSL extension,
2494
- * for example if socket support is enabled, or the host name TLS extension
2495
- * is enabled. Constants in this module will always be defined, but contain
2496
- * +true+ or +false+ values depending on the configuration of your OpenSSL
2497
- * installation.
2498
- */
2499
- mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig");
2500
-
2501
2594
  /* Document-class: OpenSSL::SSL::SSLError
2502
2595
  *
2503
2596
  * Generic error class raised by SSLSocket and SSLContext.
@@ -2529,7 +2622,7 @@ Init_ossl_ssl(void)
2529
2622
  * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2530
2623
  * It is recommended to use #add_certificate instead.
2531
2624
  */
2532
- rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse);
2625
+ rb_attr(cSSLContext, rb_intern_const("cert"), 1, 1, Qfalse);
2533
2626
 
2534
2627
  /*
2535
2628
  * Context private key
@@ -2537,29 +2630,29 @@ Init_ossl_ssl(void)
2537
2630
  * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2538
2631
  * It is recommended to use #add_certificate instead.
2539
2632
  */
2540
- rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse);
2633
+ rb_attr(cSSLContext, rb_intern_const("key"), 1, 1, Qfalse);
2541
2634
 
2542
2635
  /*
2543
2636
  * A certificate or Array of certificates that will be sent to the client.
2544
2637
  */
2545
- rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse);
2638
+ rb_attr(cSSLContext, rb_intern_const("client_ca"), 1, 1, Qfalse);
2546
2639
 
2547
2640
  /*
2548
2641
  * The path to a file containing a PEM-format CA certificate
2549
2642
  */
2550
- rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse);
2643
+ rb_attr(cSSLContext, rb_intern_const("ca_file"), 1, 1, Qfalse);
2551
2644
 
2552
2645
  /*
2553
2646
  * The path to a directory containing CA certificates in PEM format.
2554
2647
  *
2555
2648
  * Files are looked up by subject's X509 name's hash value.
2556
2649
  */
2557
- rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse);
2650
+ rb_attr(cSSLContext, rb_intern_const("ca_path"), 1, 1, Qfalse);
2558
2651
 
2559
2652
  /*
2560
2653
  * Maximum session lifetime in seconds.
2561
2654
  */
2562
- rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse);
2655
+ rb_attr(cSSLContext, rb_intern_const("timeout"), 1, 1, Qfalse);
2563
2656
 
2564
2657
  /*
2565
2658
  * Session verification mode.
@@ -2572,12 +2665,12 @@ Init_ossl_ssl(void)
2572
2665
  *
2573
2666
  * See SSL_CTX_set_verify(3) for details.
2574
2667
  */
2575
- rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse);
2668
+ rb_attr(cSSLContext, rb_intern_const("verify_mode"), 1, 1, Qfalse);
2576
2669
 
2577
2670
  /*
2578
2671
  * Number of CA certificates to walk when verifying a certificate chain.
2579
2672
  */
2580
- rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse);
2673
+ rb_attr(cSSLContext, rb_intern_const("verify_depth"), 1, 1, Qfalse);
2581
2674
 
2582
2675
  /*
2583
2676
  * A callback for additional certificate verification. The callback is
@@ -2591,7 +2684,7 @@ Init_ossl_ssl(void)
2591
2684
  * If the callback returns +false+, the chain verification is immediately
2592
2685
  * stopped and a bad_certificate alert is then sent.
2593
2686
  */
2594
- rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
2687
+ rb_attr(cSSLContext, rb_intern_const("verify_callback"), 1, 1, Qfalse);
2595
2688
 
2596
2689
  /*
2597
2690
  * Whether to check the server certificate is valid for the hostname.
@@ -2599,12 +2692,12 @@ Init_ossl_ssl(void)
2599
2692
  * In order to make this work, verify_mode must be set to VERIFY_PEER and
2600
2693
  * the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=.
2601
2694
  */
2602
- rb_attr(cSSLContext, rb_intern("verify_hostname"), 1, 1, Qfalse);
2695
+ rb_attr(cSSLContext, rb_intern_const("verify_hostname"), 1, 1, Qfalse);
2603
2696
 
2604
2697
  /*
2605
2698
  * An OpenSSL::X509::Store used for certificate verification.
2606
2699
  */
2607
- rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse);
2700
+ rb_attr(cSSLContext, rb_intern_const("cert_store"), 1, 1, Qfalse);
2608
2701
 
2609
2702
  /*
2610
2703
  * An Array of extra X509 certificates to be added to the certificate
@@ -2613,7 +2706,7 @@ Init_ossl_ssl(void)
2613
2706
  * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2614
2707
  * It is recommended to use #add_certificate instead.
2615
2708
  */
2616
- rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse);
2709
+ rb_attr(cSSLContext, rb_intern_const("extra_chain_cert"), 1, 1, Qfalse);
2617
2710
 
2618
2711
  /*
2619
2712
  * A callback invoked when a client certificate is requested by a server
@@ -2623,28 +2716,14 @@ Init_ossl_ssl(void)
2623
2716
  * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any
2624
2717
  * other value is returned the handshake is suspended.
2625
2718
  */
2626
- rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
2627
-
2628
- #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
2629
- /*
2630
- * A callback invoked when ECDH parameters are required.
2631
- *
2632
- * The callback is invoked with the Session for the key exchange, an
2633
- * flag indicating the use of an export cipher and the keylength
2634
- * required.
2635
- *
2636
- * The callback is deprecated. This does not work with recent versions of
2637
- * OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead.
2638
- */
2639
- rb_attr(cSSLContext, rb_intern("tmp_ecdh_callback"), 1, 1, Qfalse);
2640
- #endif
2719
+ rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
2641
2720
 
2642
2721
  /*
2643
2722
  * Sets the context in which a session can be reused. This allows
2644
2723
  * sessions for multiple applications to be distinguished, for example, by
2645
2724
  * name.
2646
2725
  */
2647
- rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse);
2726
+ rb_attr(cSSLContext, rb_intern_const("session_id_context"), 1, 1, Qfalse);
2648
2727
 
2649
2728
  /*
2650
2729
  * A callback invoked on a server when a session is proposed by the client
@@ -2653,7 +2732,7 @@ Init_ossl_ssl(void)
2653
2732
  * The callback is invoked with the SSLSocket and session id. The
2654
2733
  * callback may return a Session from an external cache.
2655
2734
  */
2656
- rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse);
2735
+ rb_attr(cSSLContext, rb_intern_const("session_get_cb"), 1, 1, Qfalse);
2657
2736
 
2658
2737
  /*
2659
2738
  * A callback invoked when a new session was negotiated.
@@ -2661,7 +2740,7 @@ Init_ossl_ssl(void)
2661
2740
  * The callback is invoked with an SSLSocket. If +false+ is returned the
2662
2741
  * session will be removed from the internal cache.
2663
2742
  */
2664
- rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse);
2743
+ rb_attr(cSSLContext, rb_intern_const("session_new_cb"), 1, 1, Qfalse);
2665
2744
 
2666
2745
  /*
2667
2746
  * A callback invoked when a session is removed from the internal cache.
@@ -2672,18 +2751,16 @@ Init_ossl_ssl(void)
2672
2751
  * multi-threaded application. The callback is called inside a global lock
2673
2752
  * and it can randomly cause deadlock on Ruby thread switching.
2674
2753
  */
2675
- rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
2676
-
2677
- rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
2754
+ rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
2678
2755
 
2679
2756
  /*
2680
- * A callback invoked whenever a new handshake is initiated. May be used
2681
- * to disable renegotiation entirely.
2757
+ * A callback invoked whenever a new handshake is initiated on an
2758
+ * established connection. May be used to disable renegotiation entirely.
2682
2759
  *
2683
2760
  * The callback is invoked with the active SSLSocket. The callback's
2684
- * return value is irrelevant, normal return indicates "approval" of the
2761
+ * return value is ignored. A normal return indicates "approval" of the
2685
2762
  * renegotiation and will continue the process. To forbid renegotiation
2686
- * and to cancel the process, an Error may be raised within the callback.
2763
+ * and to cancel the process, raise an exception within the callback.
2687
2764
  *
2688
2765
  * === Disable client renegotiation
2689
2766
  *
@@ -2691,14 +2768,12 @@ Init_ossl_ssl(void)
2691
2768
  * renegotiation entirely. You may use a callback as follows to implement
2692
2769
  * this feature:
2693
2770
  *
2694
- * num_handshakes = 0
2695
2771
  * ctx.renegotiation_cb = lambda do |ssl|
2696
- * num_handshakes += 1
2697
- * raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
2772
+ * raise RuntimeError, "Client renegotiation disabled"
2698
2773
  * end
2699
2774
  */
2700
- rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse);
2701
- #ifndef OPENSSL_NO_NEXTPROTONEG
2775
+ rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
2776
+ #ifdef OSSL_USE_NEXTPROTONEG
2702
2777
  /*
2703
2778
  * An Enumerable of Strings. Each String represents a protocol to be
2704
2779
  * advertised as the list of supported protocols for Next Protocol
@@ -2710,7 +2785,7 @@ Init_ossl_ssl(void)
2710
2785
  *
2711
2786
  * ctx.npn_protocols = ["http/1.1", "spdy/2"]
2712
2787
  */
2713
- rb_attr(cSSLContext, rb_intern("npn_protocols"), 1, 1, Qfalse);
2788
+ rb_attr(cSSLContext, rb_intern_const("npn_protocols"), 1, 1, Qfalse);
2714
2789
  /*
2715
2790
  * A callback invoked on the client side when the client needs to select
2716
2791
  * a protocol from the list sent by the server. Supported in OpenSSL 1.0.1
@@ -2727,10 +2802,9 @@ Init_ossl_ssl(void)
2727
2802
  * protocols.first
2728
2803
  * end
2729
2804
  */
2730
- rb_attr(cSSLContext, rb_intern("npn_select_cb"), 1, 1, Qfalse);
2805
+ rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse);
2731
2806
  #endif
2732
2807
 
2733
- #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2734
2808
  /*
2735
2809
  * An Enumerable of Strings. Each String represents a protocol to be
2736
2810
  * advertised as the list of supported protocols for Application-Layer
@@ -2742,7 +2816,7 @@ Init_ossl_ssl(void)
2742
2816
  *
2743
2817
  * ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"]
2744
2818
  */
2745
- rb_attr(cSSLContext, rb_intern("alpn_protocols"), 1, 1, Qfalse);
2819
+ rb_attr(cSSLContext, rb_intern_const("alpn_protocols"), 1, 1, Qfalse);
2746
2820
  /*
2747
2821
  * A callback invoked on the server side when the server needs to select
2748
2822
  * a protocol from the list sent by the client. Supported in OpenSSL 1.0.2
@@ -2759,8 +2833,30 @@ Init_ossl_ssl(void)
2759
2833
  * protocols.first
2760
2834
  * end
2761
2835
  */
2762
- rb_attr(cSSLContext, rb_intern("alpn_select_cb"), 1, 1, Qfalse);
2763
- #endif
2836
+ rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
2837
+
2838
+ /*
2839
+ * A callback invoked when TLS key material is generated or received, in
2840
+ * order to allow applications to store this keying material for debugging
2841
+ * purposes.
2842
+ *
2843
+ * The callback is invoked with an SSLSocket and a string containing the
2844
+ * key material in the format used by NSS for its SSLKEYLOGFILE debugging
2845
+ * output.
2846
+ *
2847
+ * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
2848
+ * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
2849
+ * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
2850
+ *
2851
+ * === Example
2852
+ *
2853
+ * context.keylog_cb = proc do |_sock, line|
2854
+ * File.open('ssl_keylog_file', "a") do |f|
2855
+ * f.write("#{line}\n")
2856
+ * end
2857
+ * end
2858
+ */
2859
+ rb_attr(cSSLContext, rb_intern_const("keylog_cb"), 1, 1, Qfalse);
2764
2860
 
2765
2861
  rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2766
2862
  rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
@@ -2768,6 +2864,12 @@ Init_ossl_ssl(void)
2768
2864
  ossl_sslctx_set_minmax_proto_version, 2);
2769
2865
  rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2770
2866
  rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
2867
+ #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
2868
+ rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1);
2869
+ #endif
2870
+ #ifndef OPENSSL_NO_DH
2871
+ rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
2872
+ #endif
2771
2873
  rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
2772
2874
  rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
2773
2875
  rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
@@ -2841,11 +2943,6 @@ Init_ossl_ssl(void)
2841
2943
  * Document-class: OpenSSL::SSL::SSLSocket
2842
2944
  */
2843
2945
  cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
2844
- #ifdef OPENSSL_NO_SOCK
2845
- rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue);
2846
- rb_define_method(cSSLSocket, "initialize", rb_f_notimplement, -1);
2847
- #else
2848
- rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse);
2849
2946
  rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
2850
2947
  rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
2851
2948
  rb_undef_method(cSSLSocket, "initialize_copy");
@@ -2872,16 +2969,14 @@ Init_ossl_ssl(void)
2872
2969
  rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
2873
2970
  /* #hostname is defined in lib/openssl/ssl.rb */
2874
2971
  rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
2875
- # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2972
+ rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0);
2973
+ rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
2876
2974
  rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
2877
- # endif
2878
- # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2879
2975
  rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
2880
- # endif
2881
- # ifndef OPENSSL_NO_NEXTPROTONEG
2976
+ rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1);
2977
+ # ifdef OSSL_USE_NEXTPROTONEG
2882
2978
  rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2883
2979
  # endif
2884
- #endif
2885
2980
 
2886
2981
  rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
2887
2982
  rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
@@ -2889,12 +2984,23 @@ Init_ossl_ssl(void)
2889
2984
  rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
2890
2985
 
2891
2986
  rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL));
2987
+ #ifdef SSL_OP_CLEANSE_PLAINTEXT /* OpenSSL 3.0 */
2988
+ rb_define_const(mSSL, "OP_CLEANSE_PLAINTEXT", ULONG2NUM(SSL_OP_CLEANSE_PLAINTEXT));
2989
+ #endif
2892
2990
  rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
2893
- #ifdef SSL_OP_TLSEXT_PADDING /* OpenSSL 1.0.1h and OpenSSL 1.0.2 */
2894
- rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
2991
+ #ifdef SSL_OP_ENABLE_KTLS /* OpenSSL 3.0 */
2992
+ rb_define_const(mSSL, "OP_ENABLE_KTLS", ULONG2NUM(SSL_OP_ENABLE_KTLS));
2895
2993
  #endif
2896
- #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG /* OpenSSL 1.0.1f and OpenSSL 1.0.2 */
2994
+ rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
2897
2995
  rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG));
2996
+ #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* OpenSSL 3.0 */
2997
+ rb_define_const(mSSL, "OP_IGNORE_UNEXPECTED_EOF", ULONG2NUM(SSL_OP_IGNORE_UNEXPECTED_EOF));
2998
+ #endif
2999
+ #ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION /* OpenSSL 3.0 */
3000
+ rb_define_const(mSSL, "OP_ALLOW_CLIENT_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_CLIENT_RENEGOTIATION));
3001
+ #endif
3002
+ #ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */
3003
+ rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES));
2898
3004
  #endif
2899
3005
  #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
2900
3006
  rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
@@ -2907,13 +3013,15 @@ Init_ossl_ssl(void)
2907
3013
  #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
2908
3014
  rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
2909
3015
  #endif
2910
- rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
2911
- rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
2912
- #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
2913
- rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
3016
+ #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */
3017
+ rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT));
3018
+ #endif
3019
+ #ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */
3020
+ rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA));
3021
+ #endif
3022
+ #ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */
3023
+ rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY));
2914
3024
  #endif
2915
- rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
2916
-
2917
3025
  rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
2918
3026
  rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
2919
3027
  rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
@@ -2921,6 +3029,12 @@ Init_ossl_ssl(void)
2921
3029
  #ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
2922
3030
  rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
2923
3031
  #endif
3032
+ rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
3033
+ rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
3034
+ #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
3035
+ rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
3036
+ #endif
3037
+ rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
2924
3038
 
2925
3039
  /* SSL_OP_* flags for DTLS */
2926
3040
  #if 0
@@ -2985,17 +3099,16 @@ Init_ossl_ssl(void)
2985
3099
  #endif
2986
3100
 
2987
3101
 
2988
- sym_exception = ID2SYM(rb_intern("exception"));
2989
- sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
2990
- sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
3102
+ sym_exception = ID2SYM(rb_intern_const("exception"));
3103
+ sym_wait_readable = ID2SYM(rb_intern_const("wait_readable"));
3104
+ sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
2991
3105
 
2992
- id_tmp_dh_callback = rb_intern("tmp_dh_callback");
2993
- id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
2994
- id_npn_protocols_encoded = rb_intern("npn_protocols_encoded");
3106
+ id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
3107
+ id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
2995
3108
  id_each = rb_intern_const("each");
2996
3109
 
2997
3110
  #define DefIVarID(name) do \
2998
- id_i_##name = rb_intern("@"#name); while (0)
3111
+ id_i_##name = rb_intern_const("@"#name); while (0)
2999
3112
 
3000
3113
  DefIVarID(cert_store);
3001
3114
  DefIVarID(ca_file);
@@ -3009,7 +3122,6 @@ Init_ossl_ssl(void)
3009
3122
  DefIVarID(key);
3010
3123
  DefIVarID(extra_chain_cert);
3011
3124
  DefIVarID(client_cert_cb);
3012
- DefIVarID(tmp_ecdh_callback);
3013
3125
  DefIVarID(timeout);
3014
3126
  DefIVarID(session_id_context);
3015
3127
  DefIVarID(session_get_cb);
@@ -3021,8 +3133,10 @@ Init_ossl_ssl(void)
3021
3133
  DefIVarID(alpn_select_cb);
3022
3134
  DefIVarID(servername_cb);
3023
3135
  DefIVarID(verify_hostname);
3136
+ DefIVarID(keylog_cb);
3024
3137
 
3025
3138
  DefIVarID(io);
3026
3139
  DefIVarID(context);
3027
3140
  DefIVarID(hostname);
3141
+ #endif /* !defined(OPENSSL_NO_SOCK) */
3028
3142
  }