openssl 2.1.3 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
  }