openssl 3.0.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -227,7 +227,7 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other)
227
227
  static VALUE
228
228
  ossl_ec_key_get_group(VALUE self)
229
229
  {
230
- EC_KEY *ec;
230
+ OSSL_3_const EC_KEY *ec;
231
231
  const EC_GROUP *group;
232
232
 
233
233
  GetEC(self, ec);
@@ -272,7 +272,7 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v)
272
272
  */
273
273
  static VALUE ossl_ec_key_get_private_key(VALUE self)
274
274
  {
275
- EC_KEY *ec;
275
+ OSSL_3_const EC_KEY *ec;
276
276
  const BIGNUM *bn;
277
277
 
278
278
  GetEC(self, ec);
@@ -323,7 +323,7 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)
323
323
  */
324
324
  static VALUE ossl_ec_key_get_public_key(VALUE self)
325
325
  {
326
- EC_KEY *ec;
326
+ OSSL_3_const EC_KEY *ec;
327
327
  const EC_POINT *point;
328
328
 
329
329
  GetEC(self, ec);
@@ -375,7 +375,7 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
375
375
  */
376
376
  static VALUE ossl_ec_key_is_public(VALUE self)
377
377
  {
378
- EC_KEY *ec;
378
+ OSSL_3_const EC_KEY *ec;
379
379
 
380
380
  GetEC(self, ec);
381
381
 
@@ -391,7 +391,7 @@ static VALUE ossl_ec_key_is_public(VALUE self)
391
391
  */
392
392
  static VALUE ossl_ec_key_is_private(VALUE self)
393
393
  {
394
- EC_KEY *ec;
394
+ OSSL_3_const EC_KEY *ec;
395
395
 
396
396
  GetEC(self, ec);
397
397
 
@@ -411,7 +411,7 @@ static VALUE ossl_ec_key_is_private(VALUE self)
411
411
  static VALUE
412
412
  ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
413
413
  {
414
- EC_KEY *ec;
414
+ OSSL_3_const EC_KEY *ec;
415
415
 
416
416
  GetEC(self, ec);
417
417
  if (EC_KEY_get0_public_key(ec) == NULL)
@@ -431,7 +431,7 @@ ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
431
431
  static VALUE
432
432
  ossl_ec_key_to_der(VALUE self)
433
433
  {
434
- EC_KEY *ec;
434
+ OSSL_3_const EC_KEY *ec;
435
435
 
436
436
  GetEC(self, ec);
437
437
  if (EC_KEY_get0_public_key(ec) == NULL)
@@ -483,16 +483,28 @@ static VALUE ossl_ec_key_check_key(VALUE self)
483
483
  #ifdef HAVE_EVP_PKEY_CHECK
484
484
  EVP_PKEY *pkey;
485
485
  EVP_PKEY_CTX *pctx;
486
- int ret;
486
+ EC_KEY *ec;
487
487
 
488
488
  GetPKey(self, pkey);
489
+ GetEC(self, ec);
489
490
  pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
490
491
  if (!pctx)
491
- ossl_raise(eDHError, "EVP_PKEY_CTX_new");
492
- ret = EVP_PKEY_public_check(pctx);
492
+ ossl_raise(eECError, "EVP_PKEY_CTX_new");
493
+
494
+ if (EC_KEY_get0_private_key(ec) != NULL) {
495
+ if (EVP_PKEY_check(pctx) != 1) {
496
+ EVP_PKEY_CTX_free(pctx);
497
+ ossl_raise(eECError, "EVP_PKEY_check");
498
+ }
499
+ }
500
+ else {
501
+ if (EVP_PKEY_public_check(pctx) != 1) {
502
+ EVP_PKEY_CTX_free(pctx);
503
+ ossl_raise(eECError, "EVP_PKEY_public_check");
504
+ }
505
+ }
506
+
493
507
  EVP_PKEY_CTX_free(pctx);
494
- if (ret != 1)
495
- ossl_raise(eECError, "EVP_PKEY_public_check");
496
508
  #else
497
509
  EC_KEY *ec;
498
510
 
@@ -668,10 +680,11 @@ static VALUE ossl_ec_group_eql(VALUE a, VALUE b)
668
680
  GetECGroup(a, group1);
669
681
  GetECGroup(b, group2);
670
682
 
671
- if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1)
672
- return Qfalse;
673
-
674
- return Qtrue;
683
+ switch (EC_GROUP_cmp(group1, group2, ossl_bn_ctx)) {
684
+ case 0: return Qtrue;
685
+ case 1: return Qfalse;
686
+ default: ossl_raise(eEC_GROUP, "EC_GROUP_cmp");
687
+ }
675
688
  }
676
689
 
677
690
  /*
@@ -1232,10 +1245,13 @@ static VALUE ossl_ec_point_eql(VALUE a, VALUE b)
1232
1245
  GetECPoint(b, point2);
1233
1246
  GetECGroup(group_v1, group);
1234
1247
 
1235
- if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1)
1236
- return Qfalse;
1248
+ switch (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx)) {
1249
+ case 0: return Qtrue;
1250
+ case 1: return Qfalse;
1251
+ default: ossl_raise(eEC_POINT, "EC_POINT_cmp");
1252
+ }
1237
1253
 
1238
- return Qtrue;
1254
+ UNREACHABLE;
1239
1255
  }
1240
1256
 
1241
1257
  /*
@@ -1253,7 +1269,7 @@ static VALUE ossl_ec_point_is_at_infinity(VALUE self)
1253
1269
  switch (EC_POINT_is_at_infinity(group, point)) {
1254
1270
  case 1: return Qtrue;
1255
1271
  case 0: return Qfalse;
1256
- default: ossl_raise(cEC_POINT, "EC_POINT_is_at_infinity");
1272
+ default: ossl_raise(eEC_POINT, "EC_POINT_is_at_infinity");
1257
1273
  }
1258
1274
 
1259
1275
  UNREACHABLE;
@@ -1274,7 +1290,7 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self)
1274
1290
  switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) {
1275
1291
  case 1: return Qtrue;
1276
1292
  case 0: return Qfalse;
1277
- default: ossl_raise(cEC_POINT, "EC_POINT_is_on_curve");
1293
+ default: ossl_raise(eEC_POINT, "EC_POINT_is_on_curve");
1278
1294
  }
1279
1295
 
1280
1296
  UNREACHABLE;
@@ -1297,7 +1313,7 @@ static VALUE ossl_ec_point_make_affine(VALUE self)
1297
1313
  rb_warn("OpenSSL::PKey::EC::Point#make_affine! is deprecated");
1298
1314
  #if !OSSL_OPENSSL_PREREQ(3, 0, 0)
1299
1315
  if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)
1300
- ossl_raise(cEC_POINT, "EC_POINT_make_affine");
1316
+ ossl_raise(eEC_POINT, "EC_POINT_make_affine");
1301
1317
  #endif
1302
1318
 
1303
1319
  return self;
@@ -1316,7 +1332,7 @@ static VALUE ossl_ec_point_invert(VALUE self)
1316
1332
  GetECPointGroup(self, group);
1317
1333
 
1318
1334
  if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1)
1319
- ossl_raise(cEC_POINT, "EC_POINT_invert");
1335
+ ossl_raise(eEC_POINT, "EC_POINT_invert");
1320
1336
 
1321
1337
  return self;
1322
1338
  }
@@ -1334,7 +1350,7 @@ static VALUE ossl_ec_point_set_to_infinity(VALUE self)
1334
1350
  GetECPointGroup(self, group);
1335
1351
 
1336
1352
  if (EC_POINT_set_to_infinity(group, point) != 1)
1337
- ossl_raise(cEC_POINT, "EC_POINT_set_to_infinity");
1353
+ ossl_raise(eEC_POINT, "EC_POINT_set_to_infinity");
1338
1354
 
1339
1355
  return self;
1340
1356
  }
@@ -24,7 +24,7 @@
24
24
  } while (0)
25
25
 
26
26
  static inline int
27
- RSA_HAS_PRIVATE(RSA *rsa)
27
+ RSA_HAS_PRIVATE(OSSL_3_const RSA *rsa)
28
28
  {
29
29
  const BIGNUM *e, *d;
30
30
 
@@ -33,7 +33,7 @@ RSA_HAS_PRIVATE(RSA *rsa)
33
33
  }
34
34
 
35
35
  static inline int
36
- RSA_PRIVATE(VALUE obj, RSA *rsa)
36
+ RSA_PRIVATE(VALUE obj, OSSL_3_const RSA *rsa)
37
37
  {
38
38
  return RSA_HAS_PRIVATE(rsa) || OSSL_PKEY_IS_PRIVATE(obj);
39
39
  }
@@ -174,7 +174,7 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other)
174
174
  static VALUE
175
175
  ossl_rsa_is_public(VALUE self)
176
176
  {
177
- RSA *rsa;
177
+ OSSL_3_const RSA *rsa;
178
178
 
179
179
  GetRSA(self, rsa);
180
180
  /*
@@ -193,7 +193,7 @@ ossl_rsa_is_public(VALUE self)
193
193
  static VALUE
194
194
  ossl_rsa_is_private(VALUE self)
195
195
  {
196
- RSA *rsa;
196
+ OSSL_3_const RSA *rsa;
197
197
 
198
198
  GetRSA(self, rsa);
199
199
 
@@ -203,7 +203,7 @@ ossl_rsa_is_private(VALUE self)
203
203
  static int
204
204
  can_export_rsaprivatekey(VALUE self)
205
205
  {
206
- RSA *rsa;
206
+ OSSL_3_const RSA *rsa;
207
207
  const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
208
208
 
209
209
  GetRSA(self, rsa);
@@ -453,7 +453,7 @@ ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self)
453
453
  static VALUE
454
454
  ossl_rsa_get_params(VALUE self)
455
455
  {
456
- RSA *rsa;
456
+ OSSL_3_const RSA *rsa;
457
457
  VALUE hash;
458
458
  const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
459
459
 
@@ -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;
@@ -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)
@@ -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
  {
@@ -1602,11 +1703,16 @@ no_exception_p(VALUE opts)
1602
1703
  return 0;
1603
1704
  }
1604
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
+
1605
1711
  static void
1606
1712
  io_wait_writable(rb_io_t *fptr)
1607
1713
  {
1608
1714
  #ifdef HAVE_RB_IO_MAYBE_WAIT
1609
- rb_io_maybe_wait_writable(errno, fptr->self, Qnil);
1715
+ rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT);
1610
1716
  #else
1611
1717
  rb_io_wait_writable(fptr->fd);
1612
1718
  #endif
@@ -1616,14 +1722,14 @@ static void
1616
1722
  io_wait_readable(rb_io_t *fptr)
1617
1723
  {
1618
1724
  #ifdef HAVE_RB_IO_MAYBE_WAIT
1619
- rb_io_maybe_wait_readable(errno, fptr->self, Qnil);
1725
+ rb_io_maybe_wait_readable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT);
1620
1726
  #else
1621
1727
  rb_io_wait_readable(fptr->fd);
1622
1728
  #endif
1623
1729
  }
1624
1730
 
1625
1731
  static VALUE
1626
- 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)
1627
1733
  {
1628
1734
  SSL *ssl;
1629
1735
  rb_io_t *fptr;
@@ -2342,7 +2448,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
2342
2448
  return ossl_x509name_sk2ary(ca);
2343
2449
  }
2344
2450
 
2345
- # ifndef OPENSSL_NO_NEXTPROTONEG
2451
+ # ifdef OSSL_USE_NEXTPROTONEG
2346
2452
  /*
2347
2453
  * call-seq:
2348
2454
  * ssl.npn_protocol => String | nil
@@ -2390,6 +2496,49 @@ ossl_ssl_alpn_protocol(VALUE self)
2390
2496
  return rb_str_new((const char *) out, outlen);
2391
2497
  }
2392
2498
 
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
+
2393
2542
  /*
2394
2543
  * call-seq:
2395
2544
  * ssl.tmp_key => PKey or nil
@@ -2419,6 +2568,7 @@ Init_ossl_ssl(void)
2419
2568
  rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
2420
2569
  #endif
2421
2570
 
2571
+ #ifndef OPENSSL_NO_SOCK
2422
2572
  id_call = rb_intern_const("call");
2423
2573
  ID_callback_state = rb_intern_const("callback_state");
2424
2574
 
@@ -2441,16 +2591,6 @@ Init_ossl_ssl(void)
2441
2591
  */
2442
2592
  mSSL = rb_define_module_under(mOSSL, "SSL");
2443
2593
 
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
2594
  /* Document-class: OpenSSL::SSL::SSLError
2455
2595
  *
2456
2596
  * Generic error class raised by SSLSocket and SSLContext.
@@ -2613,8 +2753,6 @@ Init_ossl_ssl(void)
2613
2753
  */
2614
2754
  rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
2615
2755
 
2616
- rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
2617
-
2618
2756
  /*
2619
2757
  * A callback invoked whenever a new handshake is initiated on an
2620
2758
  * established connection. May be used to disable renegotiation entirely.
@@ -2635,7 +2773,7 @@ Init_ossl_ssl(void)
2635
2773
  * end
2636
2774
  */
2637
2775
  rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
2638
- #ifndef OPENSSL_NO_NEXTPROTONEG
2776
+ #ifdef OSSL_USE_NEXTPROTONEG
2639
2777
  /*
2640
2778
  * An Enumerable of Strings. Each String represents a protocol to be
2641
2779
  * advertised as the list of supported protocols for Next Protocol
@@ -2697,12 +2835,38 @@ Init_ossl_ssl(void)
2697
2835
  */
2698
2836
  rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
2699
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);
2860
+
2700
2861
  rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2701
2862
  rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
2702
2863
  rb_define_private_method(cSSLContext, "set_minmax_proto_version",
2703
2864
  ossl_sslctx_set_minmax_proto_version, 2);
2704
2865
  rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2705
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
2706
2870
  #ifndef OPENSSL_NO_DH
2707
2871
  rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
2708
2872
  #endif
@@ -2779,11 +2943,6 @@ Init_ossl_ssl(void)
2779
2943
  * Document-class: OpenSSL::SSL::SSLSocket
2780
2944
  */
2781
2945
  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
2946
  rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
2788
2947
  rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
2789
2948
  rb_undef_method(cSSLSocket, "initialize_copy");
@@ -2814,10 +2973,10 @@ Init_ossl_ssl(void)
2814
2973
  rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
2815
2974
  rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
2816
2975
  rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
2817
- # ifndef OPENSSL_NO_NEXTPROTONEG
2976
+ rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1);
2977
+ # ifdef OSSL_USE_NEXTPROTONEG
2818
2978
  rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2819
2979
  # endif
2820
- #endif
2821
2980
 
2822
2981
  rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
2823
2982
  rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
@@ -2974,8 +3133,10 @@ Init_ossl_ssl(void)
2974
3133
  DefIVarID(alpn_select_cb);
2975
3134
  DefIVarID(servername_cb);
2976
3135
  DefIVarID(verify_hostname);
3136
+ DefIVarID(keylog_cb);
2977
3137
 
2978
3138
  DefIVarID(io);
2979
3139
  DefIVarID(context);
2980
3140
  DefIVarID(hostname);
3141
+ #endif /* !defined(OPENSSL_NO_SOCK) */
2981
3142
  }
@@ -4,6 +4,7 @@
4
4
 
5
5
  #include "ossl.h"
6
6
 
7
+ #ifndef OPENSSL_NO_SOCK
7
8
  VALUE cSSLSession;
8
9
  static VALUE eSSLSession;
9
10
 
@@ -299,6 +300,7 @@ static VALUE ossl_ssl_session_to_text(VALUE self)
299
300
  return ossl_membio2str(out);
300
301
  }
301
302
 
303
+ #endif /* !defined(OPENSSL_NO_SOCK) */
302
304
 
303
305
  void Init_ossl_ssl_session(void)
304
306
  {
@@ -307,6 +309,7 @@ void Init_ossl_ssl_session(void)
307
309
  mSSL = rb_define_module_under(mOSSL, "SSL");
308
310
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
309
311
  #endif
312
+ #ifndef OPENSSL_NO_SOCK
310
313
  cSSLSession = rb_define_class_under(mSSL, "Session", rb_cObject);
311
314
  eSSLSession = rb_define_class_under(cSSLSession, "SessionError", eOSSLError);
312
315
 
@@ -324,4 +327,5 @@ void Init_ossl_ssl_session(void)
324
327
  rb_define_method(cSSLSession, "to_der", ossl_ssl_session_to_der, 0);
325
328
  rb_define_method(cSSLSession, "to_pem", ossl_ssl_session_to_pem, 0);
326
329
  rb_define_method(cSSLSession, "to_text", ossl_ssl_session_to_text, 0);
330
+ #endif /* !defined(OPENSSL_NO_SOCK) */
327
331
  }