openssl 3.0.2 → 3.2.0

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