openssl 2.1.2 → 3.0.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +232 -0
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +61 -46
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +60 -44
  8. data/ext/openssl/ossl.c +112 -66
  9. data/ext/openssl/ossl.h +28 -11
  10. data/ext/openssl/ossl_asn1.c +42 -5
  11. data/ext/openssl/ossl_bn.c +276 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +38 -29
  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 +31 -62
  17. data/ext/openssl/ossl_engine.c +18 -27
  18. data/ext/openssl/ossl_hmac.c +52 -145
  19. data/ext/openssl/ossl_kdf.c +11 -19
  20. data/ext/openssl/ossl_ns_spki.c +1 -1
  21. data/ext/openssl/ossl_ocsp.c +9 -62
  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 +1255 -178
  27. data/ext/openssl/ossl_pkey.h +40 -77
  28. data/ext/openssl/ossl_pkey_dh.c +125 -335
  29. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  30. data/ext/openssl/ossl_pkey_ec.c +155 -318
  31. data/ext/openssl/ossl_pkey_rsa.c +105 -484
  32. data/ext/openssl/ossl_rand.c +2 -40
  33. data/ext/openssl/ossl_ssl.c +395 -364
  34. data/ext/openssl/ossl_ssl_session.c +24 -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 +86 -1
  38. data/ext/openssl/ossl_x509cert.c +166 -10
  39. data/ext/openssl/ossl_x509crl.c +10 -7
  40. data/ext/openssl/ossl_x509ext.c +15 -2
  41. data/ext/openssl/ossl_x509name.c +16 -5
  42. data/ext/openssl/ossl_x509req.c +10 -7
  43. data/ext/openssl/ossl_x509store.c +193 -92
  44. data/lib/openssl/bn.rb +1 -1
  45. data/lib/openssl/buffering.rb +42 -17
  46. data/lib/openssl/cipher.rb +1 -1
  47. data/lib/openssl/digest.rb +10 -12
  48. data/lib/openssl/hmac.rb +78 -0
  49. data/lib/openssl/marshal.rb +30 -0
  50. data/lib/openssl/pkcs5.rb +1 -1
  51. data/lib/openssl/pkey.rb +435 -1
  52. data/lib/openssl/ssl.rb +53 -14
  53. data/lib/openssl/version.rb +5 -0
  54. data/lib/openssl/x509.rb +177 -1
  55. data/lib/openssl.rb +24 -9
  56. metadata +13 -69
  57. data/ext/openssl/deprecation.rb +0 -23
  58. data/ext/openssl/ossl_version.h +0 -15
  59. data/ext/openssl/ruby_missing.h +0 -24
  60. data/lib/openssl/config.rb +0 -474
@@ -13,6 +13,12 @@
13
13
 
14
14
  #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
15
15
 
16
+ #if !defined(TLS1_3_VERSION) && \
17
+ defined(LIBRESSL_VERSION_NUMBER) && \
18
+ LIBRESSL_VERSION_NUMBER >= 0x3020000fL
19
+ # define TLS1_3_VERSION 0x0304
20
+ #endif
21
+
16
22
  #ifdef _WIN32
17
23
  # define TO_SOCKET(s) _get_osfhandle(s)
18
24
  #else
@@ -32,14 +38,14 @@ VALUE cSSLSocket;
32
38
  static VALUE eSSLErrorWaitReadable;
33
39
  static VALUE eSSLErrorWaitWritable;
34
40
 
35
- static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
36
- id_npn_protocols_encoded;
41
+ static ID id_call, ID_callback_state, id_tmp_dh_callback,
42
+ id_npn_protocols_encoded, id_each;
37
43
  static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
38
44
 
39
45
  static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
40
46
  id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
41
47
  id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
42
- id_i_client_cert_cb, id_i_tmp_ecdh_callback, id_i_timeout,
48
+ id_i_client_cert_cb, id_i_timeout,
43
49
  id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
44
50
  id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
45
51
  id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
@@ -49,25 +55,24 @@ static ID id_i_io, id_i_context, id_i_hostname;
49
55
  static int ossl_ssl_ex_vcb_idx;
50
56
  static int ossl_ssl_ex_ptr_idx;
51
57
  static int ossl_sslctx_ex_ptr_idx;
52
- #if !defined(HAVE_X509_STORE_UP_REF)
53
- static int ossl_sslctx_ex_store_p;
54
- #endif
55
58
 
56
59
  static void
57
- ossl_sslctx_free(void *ptr)
60
+ ossl_sslctx_mark(void *ptr)
58
61
  {
59
62
  SSL_CTX *ctx = ptr;
60
- #if !defined(HAVE_X509_STORE_UP_REF)
61
- if (ctx && SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_store_p))
62
- ctx->cert_store = NULL;
63
- #endif
64
- SSL_CTX_free(ctx);
63
+ rb_gc_mark((VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx));
64
+ }
65
+
66
+ static void
67
+ ossl_sslctx_free(void *ptr)
68
+ {
69
+ SSL_CTX_free(ptr);
65
70
  }
66
71
 
67
72
  static const rb_data_type_t ossl_sslctx_type = {
68
73
  "OpenSSL/SSL/CTX",
69
74
  {
70
- 0, ossl_sslctx_free,
75
+ ossl_sslctx_mark, ossl_sslctx_free,
71
76
  },
72
77
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
73
78
  };
@@ -83,7 +88,7 @@ ossl_sslctx_s_alloc(VALUE klass)
83
88
  VALUE obj;
84
89
 
85
90
  obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
86
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
91
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
87
92
  ctx = SSL_CTX_new(TLS_method());
88
93
  #else
89
94
  ctx = SSL_CTX_new(SSLv23_method());
@@ -95,14 +100,15 @@ ossl_sslctx_s_alloc(VALUE klass)
95
100
  RTYPEDDATA_DATA(obj) = ctx;
96
101
  SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj);
97
102
 
98
- #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
103
+ #if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER < 0x10100000 && \
104
+ !defined(LIBRESSL_VERSION_NUMBER)
99
105
  /* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
100
106
  * allows to specify multiple curve names and OpenSSL will select
101
107
  * automatically from them. In OpenSSL 1.0.2, the automatic selection has to
102
- * be enabled explicitly. But OpenSSL 1.1.0 removed the knob and it is
103
- * always enabled. To uniform the behavior, we enable the automatic
104
- * selection also in 1.0.2. Users can still disable ECDH by removing ECDH
105
- * cipher suites by SSLContext#ciphers=. */
108
+ * be enabled explicitly. OpenSSL 1.1.0 and LibreSSL 2.6.1 removed the knob
109
+ * and it is always enabled. To uniform the behavior, we enable the
110
+ * automatic selection also in 1.0.2. Users can still disable ECDH by
111
+ * removing ECDH cipher suites by SSLContext#ciphers=. */
106
112
  if (!SSL_CTX_set_ecdh_auto(ctx, 1))
107
113
  ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
108
114
  #endif
@@ -184,8 +190,10 @@ ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
184
190
 
185
191
  for (i = 0; i < numberof(options_map); i++) {
186
192
  sum |= options_map[i].opts;
187
- if (min && min > options_map[i].ver || max && max < options_map[i].ver)
193
+ if ((min && min > options_map[i].ver) ||
194
+ (max && max < options_map[i].ver)) {
188
195
  opts |= options_map[i].opts;
196
+ }
189
197
  }
190
198
  SSL_CTX_clear_options(ctx, sum);
191
199
  SSL_CTX_set_options(ctx, opts);
@@ -229,8 +237,7 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
229
237
  return 1;
230
238
  }
231
239
 
232
- #if !defined(OPENSSL_NO_DH) || \
233
- !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
240
+ #if !defined(OPENSSL_NO_DH)
234
241
  struct tmp_dh_callback_args {
235
242
  VALUE ssl_obj;
236
243
  ID id;
@@ -239,22 +246,23 @@ struct tmp_dh_callback_args {
239
246
  int keylength;
240
247
  };
241
248
 
242
- static EVP_PKEY *
243
- ossl_call_tmp_dh_callback(struct tmp_dh_callback_args *args)
249
+ static VALUE
250
+ ossl_call_tmp_dh_callback(VALUE arg)
244
251
  {
252
+ struct tmp_dh_callback_args *args = (struct tmp_dh_callback_args *)arg;
245
253
  VALUE cb, dh;
246
254
  EVP_PKEY *pkey;
247
255
 
248
256
  cb = rb_funcall(args->ssl_obj, args->id, 0);
249
257
  if (NIL_P(cb))
250
- return NULL;
258
+ return (VALUE)NULL;
251
259
  dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
252
260
  INT2NUM(args->keylength));
253
261
  pkey = GetPKeyPtr(dh);
254
262
  if (EVP_PKEY_base_id(pkey) != args->type)
255
- return NULL;
263
+ return (VALUE)NULL;
256
264
 
257
- return pkey;
265
+ return (VALUE)pkey;
258
266
  }
259
267
  #endif
260
268
 
@@ -274,7 +282,7 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
274
282
  args.keylength = keylength;
275
283
  args.type = EVP_PKEY_DH;
276
284
 
277
- pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
285
+ pkey = (EVP_PKEY *)rb_protect(ossl_call_tmp_dh_callback,
278
286
  (VALUE)&args, &state);
279
287
  if (state) {
280
288
  rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
@@ -287,35 +295,6 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
287
295
  }
288
296
  #endif /* OPENSSL_NO_DH */
289
297
 
290
- #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
291
- static EC_KEY *
292
- ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
293
- {
294
- VALUE rb_ssl;
295
- EVP_PKEY *pkey;
296
- struct tmp_dh_callback_args args;
297
- int state;
298
-
299
- rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
300
- args.ssl_obj = rb_ssl;
301
- args.id = id_tmp_ecdh_callback;
302
- args.is_export = is_export;
303
- args.keylength = keylength;
304
- args.type = EVP_PKEY_EC;
305
-
306
- pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback,
307
- (VALUE)&args, &state);
308
- if (state) {
309
- rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
310
- return NULL;
311
- }
312
- if (!pkey)
313
- return NULL;
314
-
315
- return EVP_PKEY_get0_EC_KEY(pkey);
316
- }
317
- #endif
318
-
319
298
  static VALUE
320
299
  call_verify_certificate_identity(VALUE ctx_v)
321
300
  {
@@ -357,7 +336,14 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
357
336
  rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
358
337
  return 0;
359
338
  }
360
- preverify_ok = ret == Qtrue;
339
+ if (ret != Qtrue) {
340
+ preverify_ok = 0;
341
+ #if defined(X509_V_ERR_HOSTNAME_MISMATCH)
342
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
343
+ #else
344
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
345
+ #endif
346
+ }
361
347
  }
362
348
 
363
349
  return ossl_verify_cb_call(cb, preverify_ok, ctx);
@@ -378,7 +364,7 @@ ossl_call_session_get_cb(VALUE ary)
378
364
  }
379
365
 
380
366
  static SSL_SESSION *
381
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
367
+ #if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
382
368
  ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
383
369
  #else
384
370
  ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
@@ -587,10 +573,8 @@ ssl_renegotiation_cb(const SSL *ssl)
587
573
  rb_funcallv(cb, id_call, 1, &ssl_obj);
588
574
  }
589
575
 
590
- #if !defined(OPENSSL_NO_NEXTPROTONEG) || \
591
- defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
592
576
  static VALUE
593
- ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
577
+ ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
594
578
  {
595
579
  int len = RSTRING_LENINT(cur);
596
580
  char len_byte;
@@ -607,7 +591,7 @@ static VALUE
607
591
  ssl_encode_npn_protocols(VALUE protocols)
608
592
  {
609
593
  VALUE encoded = rb_str_new(NULL, 0);
610
- rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded);
594
+ rb_block_call(protocols, id_each, 0, 0, ssl_npn_encode_protocol_i, encoded);
611
595
  return encoded;
612
596
  }
613
597
 
@@ -670,14 +654,13 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
670
654
 
671
655
  return SSL_TLSEXT_ERR_OK;
672
656
  }
673
- #endif
674
657
 
675
658
  #ifndef OPENSSL_NO_NEXTPROTONEG
676
659
  static int
677
660
  ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
678
661
  void *arg)
679
662
  {
680
- VALUE protocols = (VALUE)arg;
663
+ VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded);
681
664
 
682
665
  *out = (const unsigned char *) RSTRING_PTR(protocols);
683
666
  *outlen = RSTRING_LENINT(protocols);
@@ -699,7 +682,6 @@ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
699
682
  }
700
683
  #endif
701
684
 
702
- #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
703
685
  static int
704
686
  ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
705
687
  const unsigned char *in, unsigned int inlen, void *arg)
@@ -711,7 +693,6 @@ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
711
693
 
712
694
  return ssl_npn_select_cb_common(ssl, cb, out, outlen, in, inlen);
713
695
  }
714
- #endif
715
696
 
716
697
  /* This function may serve as the entry point to support further callbacks. */
717
698
  static void
@@ -788,41 +769,15 @@ ossl_sslctx_setup(VALUE self)
788
769
  SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
789
770
  #endif
790
771
 
791
- #if !defined(OPENSSL_NO_EC)
792
- /* We added SSLContext#tmp_ecdh_callback= in Ruby 2.3.0,
793
- * but SSL_CTX_set_tmp_ecdh_callback() was removed in OpenSSL 1.1.0. */
794
- if (RTEST(rb_attr_get(self, id_i_tmp_ecdh_callback))) {
795
- # if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
796
- rb_warn("#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
797
- SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
798
- # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
799
- /* tmp_ecdh_callback and ecdh_auto conflict; OpenSSL ignores
800
- * tmp_ecdh_callback. So disable ecdh_auto. */
801
- if (!SSL_CTX_set_ecdh_auto(ctx, 0))
802
- ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
803
- # endif
804
- # else
805
- ossl_raise(eSSLError, "OpenSSL does not support tmp_ecdh_callback; "
806
- "use #ecdh_curves= instead");
807
- # endif
808
- }
809
- #endif /* OPENSSL_NO_EC */
772
+ #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
773
+ SSL_CTX_set_post_handshake_auth(ctx, 1);
774
+ #endif
810
775
 
811
776
  val = rb_attr_get(self, id_i_cert_store);
812
777
  if (!NIL_P(val)) {
813
778
  X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
814
779
  SSL_CTX_set_cert_store(ctx, store);
815
- #if !defined(HAVE_X509_STORE_UP_REF)
816
- /*
817
- * WORKAROUND:
818
- * X509_STORE can count references, but
819
- * X509_STORE_free() doesn't care it.
820
- * So we won't increment it but mark it by ex_data.
821
- */
822
- SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
823
- #else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
824
780
  X509_STORE_up_ref(store);
825
- #endif
826
781
  }
827
782
 
828
783
  val = rb_attr_get(self, id_i_extra_chain_cert);
@@ -873,10 +828,17 @@ ossl_sslctx_setup(VALUE self)
873
828
  ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
874
829
  val = rb_attr_get(self, id_i_ca_path);
875
830
  ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
831
+ #ifdef HAVE_SSL_CTX_LOAD_VERIFY_FILE
832
+ if (ca_file && !SSL_CTX_load_verify_file(ctx, ca_file))
833
+ ossl_raise(eSSLError, "SSL_CTX_load_verify_file");
834
+ if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path))
835
+ ossl_raise(eSSLError, "SSL_CTX_load_verify_dir");
836
+ #else
876
837
  if(ca_file || ca_path){
877
838
  if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
878
839
  rb_warning("can't set verify locations");
879
840
  }
841
+ #endif
880
842
 
881
843
  val = rb_attr_get(self, id_i_verify_mode);
882
844
  verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
@@ -895,7 +857,7 @@ ossl_sslctx_setup(VALUE self)
895
857
  if (!NIL_P(val)) {
896
858
  VALUE encoded = ssl_encode_npn_protocols(val);
897
859
  rb_ivar_set(self, id_npn_protocols_encoded, encoded);
898
- SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)encoded);
860
+ SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
899
861
  OSSL_Debug("SSL NPN advertise callback added");
900
862
  }
901
863
  if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
@@ -904,7 +866,6 @@ ossl_sslctx_setup(VALUE self)
904
866
  }
905
867
  #endif
906
868
 
907
- #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
908
869
  val = rb_attr_get(self, id_i_alpn_protocols);
909
870
  if (!NIL_P(val)) {
910
871
  VALUE rprotos = ssl_encode_npn_protocols(val);
@@ -919,7 +880,6 @@ ossl_sslctx_setup(VALUE self)
919
880
  SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
920
881
  OSSL_Debug("SSL ALPN select callback added");
921
882
  }
922
- #endif
923
883
 
924
884
  rb_obj_freeze(self);
925
885
 
@@ -1041,6 +1001,52 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1041
1001
  return v;
1042
1002
  }
1043
1003
 
1004
+ #ifndef OPENSSL_NO_DH
1005
+ /*
1006
+ * call-seq:
1007
+ * ctx.tmp_dh = pkey
1008
+ *
1009
+ * Sets DH parameters used for ephemeral DH key exchange. This is relevant for
1010
+ * servers only.
1011
+ *
1012
+ * +pkey+ is an instance of OpenSSL::PKey::DH. Note that key components
1013
+ * contained in the key object, if any, are ignored. The server will always
1014
+ * generate a new key pair for each handshake.
1015
+ *
1016
+ * Added in version 3.0. See also the man page SSL_set0_tmp_dh_pkey(3).
1017
+ *
1018
+ * Example:
1019
+ * ctx = OpenSSL::SSL::SSLContext.new
1020
+ * ctx.tmp_dh = OpenSSL::DH.generate(2048)
1021
+ * svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx)
1022
+ * Thread.new { svr.accept }
1023
+ */
1024
+ static VALUE
1025
+ ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg)
1026
+ {
1027
+ SSL_CTX *ctx;
1028
+ EVP_PKEY *pkey;
1029
+
1030
+ rb_check_frozen(self);
1031
+ GetSSLCTX(self, ctx);
1032
+ pkey = GetPKeyPtr(arg);
1033
+
1034
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH)
1035
+ rb_raise(eSSLError, "invalid pkey type %s (expected DH)",
1036
+ OBJ_nid2sn(EVP_PKEY_base_id(pkey)));
1037
+ #ifdef HAVE_SSL_SET0_TMP_DH_PKEY
1038
+ if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkey))
1039
+ ossl_raise(eSSLError, "SSL_CTX_set0_tmp_dh_pkey");
1040
+ EVP_PKEY_up_ref(pkey);
1041
+ #else
1042
+ if (!SSL_CTX_set_tmp_dh(ctx, EVP_PKEY_get0_DH(pkey)))
1043
+ ossl_raise(eSSLError, "SSL_CTX_set_tmp_dh");
1044
+ #endif
1045
+
1046
+ return arg;
1047
+ }
1048
+ #endif
1049
+
1044
1050
  #if !defined(OPENSSL_NO_EC)
1045
1051
  /*
1046
1052
  * call-seq:
@@ -1052,9 +1058,6 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1052
1058
  * Extension. For a server, the list is used by OpenSSL to determine the set of
1053
1059
  * shared curves. OpenSSL will pick the most appropriate one from it.
1054
1060
  *
1055
- * Note that this works differently with old OpenSSL (<= 1.0.1). Only one curve
1056
- * can be set, and this has no effect for TLS clients.
1057
- *
1058
1061
  * === Example
1059
1062
  * ctx1 = OpenSSL::SSL::SSLContext.new
1060
1063
  * ctx1.ecdh_curves = "X25519:P-256:P-224"
@@ -1078,48 +1081,8 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
1078
1081
  GetSSLCTX(self, ctx);
1079
1082
  StringValueCStr(arg);
1080
1083
 
1081
- #if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
1082
1084
  if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
1083
1085
  ossl_raise(eSSLError, NULL);
1084
- #else
1085
- /* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to
1086
- * SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */
1087
- {
1088
- VALUE curve, splitted;
1089
- EC_KEY *ec;
1090
- int nid;
1091
-
1092
- splitted = rb_str_split(arg, ":");
1093
- if (!RARRAY_LEN(splitted))
1094
- ossl_raise(eSSLError, "invalid input format");
1095
- curve = RARRAY_AREF(splitted, 0);
1096
- StringValueCStr(curve);
1097
-
1098
- /* SSL_CTX_set1_curves_list() accepts NIST names */
1099
- nid = EC_curve_nist2nid(RSTRING_PTR(curve));
1100
- if (nid == NID_undef)
1101
- nid = OBJ_txt2nid(RSTRING_PTR(curve));
1102
- if (nid == NID_undef)
1103
- ossl_raise(eSSLError, "unknown curve name");
1104
-
1105
- ec = EC_KEY_new_by_curve_name(nid);
1106
- if (!ec)
1107
- ossl_raise(eSSLError, NULL);
1108
- EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
1109
- if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) {
1110
- EC_KEY_free(ec);
1111
- ossl_raise(eSSLError, "SSL_CTX_set_tmp_ecdh");
1112
- }
1113
- EC_KEY_free(ec);
1114
- # if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
1115
- /* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto
1116
- * is enabled. So disable ecdh_auto. */
1117
- if (!SSL_CTX_set_ecdh_auto(ctx, 0))
1118
- ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
1119
- # endif
1120
- }
1121
- #endif
1122
-
1123
1086
  return arg;
1124
1087
  }
1125
1088
  #else
@@ -1210,7 +1173,7 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
1210
1173
 
1211
1174
  /*
1212
1175
  * call-seq:
1213
- * ctx.add_certificate(certiticate, pkey [, extra_certs]) -> self
1176
+ * ctx.add_certificate(certificate, pkey [, extra_certs]) -> self
1214
1177
  *
1215
1178
  * Adds a certificate to the context. _pkey_ must be a corresponding private
1216
1179
  * key with _certificate_.
@@ -1242,10 +1205,6 @@ ossl_sslctx_enable_fallback_scsv(VALUE self)
1242
1205
  * ecdsa_pkey = ...
1243
1206
  * another_ca_cert = ...
1244
1207
  * ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])
1245
- *
1246
- * === Note
1247
- * OpenSSL before the version 1.0.2 could handle only one extra chain across
1248
- * all key types. Calling this method discards the chain set previously.
1249
1208
  */
1250
1209
  static VALUE
1251
1210
  ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
@@ -1270,7 +1229,7 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
1270
1229
  EVP_PKEY_free(pub_pkey);
1271
1230
  if (!pub_pkey)
1272
1231
  rb_raise(rb_eArgError, "certificate does not contain public key");
1273
- if (EVP_PKEY_cmp(pub_pkey, pkey) != 1)
1232
+ if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
1274
1233
  rb_raise(rb_eArgError, "public key mismatch");
1275
1234
 
1276
1235
  if (argc >= 3)
@@ -1284,34 +1243,9 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
1284
1243
  sk_X509_pop_free(extra_chain, X509_free);
1285
1244
  ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
1286
1245
  }
1287
-
1288
- if (extra_chain) {
1289
- #if OPENSSL_VERSION_NUMBER >= 0x10002000 && !defined(LIBRESSL_VERSION_NUMBER)
1290
- if (!SSL_CTX_set0_chain(ctx, extra_chain)) {
1291
- sk_X509_pop_free(extra_chain, X509_free);
1292
- ossl_raise(eSSLError, "SSL_CTX_set0_chain");
1293
- }
1294
- #else
1295
- STACK_OF(X509) *orig_extra_chain;
1296
- X509 *x509_tmp;
1297
-
1298
- /* First, clear the existing chain */
1299
- SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain);
1300
- if (orig_extra_chain && sk_X509_num(orig_extra_chain)) {
1301
- rb_warning("SSL_CTX_set0_chain() is not available; " \
1302
- "clearing previously set certificate chain");
1303
- SSL_CTX_clear_extra_chain_certs(ctx);
1304
- }
1305
- while ((x509_tmp = sk_X509_shift(extra_chain))) {
1306
- /* Transfers ownership */
1307
- if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) {
1308
- X509_free(x509_tmp);
1309
- sk_X509_pop_free(extra_chain, X509_free);
1310
- ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert");
1311
- }
1312
- }
1313
- sk_X509_free(extra_chain);
1314
- #endif
1246
+ if (extra_chain && !SSL_CTX_set0_chain(ctx, extra_chain)) {
1247
+ sk_X509_pop_free(extra_chain, X509_free);
1248
+ ossl_raise(eSSLError, "SSL_CTX_set0_chain");
1315
1249
  }
1316
1250
  return self;
1317
1251
  }
@@ -1509,8 +1443,16 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
1509
1443
  static inline int
1510
1444
  ssl_started(SSL *ssl)
1511
1445
  {
1512
- /* the FD is set in ossl_ssl_setup(), called by #connect or #accept */
1513
- return SSL_get_fd(ssl) >= 0;
1446
+ /* BIO is created through ossl_ssl_setup(), called by #connect or #accept */
1447
+ return SSL_get_rbio(ssl) != NULL;
1448
+ }
1449
+
1450
+ static void
1451
+ ossl_ssl_mark(void *ptr)
1452
+ {
1453
+ SSL *ssl = ptr;
1454
+ rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
1455
+ rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
1514
1456
  }
1515
1457
 
1516
1458
  static void
@@ -1522,7 +1464,7 @@ ossl_ssl_free(void *ssl)
1522
1464
  const rb_data_type_t ossl_ssl_type = {
1523
1465
  "OpenSSL/SSL",
1524
1466
  {
1525
- 0, ossl_ssl_free,
1467
+ ossl_ssl_mark, ossl_ssl_free,
1526
1468
  },
1527
1469
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
1528
1470
  };
@@ -1533,6 +1475,29 @@ ossl_ssl_s_alloc(VALUE klass)
1533
1475
  return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
1534
1476
  }
1535
1477
 
1478
+ static VALUE
1479
+ peer_ip_address(VALUE self)
1480
+ {
1481
+ VALUE remote_address = rb_funcall(rb_attr_get(self, id_i_io), rb_intern("remote_address"), 0);
1482
+
1483
+ return rb_funcall(remote_address, rb_intern("inspect_sockaddr"), 0);
1484
+ }
1485
+
1486
+ static VALUE
1487
+ fallback_peer_ip_address(VALUE self, VALUE args)
1488
+ {
1489
+ return rb_str_new_cstr("(null)");
1490
+ }
1491
+
1492
+ static VALUE
1493
+ peeraddr_ip_str(VALUE self)
1494
+ {
1495
+ VALUE rb_mErrno = rb_const_get(rb_cObject, rb_intern("Errno"));
1496
+ VALUE rb_eSystemCallError = rb_const_get(rb_mErrno, rb_intern("SystemCallError"));
1497
+
1498
+ return rb_rescue2(peer_ip_address, self, fallback_peer_ip_address, (VALUE)0, rb_eSystemCallError, NULL);
1499
+ }
1500
+
1536
1501
  /*
1537
1502
  * call-seq:
1538
1503
  * SSLSocket.new(io) => aSSLSocket
@@ -1569,6 +1534,7 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1569
1534
 
1570
1535
  if (rb_respond_to(io, rb_intern("nonblock=")))
1571
1536
  rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
1537
+ Check_Type(io, T_FILE);
1572
1538
  rb_ivar_set(self, id_i_io, io);
1573
1539
 
1574
1540
  ssl = SSL_new(ctx);
@@ -1636,6 +1602,26 @@ no_exception_p(VALUE opts)
1636
1602
  return 0;
1637
1603
  }
1638
1604
 
1605
+ static void
1606
+ io_wait_writable(rb_io_t *fptr)
1607
+ {
1608
+ #ifdef HAVE_RB_IO_MAYBE_WAIT
1609
+ rb_io_maybe_wait_writable(errno, fptr->self, Qnil);
1610
+ #else
1611
+ rb_io_wait_writable(fptr->fd);
1612
+ #endif
1613
+ }
1614
+
1615
+ static void
1616
+ io_wait_readable(rb_io_t *fptr)
1617
+ {
1618
+ #ifdef HAVE_RB_IO_MAYBE_WAIT
1619
+ rb_io_maybe_wait_readable(errno, fptr->self, Qnil);
1620
+ #else
1621
+ rb_io_wait_readable(fptr->fd);
1622
+ #endif
1623
+ }
1624
+
1639
1625
  static VALUE
1640
1626
  ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1641
1627
  {
@@ -1670,16 +1656,23 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1670
1656
  case SSL_ERROR_WANT_WRITE:
1671
1657
  if (no_exception_p(opts)) { return sym_wait_writable; }
1672
1658
  write_would_block(nonblock);
1673
- rb_io_wait_writable(fptr->fd);
1659
+ io_wait_writable(fptr);
1674
1660
  continue;
1675
1661
  case SSL_ERROR_WANT_READ:
1676
1662
  if (no_exception_p(opts)) { return sym_wait_readable; }
1677
1663
  read_would_block(nonblock);
1678
- rb_io_wait_readable(fptr->fd);
1664
+ io_wait_readable(fptr);
1679
1665
  continue;
1680
1666
  case SSL_ERROR_SYSCALL:
1667
+ #ifdef __APPLE__
1668
+ /* See ossl_ssl_write_internal() */
1669
+ if (errno == EPROTOTYPE)
1670
+ continue;
1671
+ #endif
1681
1672
  if (errno) rb_sys_fail(funcname);
1682
- ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
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
+
1683
1676
  #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1684
1677
  case SSL_ERROR_SSL:
1685
1678
  err = ERR_peek_last_error();
@@ -1692,13 +1685,15 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1692
1685
  if (!verify_msg)
1693
1686
  verify_msg = "(null)";
1694
1687
  ossl_clear_error(); /* let ossl_raise() not append message */
1695
- ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s: %s (%s)",
1696
- funcname, ret2, errno, SSL_state_string_long(ssl),
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),
1697
1690
  err_msg, verify_msg);
1698
1691
  }
1699
1692
  #endif
1693
+ /* fallthrough */
1700
1694
  default:
1701
- ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
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));
1702
1697
  }
1703
1698
  }
1704
1699
 
@@ -1709,8 +1704,7 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1709
1704
  * call-seq:
1710
1705
  * ssl.connect => self
1711
1706
  *
1712
- * Initiates an SSL/TLS handshake with a server. The handshake may be started
1713
- * after unencrypted data has been sent over the socket.
1707
+ * Initiates an SSL/TLS handshake with a server.
1714
1708
  */
1715
1709
  static VALUE
1716
1710
  ossl_ssl_connect(VALUE self)
@@ -1757,8 +1751,7 @@ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
1757
1751
  * call-seq:
1758
1752
  * ssl.accept => self
1759
1753
  *
1760
- * Waits for a SSL/TLS client to initiate a handshake. The handshake may be
1761
- * started after unencrypted data has been sent over the socket.
1754
+ * Waits for a SSL/TLS client to initiate a handshake.
1762
1755
  */
1763
1756
  static VALUE
1764
1757
  ossl_ssl_accept(VALUE self)
@@ -1805,7 +1798,7 @@ static VALUE
1805
1798
  ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1806
1799
  {
1807
1800
  SSL *ssl;
1808
- int ilen, nread = 0;
1801
+ int ilen;
1809
1802
  VALUE len, str;
1810
1803
  rb_io_t *fptr;
1811
1804
  VALUE io, opts = Qnil;
@@ -1815,6 +1808,9 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1815
1808
  } else {
1816
1809
  rb_scan_args(argc, argv, "11", &len, &str);
1817
1810
  }
1811
+ GetSSL(self, ssl);
1812
+ if (!ssl_started(ssl))
1813
+ rb_raise(eSSLError, "SSL session is not started yet");
1818
1814
 
1819
1815
  ilen = NUM2INT(len);
1820
1816
  if (NIL_P(str))
@@ -1826,67 +1822,64 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1826
1822
  else
1827
1823
  rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
1828
1824
  }
1829
- OBJ_TAINT(str);
1830
1825
  rb_str_set_len(str, 0);
1831
1826
  if (ilen == 0)
1832
1827
  return str;
1833
1828
 
1834
- GetSSL(self, ssl);
1835
1829
  io = rb_attr_get(self, id_i_io);
1836
1830
  GetOpenFile(io, fptr);
1837
- if (ssl_started(ssl)) {
1838
- for (;;){
1839
- nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1840
- switch(ssl_get_error(ssl, nread)){
1841
- case SSL_ERROR_NONE:
1842
- goto end;
1843
- case SSL_ERROR_ZERO_RETURN:
1844
- if (no_exception_p(opts)) { return Qnil; }
1845
- rb_eof_error();
1846
- case SSL_ERROR_WANT_WRITE:
1847
- if (no_exception_p(opts)) { return sym_wait_writable; }
1831
+
1832
+ rb_str_locktmp(str);
1833
+ for (;;) {
1834
+ int nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1835
+ switch (ssl_get_error(ssl, nread)) {
1836
+ case SSL_ERROR_NONE:
1837
+ rb_str_unlocktmp(str);
1838
+ rb_str_set_len(str, nread);
1839
+ return str;
1840
+ case SSL_ERROR_ZERO_RETURN:
1841
+ rb_str_unlocktmp(str);
1842
+ if (no_exception_p(opts)) { return Qnil; }
1843
+ rb_eof_error();
1844
+ case SSL_ERROR_WANT_WRITE:
1845
+ if (nonblock) {
1846
+ rb_str_unlocktmp(str);
1847
+ if (no_exception_p(opts)) { return sym_wait_writable; }
1848
1848
  write_would_block(nonblock);
1849
- rb_io_wait_writable(fptr->fd);
1850
- continue;
1851
- case SSL_ERROR_WANT_READ:
1852
- if (no_exception_p(opts)) { return sym_wait_readable; }
1849
+ }
1850
+ io_wait_writable(fptr);
1851
+ continue;
1852
+ case SSL_ERROR_WANT_READ:
1853
+ if (nonblock) {
1854
+ rb_str_unlocktmp(str);
1855
+ if (no_exception_p(opts)) { return sym_wait_readable; }
1853
1856
  read_would_block(nonblock);
1854
- rb_io_wait_readable(fptr->fd);
1855
- continue;
1856
- case SSL_ERROR_SYSCALL:
1857
- if (!ERR_peek_error()) {
1858
- if (errno)
1859
- rb_sys_fail(0);
1860
- else {
1861
- /*
1862
- * The underlying BIO returned 0. This is actually a
1863
- * protocol error. But unfortunately, not all
1864
- * implementations cleanly shutdown the TLS connection
1865
- * but just shutdown/close the TCP connection. So report
1866
- * EOF for now...
1867
- */
1868
- if (no_exception_p(opts)) { return Qnil; }
1869
- rb_eof_error();
1870
- }
1871
- }
1872
- default:
1873
- ossl_raise(eSSLError, "SSL_read");
1874
- }
1857
+ }
1858
+ io_wait_readable(fptr);
1859
+ continue;
1860
+ case SSL_ERROR_SYSCALL:
1861
+ if (!ERR_peek_error()) {
1862
+ rb_str_unlocktmp(str);
1863
+ if (errno)
1864
+ rb_sys_fail(0);
1865
+ else {
1866
+ /*
1867
+ * The underlying BIO returned 0. This is actually a
1868
+ * protocol error. But unfortunately, not all
1869
+ * implementations cleanly shutdown the TLS connection
1870
+ * but just shutdown/close the TCP connection. So report
1871
+ * EOF for now...
1872
+ */
1873
+ if (no_exception_p(opts)) { return Qnil; }
1874
+ rb_eof_error();
1875
+ }
1876
+ }
1877
+ /* fall through */
1878
+ default:
1879
+ rb_str_unlocktmp(str);
1880
+ ossl_raise(eSSLError, "SSL_read");
1875
1881
  }
1876
1882
  }
1877
- else {
1878
- ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
1879
-
1880
- rb_warning("SSL session is not started yet.");
1881
- if (nonblock)
1882
- return rb_funcall(io, meth, 3, len, str, opts);
1883
- else
1884
- return rb_funcall(io, meth, 2, len, str);
1885
- }
1886
-
1887
- end:
1888
- rb_str_set_len(str, nread);
1889
- return str;
1890
1883
  }
1891
1884
 
1892
1885
  /*
@@ -1926,57 +1919,55 @@ static VALUE
1926
1919
  ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1927
1920
  {
1928
1921
  SSL *ssl;
1929
- int nwrite = 0;
1930
1922
  rb_io_t *fptr;
1931
- int nonblock = opts != Qfalse;
1932
- VALUE io;
1923
+ int num, nonblock = opts != Qfalse;
1924
+ VALUE tmp, io;
1933
1925
 
1934
- StringValue(str);
1935
1926
  GetSSL(self, ssl);
1927
+ if (!ssl_started(ssl))
1928
+ rb_raise(eSSLError, "SSL session is not started yet");
1929
+
1930
+ tmp = rb_str_new_frozen(StringValue(str));
1936
1931
  io = rb_attr_get(self, id_i_io);
1937
1932
  GetOpenFile(io, fptr);
1938
- if (ssl_started(ssl)) {
1939
- for (;;){
1940
- int num = RSTRING_LENINT(str);
1941
-
1942
- /* SSL_write(3ssl) manpage states num == 0 is undefined */
1943
- if (num == 0)
1944
- goto end;
1945
-
1946
- nwrite = SSL_write(ssl, RSTRING_PTR(str), num);
1947
- switch(ssl_get_error(ssl, nwrite)){
1948
- case SSL_ERROR_NONE:
1949
- goto end;
1950
- case SSL_ERROR_WANT_WRITE:
1951
- if (no_exception_p(opts)) { return sym_wait_writable; }
1952
- write_would_block(nonblock);
1953
- rb_io_wait_writable(fptr->fd);
1954
- continue;
1955
- case SSL_ERROR_WANT_READ:
1956
- if (no_exception_p(opts)) { return sym_wait_readable; }
1957
- read_would_block(nonblock);
1958
- rb_io_wait_readable(fptr->fd);
1933
+
1934
+ /* SSL_write(3ssl) manpage states num == 0 is undefined */
1935
+ num = RSTRING_LENINT(tmp);
1936
+ if (num == 0)
1937
+ return INT2FIX(0);
1938
+
1939
+ for (;;) {
1940
+ int nwritten = SSL_write(ssl, RSTRING_PTR(tmp), num);
1941
+ switch (ssl_get_error(ssl, nwritten)) {
1942
+ case SSL_ERROR_NONE:
1943
+ return INT2NUM(nwritten);
1944
+ case SSL_ERROR_WANT_WRITE:
1945
+ if (no_exception_p(opts)) { return sym_wait_writable; }
1946
+ write_would_block(nonblock);
1947
+ io_wait_writable(fptr);
1948
+ continue;
1949
+ case SSL_ERROR_WANT_READ:
1950
+ if (no_exception_p(opts)) { return sym_wait_readable; }
1951
+ read_would_block(nonblock);
1952
+ io_wait_readable(fptr);
1953
+ continue;
1954
+ case SSL_ERROR_SYSCALL:
1955
+ #ifdef __APPLE__
1956
+ /*
1957
+ * It appears that send syscall can return EPROTOTYPE if the
1958
+ * socket is being torn down. Retry to get a proper errno to
1959
+ * make the error handling in line with the socket library.
1960
+ * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
1961
+ */
1962
+ if (errno == EPROTOTYPE)
1959
1963
  continue;
1960
- case SSL_ERROR_SYSCALL:
1961
- if (errno) rb_sys_fail(0);
1962
- default:
1963
- ossl_raise(eSSLError, "SSL_write");
1964
- }
1964
+ #endif
1965
+ if (errno) rb_sys_fail(0);
1966
+ /* fallthrough */
1967
+ default:
1968
+ ossl_raise(eSSLError, "SSL_write");
1965
1969
  }
1966
1970
  }
1967
- else {
1968
- ID meth = nonblock ?
1969
- rb_intern("write_nonblock") : rb_intern("syswrite");
1970
-
1971
- rb_warning("SSL session is not started yet.");
1972
- if (nonblock)
1973
- return rb_funcall(io, meth, 2, str, opts);
1974
- else
1975
- return rb_funcall(io, meth, 1, str);
1976
- }
1977
-
1978
- end:
1979
- return INT2NUM(nwrite);
1980
1971
  }
1981
1972
 
1982
1973
  /*
@@ -2275,7 +2266,57 @@ ossl_ssl_get_verify_result(VALUE self)
2275
2266
 
2276
2267
  GetSSL(self, ssl);
2277
2268
 
2278
- return INT2NUM(SSL_get_verify_result(ssl));
2269
+ return LONG2NUM(SSL_get_verify_result(ssl));
2270
+ }
2271
+
2272
+ /*
2273
+ * call-seq:
2274
+ * ssl.finished_message => "finished message"
2275
+ *
2276
+ * Returns the last *Finished* message sent
2277
+ *
2278
+ */
2279
+ static VALUE
2280
+ ossl_ssl_get_finished(VALUE self)
2281
+ {
2282
+ SSL *ssl;
2283
+ char sizer[1], *buf;
2284
+ size_t len;
2285
+
2286
+ GetSSL(self, ssl);
2287
+
2288
+ len = SSL_get_finished(ssl, sizer, 0);
2289
+ if (len == 0)
2290
+ return Qnil;
2291
+
2292
+ buf = ALLOCA_N(char, len);
2293
+ SSL_get_finished(ssl, buf, len);
2294
+ return rb_str_new(buf, len);
2295
+ }
2296
+
2297
+ /*
2298
+ * call-seq:
2299
+ * ssl.peer_finished_message => "peer finished message"
2300
+ *
2301
+ * Returns the last *Finished* message received
2302
+ *
2303
+ */
2304
+ static VALUE
2305
+ ossl_ssl_get_peer_finished(VALUE self)
2306
+ {
2307
+ SSL *ssl;
2308
+ char sizer[1], *buf;
2309
+ size_t len;
2310
+
2311
+ GetSSL(self, ssl);
2312
+
2313
+ len = SSL_get_peer_finished(ssl, sizer, 0);
2314
+ if (len == 0)
2315
+ return Qnil;
2316
+
2317
+ buf = ALLOCA_N(char, len);
2318
+ SSL_get_peer_finished(ssl, buf, len);
2319
+ return rb_str_new(buf, len);
2279
2320
  }
2280
2321
 
2281
2322
  /*
@@ -2326,7 +2367,6 @@ ossl_ssl_npn_protocol(VALUE self)
2326
2367
  }
2327
2368
  # endif
2328
2369
 
2329
- # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2330
2370
  /*
2331
2371
  * call-seq:
2332
2372
  * ssl.alpn_protocol => String | nil
@@ -2349,9 +2389,7 @@ ossl_ssl_alpn_protocol(VALUE self)
2349
2389
  else
2350
2390
  return rb_str_new((const char *) out, outlen);
2351
2391
  }
2352
- # endif
2353
2392
 
2354
- # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2355
2393
  /*
2356
2394
  * call-seq:
2357
2395
  * ssl.tmp_key => PKey or nil
@@ -2369,11 +2407,8 @@ ossl_ssl_tmp_key(VALUE self)
2369
2407
  return Qnil;
2370
2408
  return ossl_pkey_new(key);
2371
2409
  }
2372
- # endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */
2373
2410
  #endif /* !defined(OPENSSL_NO_SOCK) */
2374
2411
 
2375
- #undef rb_intern
2376
- #define rb_intern(s) rb_intern_const(s)
2377
2412
  void
2378
2413
  Init_ossl_ssl(void)
2379
2414
  {
@@ -2384,8 +2419,8 @@ Init_ossl_ssl(void)
2384
2419
  rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
2385
2420
  #endif
2386
2421
 
2387
- id_call = rb_intern("call");
2388
- ID_callback_state = rb_intern("callback_state");
2422
+ id_call = rb_intern_const("call");
2423
+ ID_callback_state = rb_intern_const("callback_state");
2389
2424
 
2390
2425
  ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0);
2391
2426
  if (ossl_ssl_ex_vcb_idx < 0)
@@ -2396,11 +2431,6 @@ Init_ossl_ssl(void)
2396
2431
  ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2397
2432
  if (ossl_sslctx_ex_ptr_idx < 0)
2398
2433
  ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2399
- #if !defined(HAVE_X509_STORE_UP_REF)
2400
- ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_store_p", 0, 0, 0);
2401
- if (ossl_sslctx_ex_store_p < 0)
2402
- ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2403
- #endif
2404
2434
 
2405
2435
  /* Document-module: OpenSSL::SSL
2406
2436
  *
@@ -2452,7 +2482,7 @@ Init_ossl_ssl(void)
2452
2482
  * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2453
2483
  * It is recommended to use #add_certificate instead.
2454
2484
  */
2455
- rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse);
2485
+ rb_attr(cSSLContext, rb_intern_const("cert"), 1, 1, Qfalse);
2456
2486
 
2457
2487
  /*
2458
2488
  * Context private key
@@ -2460,29 +2490,29 @@ Init_ossl_ssl(void)
2460
2490
  * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2461
2491
  * It is recommended to use #add_certificate instead.
2462
2492
  */
2463
- rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse);
2493
+ rb_attr(cSSLContext, rb_intern_const("key"), 1, 1, Qfalse);
2464
2494
 
2465
2495
  /*
2466
2496
  * A certificate or Array of certificates that will be sent to the client.
2467
2497
  */
2468
- rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse);
2498
+ rb_attr(cSSLContext, rb_intern_const("client_ca"), 1, 1, Qfalse);
2469
2499
 
2470
2500
  /*
2471
2501
  * The path to a file containing a PEM-format CA certificate
2472
2502
  */
2473
- rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse);
2503
+ rb_attr(cSSLContext, rb_intern_const("ca_file"), 1, 1, Qfalse);
2474
2504
 
2475
2505
  /*
2476
2506
  * The path to a directory containing CA certificates in PEM format.
2477
2507
  *
2478
2508
  * Files are looked up by subject's X509 name's hash value.
2479
2509
  */
2480
- rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse);
2510
+ rb_attr(cSSLContext, rb_intern_const("ca_path"), 1, 1, Qfalse);
2481
2511
 
2482
2512
  /*
2483
2513
  * Maximum session lifetime in seconds.
2484
2514
  */
2485
- rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse);
2515
+ rb_attr(cSSLContext, rb_intern_const("timeout"), 1, 1, Qfalse);
2486
2516
 
2487
2517
  /*
2488
2518
  * Session verification mode.
@@ -2495,12 +2525,12 @@ Init_ossl_ssl(void)
2495
2525
  *
2496
2526
  * See SSL_CTX_set_verify(3) for details.
2497
2527
  */
2498
- rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse);
2528
+ rb_attr(cSSLContext, rb_intern_const("verify_mode"), 1, 1, Qfalse);
2499
2529
 
2500
2530
  /*
2501
2531
  * Number of CA certificates to walk when verifying a certificate chain.
2502
2532
  */
2503
- rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse);
2533
+ rb_attr(cSSLContext, rb_intern_const("verify_depth"), 1, 1, Qfalse);
2504
2534
 
2505
2535
  /*
2506
2536
  * A callback for additional certificate verification. The callback is
@@ -2514,7 +2544,7 @@ Init_ossl_ssl(void)
2514
2544
  * If the callback returns +false+, the chain verification is immediately
2515
2545
  * stopped and a bad_certificate alert is then sent.
2516
2546
  */
2517
- rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
2547
+ rb_attr(cSSLContext, rb_intern_const("verify_callback"), 1, 1, Qfalse);
2518
2548
 
2519
2549
  /*
2520
2550
  * Whether to check the server certificate is valid for the hostname.
@@ -2522,12 +2552,12 @@ Init_ossl_ssl(void)
2522
2552
  * In order to make this work, verify_mode must be set to VERIFY_PEER and
2523
2553
  * the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=.
2524
2554
  */
2525
- rb_attr(cSSLContext, rb_intern("verify_hostname"), 1, 1, Qfalse);
2555
+ rb_attr(cSSLContext, rb_intern_const("verify_hostname"), 1, 1, Qfalse);
2526
2556
 
2527
2557
  /*
2528
2558
  * An OpenSSL::X509::Store used for certificate verification.
2529
2559
  */
2530
- rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse);
2560
+ rb_attr(cSSLContext, rb_intern_const("cert_store"), 1, 1, Qfalse);
2531
2561
 
2532
2562
  /*
2533
2563
  * An Array of extra X509 certificates to be added to the certificate
@@ -2536,7 +2566,7 @@ Init_ossl_ssl(void)
2536
2566
  * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2537
2567
  * It is recommended to use #add_certificate instead.
2538
2568
  */
2539
- rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse);
2569
+ rb_attr(cSSLContext, rb_intern_const("extra_chain_cert"), 1, 1, Qfalse);
2540
2570
 
2541
2571
  /*
2542
2572
  * A callback invoked when a client certificate is requested by a server
@@ -2546,28 +2576,14 @@ Init_ossl_ssl(void)
2546
2576
  * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any
2547
2577
  * other value is returned the handshake is suspended.
2548
2578
  */
2549
- rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
2550
-
2551
- #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
2552
- /*
2553
- * A callback invoked when ECDH parameters are required.
2554
- *
2555
- * The callback is invoked with the Session for the key exchange, an
2556
- * flag indicating the use of an export cipher and the keylength
2557
- * required.
2558
- *
2559
- * The callback is deprecated. This does not work with recent versions of
2560
- * OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead.
2561
- */
2562
- rb_attr(cSSLContext, rb_intern("tmp_ecdh_callback"), 1, 1, Qfalse);
2563
- #endif
2579
+ rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
2564
2580
 
2565
2581
  /*
2566
2582
  * Sets the context in which a session can be reused. This allows
2567
2583
  * sessions for multiple applications to be distinguished, for example, by
2568
2584
  * name.
2569
2585
  */
2570
- rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse);
2586
+ rb_attr(cSSLContext, rb_intern_const("session_id_context"), 1, 1, Qfalse);
2571
2587
 
2572
2588
  /*
2573
2589
  * A callback invoked on a server when a session is proposed by the client
@@ -2576,7 +2592,7 @@ Init_ossl_ssl(void)
2576
2592
  * The callback is invoked with the SSLSocket and session id. The
2577
2593
  * callback may return a Session from an external cache.
2578
2594
  */
2579
- rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse);
2595
+ rb_attr(cSSLContext, rb_intern_const("session_get_cb"), 1, 1, Qfalse);
2580
2596
 
2581
2597
  /*
2582
2598
  * A callback invoked when a new session was negotiated.
@@ -2584,7 +2600,7 @@ Init_ossl_ssl(void)
2584
2600
  * The callback is invoked with an SSLSocket. If +false+ is returned the
2585
2601
  * session will be removed from the internal cache.
2586
2602
  */
2587
- rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse);
2603
+ rb_attr(cSSLContext, rb_intern_const("session_new_cb"), 1, 1, Qfalse);
2588
2604
 
2589
2605
  /*
2590
2606
  * A callback invoked when a session is removed from the internal cache.
@@ -2595,18 +2611,18 @@ Init_ossl_ssl(void)
2595
2611
  * multi-threaded application. The callback is called inside a global lock
2596
2612
  * and it can randomly cause deadlock on Ruby thread switching.
2597
2613
  */
2598
- rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
2614
+ rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
2599
2615
 
2600
2616
  rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
2601
2617
 
2602
2618
  /*
2603
- * A callback invoked whenever a new handshake is initiated. May be used
2604
- * to disable renegotiation entirely.
2619
+ * A callback invoked whenever a new handshake is initiated on an
2620
+ * established connection. May be used to disable renegotiation entirely.
2605
2621
  *
2606
2622
  * The callback is invoked with the active SSLSocket. The callback's
2607
- * return value is irrelevant, normal return indicates "approval" of the
2623
+ * return value is ignored. A normal return indicates "approval" of the
2608
2624
  * renegotiation and will continue the process. To forbid renegotiation
2609
- * and to cancel the process, an Error may be raised within the callback.
2625
+ * and to cancel the process, raise an exception within the callback.
2610
2626
  *
2611
2627
  * === Disable client renegotiation
2612
2628
  *
@@ -2614,13 +2630,11 @@ Init_ossl_ssl(void)
2614
2630
  * renegotiation entirely. You may use a callback as follows to implement
2615
2631
  * this feature:
2616
2632
  *
2617
- * num_handshakes = 0
2618
2633
  * ctx.renegotiation_cb = lambda do |ssl|
2619
- * num_handshakes += 1
2620
- * raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
2634
+ * raise RuntimeError, "Client renegotiation disabled"
2621
2635
  * end
2622
2636
  */
2623
- rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse);
2637
+ rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
2624
2638
  #ifndef OPENSSL_NO_NEXTPROTONEG
2625
2639
  /*
2626
2640
  * An Enumerable of Strings. Each String represents a protocol to be
@@ -2633,7 +2647,7 @@ Init_ossl_ssl(void)
2633
2647
  *
2634
2648
  * ctx.npn_protocols = ["http/1.1", "spdy/2"]
2635
2649
  */
2636
- rb_attr(cSSLContext, rb_intern("npn_protocols"), 1, 1, Qfalse);
2650
+ rb_attr(cSSLContext, rb_intern_const("npn_protocols"), 1, 1, Qfalse);
2637
2651
  /*
2638
2652
  * A callback invoked on the client side when the client needs to select
2639
2653
  * a protocol from the list sent by the server. Supported in OpenSSL 1.0.1
@@ -2650,10 +2664,9 @@ Init_ossl_ssl(void)
2650
2664
  * protocols.first
2651
2665
  * end
2652
2666
  */
2653
- rb_attr(cSSLContext, rb_intern("npn_select_cb"), 1, 1, Qfalse);
2667
+ rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse);
2654
2668
  #endif
2655
2669
 
2656
- #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2657
2670
  /*
2658
2671
  * An Enumerable of Strings. Each String represents a protocol to be
2659
2672
  * advertised as the list of supported protocols for Application-Layer
@@ -2665,7 +2678,7 @@ Init_ossl_ssl(void)
2665
2678
  *
2666
2679
  * ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"]
2667
2680
  */
2668
- rb_attr(cSSLContext, rb_intern("alpn_protocols"), 1, 1, Qfalse);
2681
+ rb_attr(cSSLContext, rb_intern_const("alpn_protocols"), 1, 1, Qfalse);
2669
2682
  /*
2670
2683
  * A callback invoked on the server side when the server needs to select
2671
2684
  * a protocol from the list sent by the client. Supported in OpenSSL 1.0.2
@@ -2682,8 +2695,7 @@ Init_ossl_ssl(void)
2682
2695
  * protocols.first
2683
2696
  * end
2684
2697
  */
2685
- rb_attr(cSSLContext, rb_intern("alpn_select_cb"), 1, 1, Qfalse);
2686
- #endif
2698
+ rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
2687
2699
 
2688
2700
  rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2689
2701
  rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
@@ -2691,6 +2703,9 @@ Init_ossl_ssl(void)
2691
2703
  ossl_sslctx_set_minmax_proto_version, 2);
2692
2704
  rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2693
2705
  rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
2706
+ #ifndef OPENSSL_NO_DH
2707
+ rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
2708
+ #endif
2694
2709
  rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
2695
2710
  rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
2696
2711
  rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
@@ -2795,12 +2810,10 @@ Init_ossl_ssl(void)
2795
2810
  rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
2796
2811
  /* #hostname is defined in lib/openssl/ssl.rb */
2797
2812
  rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
2798
- # ifdef HAVE_SSL_GET_SERVER_TMP_KEY
2813
+ rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0);
2814
+ rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
2799
2815
  rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
2800
- # endif
2801
- # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2802
2816
  rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
2803
- # endif
2804
2817
  # ifndef OPENSSL_NO_NEXTPROTONEG
2805
2818
  rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2806
2819
  # endif
@@ -2812,12 +2825,23 @@ Init_ossl_ssl(void)
2812
2825
  rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
2813
2826
 
2814
2827
  rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL));
2828
+ #ifdef SSL_OP_CLEANSE_PLAINTEXT /* OpenSSL 3.0 */
2829
+ rb_define_const(mSSL, "OP_CLEANSE_PLAINTEXT", ULONG2NUM(SSL_OP_CLEANSE_PLAINTEXT));
2830
+ #endif
2815
2831
  rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
2816
- #ifdef SSL_OP_TLSEXT_PADDING /* OpenSSL 1.0.1h and OpenSSL 1.0.2 */
2817
- rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
2832
+ #ifdef SSL_OP_ENABLE_KTLS /* OpenSSL 3.0 */
2833
+ rb_define_const(mSSL, "OP_ENABLE_KTLS", ULONG2NUM(SSL_OP_ENABLE_KTLS));
2818
2834
  #endif
2819
- #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG /* OpenSSL 1.0.1f and OpenSSL 1.0.2 */
2835
+ rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
2820
2836
  rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG));
2837
+ #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* OpenSSL 3.0 */
2838
+ rb_define_const(mSSL, "OP_IGNORE_UNEXPECTED_EOF", ULONG2NUM(SSL_OP_IGNORE_UNEXPECTED_EOF));
2839
+ #endif
2840
+ #ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION /* OpenSSL 3.0 */
2841
+ rb_define_const(mSSL, "OP_ALLOW_CLIENT_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_CLIENT_RENEGOTIATION));
2842
+ #endif
2843
+ #ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */
2844
+ rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES));
2821
2845
  #endif
2822
2846
  #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
2823
2847
  rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
@@ -2830,13 +2854,15 @@ Init_ossl_ssl(void)
2830
2854
  #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
2831
2855
  rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
2832
2856
  #endif
2833
- rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
2834
- rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
2835
- #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
2836
- rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
2857
+ #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */
2858
+ rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT));
2859
+ #endif
2860
+ #ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */
2861
+ rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA));
2862
+ #endif
2863
+ #ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */
2864
+ rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY));
2837
2865
  #endif
2838
- rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
2839
-
2840
2866
  rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
2841
2867
  rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
2842
2868
  rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
@@ -2844,6 +2870,12 @@ Init_ossl_ssl(void)
2844
2870
  #ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
2845
2871
  rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
2846
2872
  #endif
2873
+ rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
2874
+ rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
2875
+ #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
2876
+ rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
2877
+ #endif
2878
+ rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
2847
2879
 
2848
2880
  /* SSL_OP_* flags for DTLS */
2849
2881
  #if 0
@@ -2908,16 +2940,16 @@ Init_ossl_ssl(void)
2908
2940
  #endif
2909
2941
 
2910
2942
 
2911
- sym_exception = ID2SYM(rb_intern("exception"));
2912
- sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
2913
- sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
2943
+ sym_exception = ID2SYM(rb_intern_const("exception"));
2944
+ sym_wait_readable = ID2SYM(rb_intern_const("wait_readable"));
2945
+ sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
2914
2946
 
2915
- id_tmp_dh_callback = rb_intern("tmp_dh_callback");
2916
- id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
2917
- id_npn_protocols_encoded = rb_intern("npn_protocols_encoded");
2947
+ id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
2948
+ id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
2949
+ id_each = rb_intern_const("each");
2918
2950
 
2919
2951
  #define DefIVarID(name) do \
2920
- id_i_##name = rb_intern("@"#name); while (0)
2952
+ id_i_##name = rb_intern_const("@"#name); while (0)
2921
2953
 
2922
2954
  DefIVarID(cert_store);
2923
2955
  DefIVarID(ca_file);
@@ -2931,7 +2963,6 @@ Init_ossl_ssl(void)
2931
2963
  DefIVarID(key);
2932
2964
  DefIVarID(extra_chain_cert);
2933
2965
  DefIVarID(client_cert_cb);
2934
- DefIVarID(tmp_ecdh_callback);
2935
2966
  DefIVarID(timeout);
2936
2967
  DefIVarID(session_id_context);
2937
2968
  DefIVarID(session_get_cb);