openssl 3.0.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +1 -1
  3. data/History.md +76 -0
  4. data/README.md +36 -19
  5. data/ext/openssl/extconf.rb +89 -55
  6. data/ext/openssl/ossl.c +73 -195
  7. data/ext/openssl/ossl.h +11 -6
  8. data/ext/openssl/ossl_asn1.c +11 -10
  9. data/ext/openssl/ossl_bn.c +25 -13
  10. data/ext/openssl/ossl_cipher.c +2 -3
  11. data/ext/openssl/ossl_config.c +1 -1
  12. data/ext/openssl/ossl_digest.c +1 -1
  13. data/ext/openssl/ossl_engine.c +1 -1
  14. data/ext/openssl/ossl_hmac.c +1 -1
  15. data/ext/openssl/ossl_kdf.c +4 -4
  16. data/ext/openssl/ossl_ns_spki.c +1 -1
  17. data/ext/openssl/ossl_ocsp.c +8 -8
  18. data/ext/openssl/ossl_pkcs12.c +1 -1
  19. data/ext/openssl/ossl_pkcs7.c +3 -3
  20. data/ext/openssl/ossl_pkey.c +219 -46
  21. data/ext/openssl/ossl_pkey.h +1 -1
  22. data/ext/openssl/ossl_pkey_dh.c +28 -13
  23. data/ext/openssl/ossl_pkey_dsa.c +64 -15
  24. data/ext/openssl/ossl_pkey_ec.c +73 -17
  25. data/ext/openssl/ossl_pkey_rsa.c +74 -19
  26. data/ext/openssl/ossl_provider.c +211 -0
  27. data/ext/openssl/ossl_provider.h +5 -0
  28. data/ext/openssl/ossl_ssl.c +292 -113
  29. data/ext/openssl/ossl_ssl_session.c +5 -1
  30. data/ext/openssl/ossl_ts.c +3 -3
  31. data/ext/openssl/ossl_x509attr.c +1 -1
  32. data/ext/openssl/ossl_x509cert.c +1 -1
  33. data/ext/openssl/ossl_x509crl.c +1 -1
  34. data/ext/openssl/ossl_x509ext.c +13 -7
  35. data/ext/openssl/ossl_x509name.c +1 -1
  36. data/ext/openssl/ossl_x509req.c +1 -1
  37. data/ext/openssl/ossl_x509revoked.c +1 -1
  38. data/ext/openssl/ossl_x509store.c +12 -5
  39. data/lib/openssl/buffering.rb +2 -5
  40. data/lib/openssl/digest.rb +1 -5
  41. data/lib/openssl/pkey.rb +8 -4
  42. data/lib/openssl/ssl.rb +15 -10
  43. data/lib/openssl/version.rb +1 -1
  44. metadata +9 -6
@@ -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;
@@ -49,7 +52,7 @@ static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
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;
@@ -74,7 +77,7 @@ static const rb_data_type_t ossl_sslctx_type = {
74
77
  {
75
78
  ossl_sslctx_mark, ossl_sslctx_free,
76
79
  },
77
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
80
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
78
81
  };
79
82
 
80
83
  static VALUE
@@ -291,7 +294,7 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
291
294
  if (!pkey)
292
295
  return NULL;
293
296
 
294
- return EVP_PKEY_get0_DH(pkey);
297
+ return (DH *)EVP_PKEY_get0_DH(pkey);
295
298
  }
296
299
  #endif /* OPENSSL_NO_DH */
297
300
 
@@ -441,6 +444,54 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
441
444
  return 0;
442
445
  }
443
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
+
444
495
  static VALUE
445
496
  ossl_call_session_remove_cb(VALUE ary)
446
497
  {
@@ -655,7 +706,7 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
655
706
  return SSL_TLSEXT_ERR_OK;
656
707
  }
657
708
 
658
- #ifndef OPENSSL_NO_NEXTPROTONEG
709
+ #ifdef OSSL_USE_NEXTPROTONEG
659
710
  static int
660
711
  ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
661
712
  void *arg)
@@ -834,9 +885,9 @@ ossl_sslctx_setup(VALUE self)
834
885
  if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path))
835
886
  ossl_raise(eSSLError, "SSL_CTX_load_verify_dir");
836
887
  #else
837
- if(ca_file || ca_path){
838
- if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
839
- rb_warning("can't set verify locations");
888
+ if (ca_file || ca_path) {
889
+ if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
890
+ ossl_raise(eSSLError, "SSL_CTX_load_verify_locations");
840
891
  }
841
892
  #endif
842
893
 
@@ -852,7 +903,7 @@ ossl_sslctx_setup(VALUE self)
852
903
  val = rb_attr_get(self, id_i_verify_depth);
853
904
  if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
854
905
 
855
- #ifndef OPENSSL_NO_NEXTPROTONEG
906
+ #ifdef OSSL_USE_NEXTPROTONEG
856
907
  val = rb_attr_get(self, id_i_npn_protocols);
857
908
  if (!NIL_P(val)) {
858
909
  VALUE encoded = ssl_encode_npn_protocols(val);
@@ -911,6 +962,18 @@ ossl_sslctx_setup(VALUE self)
911
962
  OSSL_Debug("SSL TLSEXT servername callback added");
912
963
  }
913
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
+
914
977
  return Qtrue;
915
978
  }
916
979
 
@@ -959,27 +1022,13 @@ ossl_sslctx_get_ciphers(VALUE self)
959
1022
  return ary;
960
1023
  }
961
1024
 
962
- /*
963
- * call-seq:
964
- * ctx.ciphers = "cipher1:cipher2:..."
965
- * ctx.ciphers = [name, ...]
966
- * ctx.ciphers = [[name, version, bits, alg_bits], ...]
967
- *
968
- * Sets the list of available cipher suites for this context. Note in a server
969
- * context some ciphers require the appropriate certificates. For example, an
970
- * RSA cipher suite can only be chosen when an RSA certificate is available.
971
- */
972
1025
  static VALUE
973
- ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1026
+ build_cipher_string(VALUE v)
974
1027
  {
975
- SSL_CTX *ctx;
976
1028
  VALUE str, elem;
977
1029
  int i;
978
1030
 
979
- rb_check_frozen(self);
980
- if (NIL_P(v))
981
- return v;
982
- else if (RB_TYPE_P(v, T_ARRAY)) {
1031
+ if (RB_TYPE_P(v, T_ARRAY)) {
983
1032
  str = rb_str_new(0, 0);
984
1033
  for (i = 0; i < RARRAY_LEN(v); i++) {
985
1034
  elem = rb_ary_entry(v, i);
@@ -993,14 +1042,67 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
993
1042
  StringValue(str);
994
1043
  }
995
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
+
996
1070
  GetSSLCTX(self, ctx);
997
- if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) {
1071
+ if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
998
1072
  ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
999
- }
1000
1073
 
1001
1074
  return v;
1002
1075
  }
1003
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
+
1004
1106
  #ifndef OPENSSL_NO_DH
1005
1107
  /*
1006
1108
  * call-seq:
@@ -1439,7 +1541,6 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
1439
1541
  /*
1440
1542
  * SSLSocket class
1441
1543
  */
1442
- #ifndef OPENSSL_NO_SOCK
1443
1544
  static inline int
1444
1545
  ssl_started(SSL *ssl)
1445
1546
  {
@@ -1452,6 +1553,10 @@ ossl_ssl_mark(void *ptr)
1452
1553
  {
1453
1554
  SSL *ssl = ptr;
1454
1555
  rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
1556
+
1557
+ // Note: this reference is stored as @verify_callback so we don't need to mark it.
1558
+ // However we do need to ensure GC compaction won't move it, hence why
1559
+ // we call rb_gc_mark here.
1455
1560
  rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
1456
1561
  }
1457
1562
 
@@ -1466,7 +1571,7 @@ const rb_data_type_t ossl_ssl_type = {
1466
1571
  {
1467
1572
  ossl_ssl_mark, ossl_ssl_free,
1468
1573
  },
1469
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
1574
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1470
1575
  };
1471
1576
 
1472
1577
  static VALUE
@@ -1545,6 +1650,8 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1545
1650
  SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
1546
1651
  SSL_set_info_callback(ssl, ssl_info_cb);
1547
1652
  verify_cb = rb_attr_get(v_ctx, id_i_verify_callback);
1653
+ // We don't need to trigger a write barrier because it's already
1654
+ // an instance variable of this object.
1548
1655
  SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
1549
1656
 
1550
1657
  rb_call_super(0, NULL);
@@ -1552,6 +1659,17 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1552
1659
  return self;
1553
1660
  }
1554
1661
 
1662
+ #ifndef HAVE_RB_IO_DESCRIPTOR
1663
+ static int
1664
+ io_descriptor_fallback(VALUE io)
1665
+ {
1666
+ rb_io_t *fptr;
1667
+ GetOpenFile(io, fptr);
1668
+ return fptr->fd;
1669
+ }
1670
+ #define rb_io_descriptor io_descriptor_fallback
1671
+ #endif
1672
+
1555
1673
  static VALUE
1556
1674
  ossl_ssl_setup(VALUE self)
1557
1675
  {
@@ -1567,8 +1685,8 @@ ossl_ssl_setup(VALUE self)
1567
1685
  GetOpenFile(io, fptr);
1568
1686
  rb_io_check_readable(fptr);
1569
1687
  rb_io_check_writable(fptr);
1570
- if (!SSL_set_fd(ssl, TO_SOCKET(fptr->fd)))
1571
- ossl_raise(eSSLError, "SSL_set_fd");
1688
+ if (!SSL_set_fd(ssl, TO_SOCKET(rb_io_descriptor(io))))
1689
+ ossl_raise(eSSLError, "SSL_set_fd");
1572
1690
 
1573
1691
  return Qtrue;
1574
1692
  }
@@ -1602,99 +1720,107 @@ no_exception_p(VALUE opts)
1602
1720
  return 0;
1603
1721
  }
1604
1722
 
1723
+ // Provided by Ruby 3.2.0 and later in order to support the default IO#timeout.
1724
+ #ifndef RUBY_IO_TIMEOUT_DEFAULT
1725
+ #define RUBY_IO_TIMEOUT_DEFAULT Qnil
1726
+ #endif
1727
+
1605
1728
  static void
1606
- io_wait_writable(rb_io_t *fptr)
1729
+ io_wait_writable(VALUE io)
1607
1730
  {
1608
1731
  #ifdef HAVE_RB_IO_MAYBE_WAIT
1609
- rb_io_maybe_wait_writable(errno, fptr->self, Qnil);
1732
+ rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
1610
1733
  #else
1734
+ rb_io_t *fptr;
1735
+ GetOpenFile(io, fptr);
1611
1736
  rb_io_wait_writable(fptr->fd);
1612
1737
  #endif
1613
1738
  }
1614
1739
 
1615
1740
  static void
1616
- io_wait_readable(rb_io_t *fptr)
1741
+ io_wait_readable(VALUE io)
1617
1742
  {
1618
1743
  #ifdef HAVE_RB_IO_MAYBE_WAIT
1619
- rb_io_maybe_wait_readable(errno, fptr->self, Qnil);
1744
+ rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
1620
1745
  #else
1746
+ rb_io_t *fptr;
1747
+ GetOpenFile(io, fptr);
1621
1748
  rb_io_wait_readable(fptr->fd);
1622
1749
  #endif
1623
1750
  }
1624
1751
 
1625
1752
  static VALUE
1626
- ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1753
+ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
1627
1754
  {
1628
1755
  SSL *ssl;
1629
- rb_io_t *fptr;
1630
1756
  int ret, ret2;
1631
1757
  VALUE cb_state;
1632
1758
  int nonblock = opts != Qfalse;
1633
- #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1634
- unsigned long err;
1635
- #endif
1636
1759
 
1637
1760
  rb_ivar_set(self, ID_callback_state, Qnil);
1638
1761
 
1639
1762
  GetSSL(self, ssl);
1640
1763
 
1641
- GetOpenFile(rb_attr_get(self, id_i_io), fptr);
1642
- for(;;){
1643
- ret = func(ssl);
1764
+ VALUE io = rb_attr_get(self, id_i_io);
1765
+ for (;;) {
1766
+ ret = func(ssl);
1644
1767
 
1645
- cb_state = rb_attr_get(self, ID_callback_state);
1768
+ cb_state = rb_attr_get(self, ID_callback_state);
1646
1769
  if (!NIL_P(cb_state)) {
1647
- /* must cleanup OpenSSL error stack before re-raising */
1648
- ossl_clear_error();
1649
- rb_jump_tag(NUM2INT(cb_state));
1650
- }
1770
+ /* must cleanup OpenSSL error stack before re-raising */
1771
+ ossl_clear_error();
1772
+ rb_jump_tag(NUM2INT(cb_state));
1773
+ }
1651
1774
 
1652
- if (ret > 0)
1653
- break;
1775
+ if (ret > 0)
1776
+ break;
1654
1777
 
1655
- switch((ret2 = ssl_get_error(ssl, ret))){
1656
- case SSL_ERROR_WANT_WRITE:
1778
+ switch ((ret2 = ssl_get_error(ssl, ret))) {
1779
+ case SSL_ERROR_WANT_WRITE:
1657
1780
  if (no_exception_p(opts)) { return sym_wait_writable; }
1658
1781
  write_would_block(nonblock);
1659
- io_wait_writable(fptr);
1782
+ io_wait_writable(io);
1660
1783
  continue;
1661
- case SSL_ERROR_WANT_READ:
1784
+ case SSL_ERROR_WANT_READ:
1662
1785
  if (no_exception_p(opts)) { return sym_wait_readable; }
1663
1786
  read_would_block(nonblock);
1664
- io_wait_readable(fptr);
1787
+ io_wait_readable(io);
1665
1788
  continue;
1666
- case SSL_ERROR_SYSCALL:
1789
+ case SSL_ERROR_SYSCALL:
1667
1790
  #ifdef __APPLE__
1668
1791
  /* See ossl_ssl_write_internal() */
1669
1792
  if (errno == EPROTOTYPE)
1670
1793
  continue;
1671
1794
  #endif
1672
- if (errno) rb_sys_fail(funcname);
1673
- ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
1674
- funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
1675
-
1795
+ if (errno) rb_sys_fail(funcname);
1796
+ /* fallthrough */
1797
+ default: {
1798
+ VALUE error_append = Qnil;
1676
1799
  #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1677
- case SSL_ERROR_SSL:
1678
- err = ERR_peek_last_error();
1679
- if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
1680
- ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1681
- const char *err_msg = ERR_reason_error_string(err),
1682
- *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1683
- if (!err_msg)
1684
- err_msg = "(null)";
1685
- if (!verify_msg)
1686
- verify_msg = "(null)";
1687
- ossl_clear_error(); /* let ossl_raise() not append message */
1688
- ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s: %s (%s)",
1689
- funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl),
1690
- err_msg, verify_msg);
1691
- }
1800
+ unsigned long err = ERR_peek_last_error();
1801
+ if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
1802
+ ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1803
+ const char *err_msg = ERR_reason_error_string(err),
1804
+ *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1805
+ if (!err_msg)
1806
+ err_msg = "(null)";
1807
+ if (!verify_msg)
1808
+ verify_msg = "(null)";
1809
+ ossl_clear_error(); /* let ossl_raise() not append message */
1810
+ error_append = rb_sprintf(": %s (%s)", err_msg, verify_msg);
1811
+ }
1692
1812
  #endif
1693
- /* fallthrough */
1694
- default:
1695
- ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
1696
- funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
1697
- }
1813
+ ossl_raise(eSSLError,
1814
+ "%s%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s%"PRIsVALUE,
1815
+ funcname,
1816
+ ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "",
1817
+ ret2,
1818
+ errno,
1819
+ peeraddr_ip_str(self),
1820
+ SSL_state_string_long(ssl),
1821
+ error_append);
1822
+ }
1823
+ }
1698
1824
  }
1699
1825
 
1700
1826
  return self;
@@ -1800,8 +1926,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1800
1926
  SSL *ssl;
1801
1927
  int ilen;
1802
1928
  VALUE len, str;
1803
- rb_io_t *fptr;
1804
- VALUE io, opts = Qnil;
1929
+ VALUE opts = Qnil;
1805
1930
 
1806
1931
  if (nonblock) {
1807
1932
  rb_scan_args(argc, argv, "11:", &len, &str, &opts);
@@ -1826,8 +1951,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1826
1951
  if (ilen == 0)
1827
1952
  return str;
1828
1953
 
1829
- io = rb_attr_get(self, id_i_io);
1830
- GetOpenFile(io, fptr);
1954
+ VALUE io = rb_attr_get(self, id_i_io);
1831
1955
 
1832
1956
  rb_str_locktmp(str);
1833
1957
  for (;;) {
@@ -1847,7 +1971,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1847
1971
  if (no_exception_p(opts)) { return sym_wait_writable; }
1848
1972
  write_would_block(nonblock);
1849
1973
  }
1850
- io_wait_writable(fptr);
1974
+ io_wait_writable(io);
1851
1975
  continue;
1852
1976
  case SSL_ERROR_WANT_READ:
1853
1977
  if (nonblock) {
@@ -1855,7 +1979,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1855
1979
  if (no_exception_p(opts)) { return sym_wait_readable; }
1856
1980
  read_would_block(nonblock);
1857
1981
  }
1858
- io_wait_readable(fptr);
1982
+ io_wait_readable(io);
1859
1983
  continue;
1860
1984
  case SSL_ERROR_SYSCALL:
1861
1985
  if (!ERR_peek_error()) {
@@ -1921,14 +2045,14 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1921
2045
  SSL *ssl;
1922
2046
  rb_io_t *fptr;
1923
2047
  int num, nonblock = opts != Qfalse;
1924
- VALUE tmp, io;
2048
+ VALUE tmp;
1925
2049
 
1926
2050
  GetSSL(self, ssl);
1927
2051
  if (!ssl_started(ssl))
1928
2052
  rb_raise(eSSLError, "SSL session is not started yet");
1929
2053
 
1930
2054
  tmp = rb_str_new_frozen(StringValue(str));
1931
- io = rb_attr_get(self, id_i_io);
2055
+ VALUE io = rb_attr_get(self, id_i_io);
1932
2056
  GetOpenFile(io, fptr);
1933
2057
 
1934
2058
  /* SSL_write(3ssl) manpage states num == 0 is undefined */
@@ -1944,12 +2068,12 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1944
2068
  case SSL_ERROR_WANT_WRITE:
1945
2069
  if (no_exception_p(opts)) { return sym_wait_writable; }
1946
2070
  write_would_block(nonblock);
1947
- io_wait_writable(fptr);
2071
+ io_wait_writable(io);
1948
2072
  continue;
1949
2073
  case SSL_ERROR_WANT_READ:
1950
2074
  if (no_exception_p(opts)) { return sym_wait_readable; }
1951
2075
  read_would_block(nonblock);
1952
- io_wait_readable(fptr);
2076
+ io_wait_readable(io);
1953
2077
  continue;
1954
2078
  case SSL_ERROR_SYSCALL:
1955
2079
  #ifdef __APPLE__
@@ -2342,7 +2466,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
2342
2466
  return ossl_x509name_sk2ary(ca);
2343
2467
  }
2344
2468
 
2345
- # ifndef OPENSSL_NO_NEXTPROTONEG
2469
+ # ifdef OSSL_USE_NEXTPROTONEG
2346
2470
  /*
2347
2471
  * call-seq:
2348
2472
  * ssl.npn_protocol => String | nil
@@ -2390,6 +2514,49 @@ ossl_ssl_alpn_protocol(VALUE self)
2390
2514
  return rb_str_new((const char *) out, outlen);
2391
2515
  }
2392
2516
 
2517
+ /*
2518
+ * call-seq:
2519
+ * session.export_keying_material(label, length) -> String
2520
+ *
2521
+ * Enables use of shared session key material in accordance with RFC 5705.
2522
+ */
2523
+ static VALUE
2524
+ ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self)
2525
+ {
2526
+ SSL *ssl;
2527
+ VALUE str;
2528
+ VALUE label;
2529
+ VALUE length;
2530
+ VALUE context;
2531
+ unsigned char *p;
2532
+ size_t len;
2533
+ int use_ctx = 0;
2534
+ unsigned char *ctx = NULL;
2535
+ size_t ctx_len = 0;
2536
+ int ret;
2537
+
2538
+ rb_scan_args(argc, argv, "21", &label, &length, &context);
2539
+ StringValue(label);
2540
+
2541
+ GetSSL(self, ssl);
2542
+
2543
+ len = (size_t)NUM2LONG(length);
2544
+ str = rb_str_new(0, len);
2545
+ p = (unsigned char *)RSTRING_PTR(str);
2546
+ if (!NIL_P(context)) {
2547
+ use_ctx = 1;
2548
+ StringValue(context);
2549
+ ctx = (unsigned char *)RSTRING_PTR(context);
2550
+ ctx_len = RSTRING_LEN(context);
2551
+ }
2552
+ ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label),
2553
+ RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
2554
+ if (ret == 0 || ret == -1) {
2555
+ ossl_raise(eSSLError, "SSL_export_keying_material");
2556
+ }
2557
+ return str;
2558
+ }
2559
+
2393
2560
  /*
2394
2561
  * call-seq:
2395
2562
  * ssl.tmp_key => PKey or nil
@@ -2419,6 +2586,7 @@ Init_ossl_ssl(void)
2419
2586
  rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
2420
2587
  #endif
2421
2588
 
2589
+ #ifndef OPENSSL_NO_SOCK
2422
2590
  id_call = rb_intern_const("call");
2423
2591
  ID_callback_state = rb_intern_const("callback_state");
2424
2592
 
@@ -2441,16 +2609,6 @@ Init_ossl_ssl(void)
2441
2609
  */
2442
2610
  mSSL = rb_define_module_under(mOSSL, "SSL");
2443
2611
 
2444
- /* Document-module: OpenSSL::ExtConfig
2445
- *
2446
- * This module contains configuration information about the SSL extension,
2447
- * for example if socket support is enabled, or the host name TLS extension
2448
- * is enabled. Constants in this module will always be defined, but contain
2449
- * +true+ or +false+ values depending on the configuration of your OpenSSL
2450
- * installation.
2451
- */
2452
- mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig");
2453
-
2454
2612
  /* Document-class: OpenSSL::SSL::SSLError
2455
2613
  *
2456
2614
  * Generic error class raised by SSLSocket and SSLContext.
@@ -2613,8 +2771,6 @@ Init_ossl_ssl(void)
2613
2771
  */
2614
2772
  rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
2615
2773
 
2616
- rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
2617
-
2618
2774
  /*
2619
2775
  * A callback invoked whenever a new handshake is initiated on an
2620
2776
  * established connection. May be used to disable renegotiation entirely.
@@ -2635,7 +2791,7 @@ Init_ossl_ssl(void)
2635
2791
  * end
2636
2792
  */
2637
2793
  rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
2638
- #ifndef OPENSSL_NO_NEXTPROTONEG
2794
+ #ifdef OSSL_USE_NEXTPROTONEG
2639
2795
  /*
2640
2796
  * An Enumerable of Strings. Each String represents a protocol to be
2641
2797
  * advertised as the list of supported protocols for Next Protocol
@@ -2697,12 +2853,38 @@ Init_ossl_ssl(void)
2697
2853
  */
2698
2854
  rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
2699
2855
 
2856
+ /*
2857
+ * A callback invoked when TLS key material is generated or received, in
2858
+ * order to allow applications to store this keying material for debugging
2859
+ * purposes.
2860
+ *
2861
+ * The callback is invoked with an SSLSocket and a string containing the
2862
+ * key material in the format used by NSS for its SSLKEYLOGFILE debugging
2863
+ * output.
2864
+ *
2865
+ * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
2866
+ * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
2867
+ * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
2868
+ *
2869
+ * === Example
2870
+ *
2871
+ * context.keylog_cb = proc do |_sock, line|
2872
+ * File.open('ssl_keylog_file', "a") do |f|
2873
+ * f.write("#{line}\n")
2874
+ * end
2875
+ * end
2876
+ */
2877
+ rb_attr(cSSLContext, rb_intern_const("keylog_cb"), 1, 1, Qfalse);
2878
+
2700
2879
  rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2701
2880
  rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
2702
2881
  rb_define_private_method(cSSLContext, "set_minmax_proto_version",
2703
2882
  ossl_sslctx_set_minmax_proto_version, 2);
2704
2883
  rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2705
2884
  rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
2885
+ #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
2886
+ rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1);
2887
+ #endif
2706
2888
  #ifndef OPENSSL_NO_DH
2707
2889
  rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
2708
2890
  #endif
@@ -2779,11 +2961,6 @@ Init_ossl_ssl(void)
2779
2961
  * Document-class: OpenSSL::SSL::SSLSocket
2780
2962
  */
2781
2963
  cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
2782
- #ifdef OPENSSL_NO_SOCK
2783
- rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue);
2784
- rb_define_method(cSSLSocket, "initialize", rb_f_notimplement, -1);
2785
- #else
2786
- rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse);
2787
2964
  rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
2788
2965
  rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
2789
2966
  rb_undef_method(cSSLSocket, "initialize_copy");
@@ -2814,10 +2991,10 @@ Init_ossl_ssl(void)
2814
2991
  rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
2815
2992
  rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
2816
2993
  rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
2817
- # ifndef OPENSSL_NO_NEXTPROTONEG
2994
+ rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1);
2995
+ # ifdef OSSL_USE_NEXTPROTONEG
2818
2996
  rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2819
2997
  # endif
2820
- #endif
2821
2998
 
2822
2999
  rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
2823
3000
  rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
@@ -2974,8 +3151,10 @@ Init_ossl_ssl(void)
2974
3151
  DefIVarID(alpn_select_cb);
2975
3152
  DefIVarID(servername_cb);
2976
3153
  DefIVarID(verify_hostname);
3154
+ DefIVarID(keylog_cb);
2977
3155
 
2978
3156
  DefIVarID(io);
2979
3157
  DefIVarID(context);
2980
3158
  DefIVarID(hostname);
3159
+ #endif /* !defined(OPENSSL_NO_SOCK) */
2981
3160
  }