openssl 3.3.0 → 4.0.1

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -0
  3. data/History.md +156 -0
  4. data/README.md +12 -11
  5. data/ext/openssl/extconf.rb +30 -69
  6. data/ext/openssl/openssl_missing.h +0 -206
  7. data/ext/openssl/ossl.c +280 -301
  8. data/ext/openssl/ossl.h +15 -10
  9. data/ext/openssl/ossl_asn1.c +598 -406
  10. data/ext/openssl/ossl_asn1.h +15 -1
  11. data/ext/openssl/ossl_bio.c +3 -3
  12. data/ext/openssl/ossl_bn.c +286 -291
  13. data/ext/openssl/ossl_cipher.c +257 -209
  14. data/ext/openssl/ossl_cipher.h +10 -1
  15. data/ext/openssl/ossl_config.c +1 -6
  16. data/ext/openssl/ossl_digest.c +74 -43
  17. data/ext/openssl/ossl_digest.h +9 -1
  18. data/ext/openssl/ossl_engine.c +39 -103
  19. data/ext/openssl/ossl_hmac.c +30 -36
  20. data/ext/openssl/ossl_kdf.c +42 -53
  21. data/ext/openssl/ossl_ns_spki.c +31 -37
  22. data/ext/openssl/ossl_ocsp.c +214 -241
  23. data/ext/openssl/ossl_pkcs12.c +26 -26
  24. data/ext/openssl/ossl_pkcs7.c +176 -146
  25. data/ext/openssl/ossl_pkey.c +163 -178
  26. data/ext/openssl/ossl_pkey.h +99 -99
  27. data/ext/openssl/ossl_pkey_dh.c +32 -67
  28. data/ext/openssl/ossl_pkey_dsa.c +16 -53
  29. data/ext/openssl/ossl_pkey_ec.c +181 -237
  30. data/ext/openssl/ossl_pkey_rsa.c +57 -102
  31. data/ext/openssl/ossl_provider.c +0 -7
  32. data/ext/openssl/ossl_rand.c +7 -14
  33. data/ext/openssl/ossl_ssl.c +544 -393
  34. data/ext/openssl/ossl_ssl.h +8 -8
  35. data/ext/openssl/ossl_ssl_session.c +93 -97
  36. data/ext/openssl/ossl_ts.c +81 -127
  37. data/ext/openssl/ossl_x509.c +9 -28
  38. data/ext/openssl/ossl_x509attr.c +33 -54
  39. data/ext/openssl/ossl_x509cert.c +69 -100
  40. data/ext/openssl/ossl_x509crl.c +78 -89
  41. data/ext/openssl/ossl_x509ext.c +45 -66
  42. data/ext/openssl/ossl_x509name.c +63 -88
  43. data/ext/openssl/ossl_x509req.c +55 -62
  44. data/ext/openssl/ossl_x509revoked.c +27 -41
  45. data/ext/openssl/ossl_x509store.c +38 -56
  46. data/lib/openssl/buffering.rb +30 -24
  47. data/lib/openssl/digest.rb +1 -1
  48. data/lib/openssl/pkey.rb +71 -49
  49. data/lib/openssl/ssl.rb +12 -80
  50. data/lib/openssl/version.rb +2 -1
  51. data/lib/openssl/x509.rb +9 -0
  52. data/lib/openssl.rb +9 -6
  53. metadata +3 -8
  54. data/ext/openssl/openssl_missing.c +0 -40
  55. data/lib/openssl/asn1.rb +0 -188
@@ -18,11 +18,6 @@
18
18
  # define OSSL_USE_NEXTPROTONEG
19
19
  #endif
20
20
 
21
- #if !defined(TLS1_3_VERSION) && \
22
- OSSL_LIBRESSL_PREREQ(3, 2, 0) && !OSSL_LIBRESSL_PREREQ(3, 4, 0)
23
- # define TLS1_3_VERSION 0x0304
24
- #endif
25
-
26
21
  #ifdef _WIN32
27
22
  # define TO_SOCKET(s) _get_osfhandle(s)
28
23
  #else
@@ -30,7 +25,7 @@
30
25
  #endif
31
26
 
32
27
  #define GetSSLCTX(obj, ctx) do { \
33
- TypedData_Get_Struct((obj), SSL_CTX, &ossl_sslctx_type, (ctx)); \
28
+ TypedData_Get_Struct((obj), SSL_CTX, &ossl_sslctx_type, (ctx)); \
34
29
  } while (0)
35
30
 
36
31
  VALUE mSSL;
@@ -41,19 +36,18 @@ VALUE cSSLSocket;
41
36
  static VALUE eSSLErrorWaitReadable;
42
37
  static VALUE eSSLErrorWaitWritable;
43
38
 
44
- static ID id_call, ID_callback_state, id_tmp_dh_callback,
45
- id_npn_protocols_encoded, id_each;
39
+ static ID id_call, ID_callback_state, id_npn_protocols_encoded, id_each;
46
40
  static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
47
41
 
48
42
  static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
49
- id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
50
- id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
51
- id_i_client_cert_cb, id_i_timeout,
52
- id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
53
- id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
54
- id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
55
- id_i_verify_hostname, id_i_keylog_cb;
56
- static ID id_i_io, id_i_context, id_i_hostname;
43
+ id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
44
+ id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
45
+ id_i_client_cert_cb, id_i_timeout,
46
+ id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
47
+ id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
48
+ id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
49
+ id_i_verify_hostname, id_i_keylog_cb, id_i_tmp_dh_callback;
50
+ static ID id_i_io, id_i_context, id_i_hostname, id_i_sync_close;
57
51
 
58
52
  static int ossl_ssl_ex_ptr_idx;
59
53
  static int ossl_sslctx_ex_ptr_idx;
@@ -84,127 +78,24 @@ ossl_sslctx_s_alloc(VALUE klass)
84
78
  {
85
79
  SSL_CTX *ctx;
86
80
  long mode = 0 |
87
- SSL_MODE_ENABLE_PARTIAL_WRITE |
88
- SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
89
- SSL_MODE_RELEASE_BUFFERS;
81
+ SSL_MODE_ENABLE_PARTIAL_WRITE |
82
+ SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
83
+ SSL_MODE_RELEASE_BUFFERS;
90
84
  VALUE obj;
91
85
 
92
86
  obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
93
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
94
87
  ctx = SSL_CTX_new(TLS_method());
95
- #else
96
- ctx = SSL_CTX_new(SSLv23_method());
97
- #endif
98
88
  if (!ctx) {
99
89
  ossl_raise(eSSLError, "SSL_CTX_new");
100
90
  }
101
91
  SSL_CTX_set_mode(ctx, mode);
92
+ SSL_CTX_set_dh_auto(ctx, 1);
102
93
  RTYPEDDATA_DATA(obj) = ctx;
103
94
  SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj);
104
95
 
105
- #if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER < 0x10100000 && \
106
- !defined(LIBRESSL_VERSION_NUMBER)
107
- /* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
108
- * allows to specify multiple curve names and OpenSSL will select
109
- * automatically from them. In OpenSSL 1.0.2, the automatic selection has to
110
- * be enabled explicitly. OpenSSL 1.1.0 and LibreSSL 2.6.1 removed the knob
111
- * and it is always enabled. To uniform the behavior, we enable the
112
- * automatic selection also in 1.0.2. Users can still disable ECDH by
113
- * removing ECDH cipher suites by SSLContext#ciphers=. */
114
- if (!SSL_CTX_set_ecdh_auto(ctx, 1))
115
- ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
116
- #endif
117
-
118
96
  return obj;
119
97
  }
120
98
 
121
- static int
122
- parse_proto_version(VALUE str)
123
- {
124
- int i;
125
- static const struct {
126
- const char *name;
127
- int version;
128
- } map[] = {
129
- { "SSL2", SSL2_VERSION },
130
- { "SSL3", SSL3_VERSION },
131
- { "TLS1", TLS1_VERSION },
132
- { "TLS1_1", TLS1_1_VERSION },
133
- { "TLS1_2", TLS1_2_VERSION },
134
- #ifdef TLS1_3_VERSION
135
- { "TLS1_3", TLS1_3_VERSION },
136
- #endif
137
- };
138
-
139
- if (NIL_P(str))
140
- return 0;
141
- if (RB_INTEGER_TYPE_P(str))
142
- return NUM2INT(str);
143
-
144
- if (SYMBOL_P(str))
145
- str = rb_sym2str(str);
146
- StringValue(str);
147
- for (i = 0; i < numberof(map); i++)
148
- if (!strncmp(map[i].name, RSTRING_PTR(str), RSTRING_LEN(str)))
149
- return map[i].version;
150
- rb_raise(rb_eArgError, "unrecognized version %+"PRIsVALUE, str);
151
- }
152
-
153
- /*
154
- * call-seq:
155
- * ctx.set_minmax_proto_version(min, max) -> nil
156
- *
157
- * Sets the minimum and maximum supported protocol versions. See #min_version=
158
- * and #max_version=.
159
- */
160
- static VALUE
161
- ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
162
- {
163
- SSL_CTX *ctx;
164
- int min, max;
165
-
166
- GetSSLCTX(self, ctx);
167
- min = parse_proto_version(min_v);
168
- max = parse_proto_version(max_v);
169
-
170
- #ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
171
- if (!SSL_CTX_set_min_proto_version(ctx, min))
172
- ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
173
- if (!SSL_CTX_set_max_proto_version(ctx, max))
174
- ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
175
- #else
176
- {
177
- unsigned long sum = 0, opts = 0;
178
- int i;
179
- static const struct {
180
- int ver;
181
- unsigned long opts;
182
- } options_map[] = {
183
- { SSL2_VERSION, SSL_OP_NO_SSLv2 },
184
- { SSL3_VERSION, SSL_OP_NO_SSLv3 },
185
- { TLS1_VERSION, SSL_OP_NO_TLSv1 },
186
- { TLS1_1_VERSION, SSL_OP_NO_TLSv1_1 },
187
- { TLS1_2_VERSION, SSL_OP_NO_TLSv1_2 },
188
- # if defined(TLS1_3_VERSION)
189
- { TLS1_3_VERSION, SSL_OP_NO_TLSv1_3 },
190
- # endif
191
- };
192
-
193
- for (i = 0; i < numberof(options_map); i++) {
194
- sum |= options_map[i].opts;
195
- if ((min && min > options_map[i].ver) ||
196
- (max && max < options_map[i].ver)) {
197
- opts |= options_map[i].opts;
198
- }
199
- }
200
- SSL_CTX_clear_options(ctx, sum);
201
- SSL_CTX_set_options(ctx, opts);
202
- }
203
- #endif
204
-
205
- return Qnil;
206
- }
207
-
208
99
  static VALUE
209
100
  ossl_call_client_cert_cb(VALUE obj)
210
101
  {
@@ -213,7 +104,7 @@ ossl_call_client_cert_cb(VALUE obj)
213
104
  ctx_obj = rb_attr_get(obj, id_i_context);
214
105
  cb = rb_attr_get(ctx_obj, id_i_client_cert_cb);
215
106
  if (NIL_P(cb))
216
- return Qnil;
107
+ return Qnil;
217
108
 
218
109
  ary = rb_funcallv(cb, id_call, 1, &obj);
219
110
  Check_Type(ary, T_ARRAY);
@@ -231,7 +122,7 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
231
122
  obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
232
123
  ret = rb_protect(ossl_call_client_cert_cb, obj, NULL);
233
124
  if (NIL_P(ret))
234
- return 0;
125
+ return 0;
235
126
 
236
127
  *x509 = DupX509CertPtr(RARRAY_AREF(ret, 0));
237
128
  *pkey = DupPKeyPtr(RARRAY_AREF(ret, 1));
@@ -242,8 +133,6 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
242
133
  #if !defined(OPENSSL_NO_DH)
243
134
  struct tmp_dh_callback_args {
244
135
  VALUE ssl_obj;
245
- ID id;
246
- int type;
247
136
  int is_export;
248
137
  int keylength;
249
138
  };
@@ -252,48 +141,36 @@ static VALUE
252
141
  ossl_call_tmp_dh_callback(VALUE arg)
253
142
  {
254
143
  struct tmp_dh_callback_args *args = (struct tmp_dh_callback_args *)arg;
255
- VALUE cb, dh;
256
- EVP_PKEY *pkey;
144
+ VALUE ctx_obj, cb, obj;
145
+ const DH *dh;
257
146
 
258
- cb = rb_funcall(args->ssl_obj, args->id, 0);
147
+ ctx_obj = rb_attr_get(args->ssl_obj, id_i_context);
148
+ cb = rb_attr_get(ctx_obj, id_i_tmp_dh_callback);
259
149
  if (NIL_P(cb))
260
- return (VALUE)NULL;
261
- dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
262
- INT2NUM(args->keylength));
263
- pkey = GetPKeyPtr(dh);
264
- if (EVP_PKEY_base_id(pkey) != args->type)
265
- return (VALUE)NULL;
150
+ return (VALUE)NULL;
151
+
152
+ obj = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
153
+ INT2NUM(args->keylength));
154
+ // TODO: We should riase if obj is not DH
155
+ dh = EVP_PKEY_get0_DH(GetPKeyPtr(obj));
156
+ if (!dh)
157
+ ossl_clear_error();
266
158
 
267
- return (VALUE)pkey;
159
+ return (VALUE)dh;
268
160
  }
269
- #endif
270
161
 
271
- #if !defined(OPENSSL_NO_DH)
272
162
  static DH *
273
163
  ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
274
164
  {
275
- VALUE rb_ssl;
276
- EVP_PKEY *pkey;
277
- struct tmp_dh_callback_args args;
278
165
  int state;
279
-
280
- rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
281
- args.ssl_obj = rb_ssl;
282
- args.id = id_tmp_dh_callback;
283
- args.is_export = is_export;
284
- args.keylength = keylength;
285
- args.type = EVP_PKEY_DH;
286
-
287
- pkey = (EVP_PKEY *)rb_protect(ossl_call_tmp_dh_callback,
288
- (VALUE)&args, &state);
166
+ VALUE rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
167
+ struct tmp_dh_callback_args args = {rb_ssl, is_export, keylength};
168
+ VALUE ret = rb_protect(ossl_call_tmp_dh_callback, (VALUE)&args, &state);
289
169
  if (state) {
290
- rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
291
- return NULL;
170
+ rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
171
+ return NULL;
292
172
  }
293
- if (!pkey)
294
- return NULL;
295
-
296
- return (DH *)EVP_PKEY_get0_DH(pkey);
173
+ return (DH *)ret;
297
174
  }
298
175
  #endif /* OPENSSL_NO_DH */
299
176
 
@@ -309,13 +186,13 @@ call_verify_certificate_identity(VALUE ctx_v)
309
186
  hostname = rb_attr_get(ssl_obj, id_i_hostname);
310
187
 
311
188
  if (!RTEST(hostname)) {
312
- rb_warning("verify_hostname requires hostname to be set");
313
- return Qtrue;
189
+ rb_warning("verify_hostname requires hostname to be set");
190
+ return Qtrue;
314
191
  }
315
192
 
316
193
  cert_obj = ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx));
317
194
  return rb_funcall(mSSL, rb_intern("verify_certificate_identity"), 2,
318
- cert_obj, hostname);
195
+ cert_obj, hostname);
319
196
  }
320
197
 
321
198
  static int
@@ -332,19 +209,15 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
332
209
  verify_hostname = rb_attr_get(sslctx_obj, id_i_verify_hostname);
333
210
 
334
211
  if (preverify_ok && RTEST(verify_hostname) && !SSL_is_server(ssl) &&
335
- !X509_STORE_CTX_get_error_depth(ctx)) {
336
- ret = rb_protect(call_verify_certificate_identity, (VALUE)ctx, &status);
337
- if (status) {
338
- rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
339
- return 0;
340
- }
212
+ !X509_STORE_CTX_get_error_depth(ctx)) {
213
+ ret = rb_protect(call_verify_certificate_identity, (VALUE)ctx, &status);
214
+ if (status) {
215
+ rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
216
+ return 0;
217
+ }
341
218
  if (ret != Qtrue) {
342
219
  preverify_ok = 0;
343
- #if defined(X509_V_ERR_HOSTNAME_MISMATCH)
344
220
  X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
345
- #else
346
- X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
347
- #endif
348
221
  }
349
222
  }
350
223
 
@@ -366,11 +239,7 @@ ossl_call_session_get_cb(VALUE ary)
366
239
  }
367
240
 
368
241
  static SSL_SESSION *
369
- #if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
370
242
  ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
371
- #else
372
- ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
373
- #endif
374
243
  {
375
244
  VALUE ary, ssl_obj, ret_obj;
376
245
  SSL_SESSION *sess;
@@ -443,7 +312,7 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
443
312
  return 0;
444
313
  }
445
314
 
446
- #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
315
+ #if !OSSL_IS_LIBRESSL
447
316
  /*
448
317
  * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
449
318
  * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
@@ -516,7 +385,7 @@ ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
516
385
  * when SSL_CTX_free() is called.
517
386
  */
518
387
  if (rb_during_gc())
519
- return;
388
+ return;
520
389
 
521
390
  OSSL_Debug("SSL SESSION remove callback entered");
522
391
 
@@ -547,8 +416,9 @@ ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
547
416
 
548
417
  GetSSLCTX(arg, ctx);
549
418
  x509 = DupX509CertPtr(i);
550
- if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){
551
- ossl_raise(eSSLError, NULL);
419
+ if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) {
420
+ X509_free(x509);
421
+ ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert");
552
422
  }
553
423
 
554
424
  return i;
@@ -578,8 +448,8 @@ ossl_call_servername_cb(VALUE arg)
578
448
  ossl_raise(eSSLError, "SSL_set_SSL_CTX");
579
449
  rb_ivar_set(ssl_obj, id_i_context, ret_obj);
580
450
  } else if (!NIL_P(ret_obj)) {
581
- ossl_raise(rb_eArgError, "servername_cb must return an "
582
- "OpenSSL::SSL::SSLContext object or nil");
451
+ ossl_raise(rb_eArgError, "servername_cb must return an "
452
+ "OpenSSL::SSL::SSLContext object or nil");
583
453
  }
584
454
 
585
455
  return Qnil;
@@ -619,7 +489,7 @@ ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
619
489
  int len = RSTRING_LENINT(cur);
620
490
  char len_byte;
621
491
  if (len < 1 || len > 255)
622
- ossl_raise(eSSLError, "Advertised protocol must have length 1..255");
492
+ ossl_raise(eSSLError, "Advertised protocol must have length 1..255");
623
493
  /* Encode the length byte */
624
494
  len_byte = len;
625
495
  rb_str_buf_cat(encoded, &len_byte, 1);
@@ -653,16 +523,16 @@ npn_select_cb_common_i(VALUE tmp)
653
523
  /* assume OpenSSL verifies this format */
654
524
  /* The format is len_1|proto_1|...|len_n|proto_n */
655
525
  while (in < in_end) {
656
- l = *in++;
657
- rb_ary_push(protocols, rb_str_new((const char *)in, l));
658
- in += l;
526
+ l = *in++;
527
+ rb_ary_push(protocols, rb_str_new((const char *)in, l));
528
+ in += l;
659
529
  }
660
530
 
661
531
  selected = rb_funcallv(args->cb, id_call, 1, &protocols);
662
532
  StringValue(selected);
663
533
  len = RSTRING_LEN(selected);
664
534
  if (len < 1 || len >= 256) {
665
- ossl_raise(eSSLError, "Selected protocol name must have length 1..255");
535
+ ossl_raise(eSSLError, "Selected protocol name must have length 1..255");
666
536
  }
667
537
 
668
538
  return selected;
@@ -670,8 +540,8 @@ npn_select_cb_common_i(VALUE tmp)
670
540
 
671
541
  static int
672
542
  ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
673
- unsigned char *outlen, const unsigned char *in,
674
- unsigned int inlen)
543
+ unsigned char *outlen, const unsigned char *in,
544
+ unsigned int inlen)
675
545
  {
676
546
  VALUE selected;
677
547
  int status;
@@ -683,10 +553,10 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
683
553
 
684
554
  selected = rb_protect(npn_select_cb_common_i, (VALUE)&args, &status);
685
555
  if (status) {
686
- VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
556
+ VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
687
557
 
688
- rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
689
- return SSL_TLSEXT_ERR_ALERT_FATAL;
558
+ rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
559
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
690
560
  }
691
561
 
692
562
  *out = (unsigned char *)RSTRING_PTR(selected);
@@ -698,7 +568,7 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
698
568
  #ifdef OSSL_USE_NEXTPROTONEG
699
569
  static int
700
570
  ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
701
- void *arg)
571
+ void *arg)
702
572
  {
703
573
  VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded);
704
574
 
@@ -710,7 +580,7 @@ ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
710
580
 
711
581
  static int
712
582
  ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
713
- const unsigned char *in, unsigned int inlen, void *arg)
583
+ const unsigned char *in, unsigned int inlen, void *arg)
714
584
  {
715
585
  VALUE sslctx_obj, cb;
716
586
 
@@ -718,13 +588,13 @@ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
718
588
  cb = rb_attr_get(sslctx_obj, id_i_npn_select_cb);
719
589
 
720
590
  return ssl_npn_select_cb_common(ssl, cb, (const unsigned char **)out,
721
- outlen, in, inlen);
591
+ outlen, in, inlen);
722
592
  }
723
593
  #endif
724
594
 
725
595
  static int
726
596
  ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
727
- const unsigned char *in, unsigned int inlen, void *arg)
597
+ const unsigned char *in, unsigned int inlen, void *arg)
728
598
  {
729
599
  VALUE sslctx_obj, cb;
730
600
 
@@ -741,7 +611,7 @@ ssl_info_cb(const SSL *ssl, int where, int val)
741
611
  int is_server = SSL_is_server((SSL *)ssl);
742
612
 
743
613
  if (is_server && where & SSL_CB_HANDSHAKE_START) {
744
- ssl_renegotiation_cb(ssl);
614
+ ssl_renegotiation_cb(ssl);
745
615
  }
746
616
  }
747
617
 
@@ -787,9 +657,9 @@ ossl_sslctx_set_options(VALUE self, VALUE options)
787
657
  SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx));
788
658
 
789
659
  if (NIL_P(options)) {
790
- SSL_CTX_set_options(ctx, SSL_OP_ALL);
660
+ SSL_CTX_set_options(ctx, SSL_OP_ALL);
791
661
  } else {
792
- SSL_CTX_set_options(ctx, NUM2ULONG(options));
662
+ SSL_CTX_set_options(ctx, NUM2ULONG(options));
793
663
  }
794
664
 
795
665
  return self;
@@ -819,23 +689,26 @@ ossl_sslctx_setup(VALUE self)
819
689
  GetSSLCTX(self, ctx);
820
690
 
821
691
  #if !defined(OPENSSL_NO_DH)
822
- SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
692
+ if (!NIL_P(rb_attr_get(self, id_i_tmp_dh_callback))) {
693
+ SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
694
+ SSL_CTX_set_dh_auto(ctx, 0);
695
+ }
823
696
  #endif
824
697
 
825
- #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
698
+ #if !defined(OPENSSL_IS_AWSLC) /* AWS-LC has no support for TLS 1.3 PHA. */
826
699
  SSL_CTX_set_post_handshake_auth(ctx, 1);
827
700
  #endif
828
701
 
829
702
  val = rb_attr_get(self, id_i_cert_store);
830
703
  if (!NIL_P(val)) {
831
- X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
832
- SSL_CTX_set_cert_store(ctx, store);
833
- X509_STORE_up_ref(store);
704
+ X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
705
+ SSL_CTX_set_cert_store(ctx, store);
706
+ X509_STORE_up_ref(store);
834
707
  }
835
708
 
836
709
  val = rb_attr_get(self, id_i_extra_chain_cert);
837
710
  if(!NIL_P(val)){
838
- rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
711
+ rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
839
712
  }
840
713
 
841
714
  /* private key may be bundled in certificate file. */
@@ -859,22 +732,22 @@ ossl_sslctx_setup(VALUE self)
859
732
 
860
733
  val = rb_attr_get(self, id_i_client_ca);
861
734
  if(!NIL_P(val)){
862
- if (RB_TYPE_P(val, T_ARRAY)) {
863
- for(i = 0; i < RARRAY_LEN(val); i++){
864
- client_ca = GetX509CertPtr(RARRAY_AREF(val, i));
865
- if (!SSL_CTX_add_client_CA(ctx, client_ca)){
866
- /* Copies X509_NAME => FREE it. */
867
- ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
868
- }
869
- }
735
+ if (RB_TYPE_P(val, T_ARRAY)) {
736
+ for(i = 0; i < RARRAY_LEN(val); i++){
737
+ client_ca = GetX509CertPtr(RARRAY_AREF(val, i));
738
+ if (!SSL_CTX_add_client_CA(ctx, client_ca)){
739
+ /* Copies X509_NAME => FREE it. */
740
+ ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
741
+ }
742
+ }
870
743
  }
871
- else{
872
- client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
744
+ else{
745
+ client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
873
746
  if (!SSL_CTX_add_client_CA(ctx, client_ca)){
874
- /* Copies X509_NAME => FREE it. */
875
- ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
747
+ /* Copies X509_NAME => FREE it. */
748
+ ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
876
749
  }
877
- }
750
+ }
878
751
  }
879
752
 
880
753
  val = rb_attr_get(self, id_i_ca_file);
@@ -897,7 +770,7 @@ ossl_sslctx_setup(VALUE self)
897
770
  verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
898
771
  SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
899
772
  if (RTEST(rb_attr_get(self, id_i_client_cert_cb)))
900
- SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
773
+ SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
901
774
 
902
775
  val = rb_attr_get(self, id_i_timeout);
903
776
  if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));
@@ -908,63 +781,63 @@ ossl_sslctx_setup(VALUE self)
908
781
  #ifdef OSSL_USE_NEXTPROTONEG
909
782
  val = rb_attr_get(self, id_i_npn_protocols);
910
783
  if (!NIL_P(val)) {
911
- VALUE encoded = ssl_encode_npn_protocols(val);
912
- rb_ivar_set(self, id_npn_protocols_encoded, encoded);
913
- SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
914
- OSSL_Debug("SSL NPN advertise callback added");
784
+ VALUE encoded = ssl_encode_npn_protocols(val);
785
+ rb_ivar_set(self, id_npn_protocols_encoded, encoded);
786
+ SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
787
+ OSSL_Debug("SSL NPN advertise callback added");
915
788
  }
916
789
  if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
917
- SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
918
- OSSL_Debug("SSL NPN select callback added");
790
+ SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
791
+ OSSL_Debug("SSL NPN select callback added");
919
792
  }
920
793
  #endif
921
794
 
922
795
  val = rb_attr_get(self, id_i_alpn_protocols);
923
796
  if (!NIL_P(val)) {
924
- VALUE rprotos = ssl_encode_npn_protocols(val);
797
+ VALUE rprotos = ssl_encode_npn_protocols(val);
925
798
 
926
- /* returns 0 on success */
927
- if (SSL_CTX_set_alpn_protos(ctx, (unsigned char *)RSTRING_PTR(rprotos),
928
- RSTRING_LENINT(rprotos)))
929
- ossl_raise(eSSLError, "SSL_CTX_set_alpn_protos");
930
- OSSL_Debug("SSL ALPN values added");
799
+ /* returns 0 on success */
800
+ if (SSL_CTX_set_alpn_protos(ctx, (unsigned char *)RSTRING_PTR(rprotos),
801
+ RSTRING_LENINT(rprotos)))
802
+ ossl_raise(eSSLError, "SSL_CTX_set_alpn_protos");
803
+ OSSL_Debug("SSL ALPN values added");
931
804
  }
932
805
  if (RTEST(rb_attr_get(self, id_i_alpn_select_cb))) {
933
- SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
934
- OSSL_Debug("SSL ALPN select callback added");
806
+ SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
807
+ OSSL_Debug("SSL ALPN select callback added");
935
808
  }
936
809
 
937
810
  rb_obj_freeze(self);
938
811
 
939
812
  val = rb_attr_get(self, id_i_session_id_context);
940
813
  if (!NIL_P(val)){
941
- StringValue(val);
942
- if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
943
- RSTRING_LENINT(val))){
944
- ossl_raise(eSSLError, "SSL_CTX_set_session_id_context");
945
- }
814
+ StringValue(val);
815
+ if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
816
+ RSTRING_LENINT(val))){
817
+ ossl_raise(eSSLError, "SSL_CTX_set_session_id_context");
818
+ }
946
819
  }
947
820
 
948
821
  if (RTEST(rb_attr_get(self, id_i_session_get_cb))) {
949
- SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
950
- OSSL_Debug("SSL SESSION get callback added");
822
+ SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
823
+ OSSL_Debug("SSL SESSION get callback added");
951
824
  }
952
825
  if (RTEST(rb_attr_get(self, id_i_session_new_cb))) {
953
- SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
954
- OSSL_Debug("SSL SESSION new callback added");
826
+ SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
827
+ OSSL_Debug("SSL SESSION new callback added");
955
828
  }
956
829
  if (RTEST(rb_attr_get(self, id_i_session_remove_cb))) {
957
- SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
958
- OSSL_Debug("SSL SESSION remove callback added");
830
+ SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
831
+ OSSL_Debug("SSL SESSION remove callback added");
959
832
  }
960
833
 
961
834
  val = rb_attr_get(self, id_i_servername_cb);
962
835
  if (!NIL_P(val)) {
963
836
  SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
964
- OSSL_Debug("SSL TLSEXT servername callback added");
837
+ OSSL_Debug("SSL TLSEXT servername callback added");
965
838
  }
966
839
 
967
- #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
840
+ #if !OSSL_IS_LIBRESSL
968
841
  /*
969
842
  * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
970
843
  * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
@@ -979,6 +852,93 @@ ossl_sslctx_setup(VALUE self)
979
852
  return Qtrue;
980
853
  }
981
854
 
855
+ static int
856
+ parse_proto_version(VALUE str)
857
+ {
858
+ int i;
859
+ static const struct {
860
+ const char *name;
861
+ int version;
862
+ } map[] = {
863
+ { "SSL2", SSL2_VERSION },
864
+ { "SSL3", SSL3_VERSION },
865
+ { "TLS1", TLS1_VERSION },
866
+ { "TLS1_1", TLS1_1_VERSION },
867
+ { "TLS1_2", TLS1_2_VERSION },
868
+ { "TLS1_3", TLS1_3_VERSION },
869
+ };
870
+
871
+ if (NIL_P(str))
872
+ return 0;
873
+ if (RB_INTEGER_TYPE_P(str))
874
+ return NUM2INT(str);
875
+
876
+ if (SYMBOL_P(str))
877
+ str = rb_sym2str(str);
878
+ StringValue(str);
879
+ for (i = 0; i < numberof(map); i++)
880
+ if (!strncmp(map[i].name, RSTRING_PTR(str), RSTRING_LEN(str)))
881
+ return map[i].version;
882
+ rb_raise(rb_eArgError, "unrecognized version %+"PRIsVALUE, str);
883
+ }
884
+
885
+ /*
886
+ * call-seq:
887
+ * ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION
888
+ * ctx.min_version = :TLS1_2
889
+ * ctx.min_version = nil
890
+ *
891
+ * Sets the lower bound on the supported SSL/TLS protocol version. The
892
+ * version may be specified by an integer constant named
893
+ * OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version".
894
+ *
895
+ * === Example
896
+ * ctx = OpenSSL::SSL::SSLContext.new
897
+ * ctx.min_version = OpenSSL::SSL::TLS1_1_VERSION
898
+ * ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
899
+ *
900
+ * sock = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx)
901
+ * sock.connect # Initiates a connection using either TLS 1.1 or TLS 1.2
902
+ */
903
+ static VALUE
904
+ ossl_sslctx_set_min_version(VALUE self, VALUE v)
905
+ {
906
+ SSL_CTX *ctx;
907
+ int version;
908
+
909
+ rb_check_frozen(self);
910
+ GetSSLCTX(self, ctx);
911
+ version = parse_proto_version(v);
912
+
913
+ if (!SSL_CTX_set_min_proto_version(ctx, version))
914
+ ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
915
+ return v;
916
+ }
917
+
918
+ /*
919
+ * call-seq:
920
+ * ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
921
+ * ctx.max_version = :TLS1_2
922
+ * ctx.max_version = nil
923
+ *
924
+ * Sets the upper bound of the supported SSL/TLS protocol version. See
925
+ * #min_version= for the possible values.
926
+ */
927
+ static VALUE
928
+ ossl_sslctx_set_max_version(VALUE self, VALUE v)
929
+ {
930
+ SSL_CTX *ctx;
931
+ int version;
932
+
933
+ rb_check_frozen(self);
934
+ GetSSLCTX(self, ctx);
935
+ version = parse_proto_version(v);
936
+
937
+ if (!SSL_CTX_set_max_proto_version(ctx, version))
938
+ ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
939
+ return v;
940
+ }
941
+
982
942
  static VALUE
983
943
  ossl_ssl_cipher_to_ary(const SSL_CIPHER *cipher)
984
944
  {
@@ -1028,11 +988,10 @@ static VALUE
1028
988
  build_cipher_string(VALUE v)
1029
989
  {
1030
990
  VALUE str, elem;
1031
- int i;
1032
991
 
1033
992
  if (RB_TYPE_P(v, T_ARRAY)) {
1034
993
  str = rb_str_new(0, 0);
1035
- for (i = 0; i < RARRAY_LEN(v); i++) {
994
+ for (long i = 0; i < RARRAY_LEN(v); i++) {
1036
995
  elem = rb_ary_entry(v, i);
1037
996
  if (RB_TYPE_P(elem, T_ARRAY)) elem = rb_ary_entry(elem, 0);
1038
997
  elem = rb_String(elem);
@@ -1053,9 +1012,14 @@ build_cipher_string(VALUE v)
1053
1012
  * ctx.ciphers = [name, ...]
1054
1013
  * ctx.ciphers = [[name, version, bits, alg_bits], ...]
1055
1014
  *
1056
- * Sets the list of available cipher suites for this context. Note in a server
1057
- * context some ciphers require the appropriate certificates. For example, an
1058
- * RSA cipher suite can only be chosen when an RSA certificate is available.
1015
+ * Sets the list of available cipher suites for TLS 1.2 and below for this
1016
+ * context.
1017
+ *
1018
+ * Note in a server context some ciphers require the appropriate certificates.
1019
+ * For example, an RSA cipher suite can only be chosen when an RSA certificate
1020
+ * is available.
1021
+ *
1022
+ * This method does not affect TLS 1.3 connections. See also #ciphersuites=.
1059
1023
  */
1060
1024
  static VALUE
1061
1025
  ossl_sslctx_set_ciphers(VALUE self, VALUE v)
@@ -1064,6 +1028,7 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1064
1028
  VALUE str;
1065
1029
 
1066
1030
  rb_check_frozen(self);
1031
+ // Assigning nil is a no-op for compatibility
1067
1032
  if (NIL_P(v))
1068
1033
  return v;
1069
1034
 
@@ -1076,14 +1041,12 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1076
1041
  return v;
1077
1042
  }
1078
1043
 
1079
- #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
1080
1044
  /*
1081
1045
  * call-seq:
1082
1046
  * ctx.ciphersuites = "cipher1:cipher2:..."
1083
1047
  * ctx.ciphersuites = [name, ...]
1084
- * ctx.ciphersuites = [[name, version, bits, alg_bits], ...]
1085
1048
  *
1086
- * Sets the list of available TLSv1.3 cipher suites for this context.
1049
+ * Sets the list of available TLS 1.3 cipher suites for this context.
1087
1050
  */
1088
1051
  static VALUE
1089
1052
  ossl_sslctx_set_ciphersuites(VALUE self, VALUE v)
@@ -1092,6 +1055,7 @@ ossl_sslctx_set_ciphersuites(VALUE self, VALUE v)
1092
1055
  VALUE str;
1093
1056
 
1094
1057
  rb_check_frozen(self);
1058
+ // Assigning nil is a no-op for compatibility
1095
1059
  if (NIL_P(v))
1096
1060
  return v;
1097
1061
 
@@ -1103,6 +1067,62 @@ ossl_sslctx_set_ciphersuites(VALUE self, VALUE v)
1103
1067
 
1104
1068
  return v;
1105
1069
  }
1070
+
1071
+ #ifdef HAVE_SSL_CTX_SET1_SIGALGS_LIST
1072
+ /*
1073
+ * call-seq:
1074
+ * ctx.sigalgs = "sigalg1:sigalg2:..."
1075
+ *
1076
+ * Sets the list of "supported signature algorithms" for this context.
1077
+ *
1078
+ * For a TLS client, the list is used in the "signature_algorithms" extension
1079
+ * in the ClientHello message. For a server, the list is used by OpenSSL to
1080
+ * determine the set of shared signature algorithms. OpenSSL will pick the most
1081
+ * appropriate one from it.
1082
+ *
1083
+ * See also #client_sigalgs= for the client authentication equivalent.
1084
+ */
1085
+ static VALUE
1086
+ ossl_sslctx_set_sigalgs(VALUE self, VALUE v)
1087
+ {
1088
+ SSL_CTX *ctx;
1089
+
1090
+ rb_check_frozen(self);
1091
+ GetSSLCTX(self, ctx);
1092
+
1093
+ if (!SSL_CTX_set1_sigalgs_list(ctx, StringValueCStr(v)))
1094
+ ossl_raise(eSSLError, "SSL_CTX_set1_sigalgs_list");
1095
+
1096
+ return v;
1097
+ }
1098
+ #endif
1099
+
1100
+ #ifdef HAVE_SSL_CTX_SET1_CLIENT_SIGALGS_LIST
1101
+ /*
1102
+ * call-seq:
1103
+ * ctx.client_sigalgs = "sigalg1:sigalg2:..."
1104
+ *
1105
+ * Sets the list of "supported signature algorithms" for client authentication
1106
+ * for this context.
1107
+ *
1108
+ * For a TLS server, the list is sent to the client as part of the
1109
+ * CertificateRequest message.
1110
+ *
1111
+ * See also #sigalgs= for the server authentication equivalent.
1112
+ */
1113
+ static VALUE
1114
+ ossl_sslctx_set_client_sigalgs(VALUE self, VALUE v)
1115
+ {
1116
+ SSL_CTX *ctx;
1117
+
1118
+ rb_check_frozen(self);
1119
+ GetSSLCTX(self, ctx);
1120
+
1121
+ if (!SSL_CTX_set1_client_sigalgs_list(ctx, StringValueCStr(v)))
1122
+ ossl_raise(eSSLError, "SSL_CTX_set1_client_sigalgs_list");
1123
+
1124
+ return v;
1125
+ }
1106
1126
  #endif
1107
1127
 
1108
1128
  #ifndef OPENSSL_NO_DH
@@ -1117,7 +1137,7 @@ ossl_sslctx_set_ciphersuites(VALUE self, VALUE v)
1117
1137
  * contained in the key object, if any, are ignored. The server will always
1118
1138
  * generate a new key pair for each handshake.
1119
1139
  *
1120
- * Added in version 3.0. See also the man page SSL_set0_tmp_dh_pkey(3).
1140
+ * Added in version 3.0. See also the man page SSL_CTX_set0_tmp_dh_pkey(3).
1121
1141
  *
1122
1142
  * Example:
1123
1143
  * ctx = OpenSSL::SSL::SSLContext.new
@@ -1138,7 +1158,7 @@ ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg)
1138
1158
  if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH)
1139
1159
  rb_raise(eSSLError, "invalid pkey type %s (expected DH)",
1140
1160
  OBJ_nid2sn(EVP_PKEY_base_id(pkey)));
1141
- #ifdef HAVE_SSL_SET0_TMP_DH_PKEY
1161
+ #ifdef HAVE_SSL_CTX_SET0_TMP_DH_PKEY
1142
1162
  if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkey))
1143
1163
  ossl_raise(eSSLError, "SSL_CTX_set0_tmp_dh_pkey");
1144
1164
  EVP_PKEY_up_ref(pkey);
@@ -1147,29 +1167,36 @@ ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg)
1147
1167
  ossl_raise(eSSLError, "SSL_CTX_set_tmp_dh");
1148
1168
  #endif
1149
1169
 
1170
+ // Turn off the "auto" DH parameters set by ossl_sslctx_s_alloc()
1171
+ SSL_CTX_set_dh_auto(ctx, 0);
1172
+
1150
1173
  return arg;
1151
1174
  }
1152
1175
  #endif
1153
1176
 
1154
- #if !defined(OPENSSL_NO_EC)
1155
1177
  /*
1156
1178
  * call-seq:
1157
- * ctx.ecdh_curves = curve_list -> curve_list
1179
+ * ctx.groups = groups_list
1180
+ * ctx.ecdh_curves = groups_list
1181
+ *
1182
+ * Sets the list of supported groups for key agreement for this context.
1158
1183
  *
1159
- * Sets the list of "supported elliptic curves" for this context.
1184
+ * For a TLS client, the list is directly used in the "supported_groups"
1185
+ * extension. For a server, the list is used by OpenSSL to determine the set of
1186
+ * shared supported groups. OpenSSL will pick the most appropriate one from it.
1160
1187
  *
1161
- * For a TLS client, the list is directly used in the Supported Elliptic Curves
1162
- * Extension. For a server, the list is used by OpenSSL to determine the set of
1163
- * shared curves. OpenSSL will pick the most appropriate one from it.
1188
+ * #ecdh_curves= is a deprecated alias for #groups=.
1189
+ *
1190
+ * See also the man page SSL_CTX_set1_groups_list(3).
1164
1191
  *
1165
1192
  * === Example
1166
1193
  * ctx1 = OpenSSL::SSL::SSLContext.new
1167
- * ctx1.ecdh_curves = "X25519:P-256:P-224"
1194
+ * ctx1.groups = "X25519:P-256:P-224"
1168
1195
  * svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx1)
1169
1196
  * Thread.new { svr.accept }
1170
1197
  *
1171
1198
  * ctx2 = OpenSSL::SSL::SSLContext.new
1172
- * ctx2.ecdh_curves = "P-256"
1199
+ * ctx2.groups = "P-256"
1173
1200
  * cli = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx2)
1174
1201
  * cli.connect
1175
1202
  *
@@ -1177,7 +1204,7 @@ ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg)
1177
1204
  * # => "prime256v1" (is an alias for NIST P-256)
1178
1205
  */
1179
1206
  static VALUE
1180
- ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
1207
+ ossl_sslctx_set_groups(VALUE self, VALUE arg)
1181
1208
  {
1182
1209
  SSL_CTX *ctx;
1183
1210
 
@@ -1185,13 +1212,10 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
1185
1212
  GetSSLCTX(self, ctx);
1186
1213
  StringValueCStr(arg);
1187
1214
 
1188
- if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
1189
- ossl_raise(eSSLError, NULL);
1215
+ if (!SSL_CTX_set1_groups_list(ctx, RSTRING_PTR(arg)))
1216
+ ossl_raise(eSSLError, "SSL_CTX_set1_groups_list");
1190
1217
  return arg;
1191
1218
  }
1192
- #else
1193
- #define ossl_sslctx_set_ecdh_curves rb_f_notimplement
1194
- #endif
1195
1219
 
1196
1220
  /*
1197
1221
  * call-seq:
@@ -1208,12 +1232,7 @@ ossl_sslctx_get_security_level(VALUE self)
1208
1232
 
1209
1233
  GetSSLCTX(self, ctx);
1210
1234
 
1211
- #if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
1212
1235
  return INT2NUM(SSL_CTX_get_security_level(ctx));
1213
- #else
1214
- (void)ctx;
1215
- return INT2FIX(0);
1216
- #endif
1217
1236
  }
1218
1237
 
1219
1238
  /*
@@ -1243,14 +1262,7 @@ ossl_sslctx_set_security_level(VALUE self, VALUE value)
1243
1262
  rb_check_frozen(self);
1244
1263
  GetSSLCTX(self, ctx);
1245
1264
 
1246
- #if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
1247
1265
  SSL_CTX_set_security_level(ctx, NUM2INT(value));
1248
- #else
1249
- (void)ctx;
1250
- if (NUM2INT(value) != 0)
1251
- ossl_raise(rb_eNotImpError, "setting security level to other than 0 is "
1252
- "not supported in this version of OpenSSL");
1253
- #endif
1254
1266
 
1255
1267
  return value;
1256
1268
  }
@@ -1332,20 +1344,20 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
1332
1344
  pub_pkey = X509_get_pubkey(x509);
1333
1345
  EVP_PKEY_free(pub_pkey);
1334
1346
  if (!pub_pkey)
1335
- rb_raise(rb_eArgError, "certificate does not contain public key");
1347
+ rb_raise(rb_eArgError, "certificate does not contain public key");
1336
1348
  if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
1337
- rb_raise(rb_eArgError, "public key mismatch");
1349
+ rb_raise(rb_eArgError, "public key mismatch");
1338
1350
 
1339
1351
  if (argc >= 3)
1340
- extra_chain = ossl_x509_ary2sk(extra_chain_ary);
1352
+ extra_chain = ossl_x509_ary2sk(extra_chain_ary);
1341
1353
 
1342
1354
  if (!SSL_CTX_use_certificate(ctx, x509)) {
1343
- sk_X509_pop_free(extra_chain, X509_free);
1344
- ossl_raise(eSSLError, "SSL_CTX_use_certificate");
1355
+ sk_X509_pop_free(extra_chain, X509_free);
1356
+ ossl_raise(eSSLError, "SSL_CTX_use_certificate");
1345
1357
  }
1346
1358
  if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
1347
- sk_X509_pop_free(extra_chain, X509_free);
1348
- ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
1359
+ sk_X509_pop_free(extra_chain, X509_free);
1360
+ ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
1349
1361
  }
1350
1362
  if (extra_chain && !SSL_CTX_set0_chain(ctx, extra_chain)) {
1351
1363
  sk_X509_pop_free(extra_chain, X509_free);
@@ -1578,32 +1590,31 @@ ossl_ssl_s_alloc(VALUE klass)
1578
1590
  }
1579
1591
 
1580
1592
  static VALUE
1581
- peer_ip_address(VALUE self)
1593
+ peer_ip_address(VALUE io)
1582
1594
  {
1583
- VALUE remote_address = rb_funcall(rb_attr_get(self, id_i_io), rb_intern("remote_address"), 0);
1595
+ VALUE remote_address = rb_funcall(io, rb_intern("remote_address"), 0);
1584
1596
 
1585
1597
  return rb_funcall(remote_address, rb_intern("inspect_sockaddr"), 0);
1586
1598
  }
1587
1599
 
1588
1600
  static VALUE
1589
- fallback_peer_ip_address(VALUE self, VALUE args)
1601
+ fallback_peer_ip_address(VALUE self, VALUE exc)
1590
1602
  {
1591
1603
  return rb_str_new_cstr("(null)");
1592
1604
  }
1593
1605
 
1594
1606
  static VALUE
1595
- peeraddr_ip_str(VALUE self)
1607
+ peeraddr_ip_str(VALUE io)
1596
1608
  {
1597
- VALUE rb_mErrno = rb_const_get(rb_cObject, rb_intern("Errno"));
1598
- VALUE rb_eSystemCallError = rb_const_get(rb_mErrno, rb_intern("SystemCallError"));
1599
-
1600
- return rb_rescue2(peer_ip_address, self, fallback_peer_ip_address, (VALUE)0, rb_eSystemCallError, NULL);
1609
+ return rb_rescue2(peer_ip_address, io, fallback_peer_ip_address, Qnil,
1610
+ rb_eSystemCallError, (VALUE)0);
1601
1611
  }
1602
1612
 
1603
1613
  /*
1604
1614
  * call-seq:
1605
1615
  * SSLSocket.new(io) => aSSLSocket
1606
1616
  * SSLSocket.new(io, ctx) => aSSLSocket
1617
+ * SSLSocket.new(io, ctx, sync_close:) => aSSLSocket
1607
1618
  *
1608
1619
  * Creates a new SSL socket from _io_ which must be a real IO object (not an
1609
1620
  * IO-like object that responds to read/write).
@@ -1611,6 +1622,10 @@ peeraddr_ip_str(VALUE self)
1611
1622
  * If _ctx_ is provided the SSL Sockets initial params will be taken from
1612
1623
  * the context.
1613
1624
  *
1625
+ * The optional _sync_close_ keyword parameter sets the _sync_close_ instance
1626
+ * variable. Setting this to +true+ will cause the underlying socket to be
1627
+ * closed when the SSL/TLS connection is shut down.
1628
+ *
1614
1629
  * The OpenSSL::Buffering module provides additional IO methods.
1615
1630
  *
1616
1631
  * This method will freeze the SSLContext if one is provided;
@@ -1619,29 +1634,42 @@ peeraddr_ip_str(VALUE self)
1619
1634
  static VALUE
1620
1635
  ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1621
1636
  {
1637
+ static ID kw_ids[1];
1638
+ VALUE kw_args[1];
1639
+ VALUE opts;
1640
+
1622
1641
  VALUE io, v_ctx;
1623
1642
  SSL *ssl;
1624
1643
  SSL_CTX *ctx;
1625
1644
 
1626
1645
  TypedData_Get_Struct(self, SSL, &ossl_ssl_type, ssl);
1627
1646
  if (ssl)
1628
- ossl_raise(eSSLError, "SSL already initialized");
1647
+ ossl_raise(eSSLError, "SSL already initialized");
1648
+
1649
+ if (rb_scan_args(argc, argv, "11:", &io, &v_ctx, &opts) == 1)
1650
+ v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
1651
+
1652
+ if (!kw_ids[0]) {
1653
+ kw_ids[0] = rb_intern_const("sync_close");
1654
+ }
1629
1655
 
1630
- if (rb_scan_args(argc, argv, "11", &io, &v_ctx) == 1)
1631
- v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
1656
+ rb_get_kwargs(opts, kw_ids, 0, 1, kw_args);
1657
+ if (kw_args[0] != Qundef) {
1658
+ rb_ivar_set(self, id_i_sync_close, kw_args[0]);
1659
+ }
1632
1660
 
1633
1661
  GetSSLCTX(v_ctx, ctx);
1634
1662
  rb_ivar_set(self, id_i_context, v_ctx);
1635
1663
  ossl_sslctx_setup(v_ctx);
1636
1664
 
1637
1665
  if (rb_respond_to(io, rb_intern("nonblock=")))
1638
- rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
1666
+ rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
1639
1667
  Check_Type(io, T_FILE);
1640
1668
  rb_ivar_set(self, id_i_io, io);
1641
1669
 
1642
1670
  ssl = SSL_new(ctx);
1643
1671
  if (!ssl)
1644
- ossl_raise(eSSLError, NULL);
1672
+ ossl_raise(eSSLError, NULL);
1645
1673
  RTYPEDDATA_DATA(self) = ssl;
1646
1674
 
1647
1675
  SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
@@ -1672,7 +1700,7 @@ ossl_ssl_setup(VALUE self)
1672
1700
 
1673
1701
  GetSSL(self, ssl);
1674
1702
  if (ssl_started(ssl))
1675
- return Qtrue;
1703
+ return Qtrue;
1676
1704
 
1677
1705
  io = rb_attr_get(self, id_i_io);
1678
1706
  GetOpenFile(io, fptr);
@@ -1684,24 +1712,28 @@ ossl_ssl_setup(VALUE self)
1684
1712
  return Qtrue;
1685
1713
  }
1686
1714
 
1715
+ static int
1716
+ errno_mapped(void)
1717
+ {
1687
1718
  #ifdef _WIN32
1688
- #define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
1719
+ return rb_w32_map_errno(WSAGetLastError());
1689
1720
  #else
1690
- #define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret))
1721
+ return errno;
1691
1722
  #endif
1723
+ }
1692
1724
 
1693
1725
  static void
1694
1726
  write_would_block(int nonblock)
1695
1727
  {
1696
1728
  if (nonblock)
1697
- ossl_raise(eSSLErrorWaitWritable, "write would block");
1729
+ ossl_raise(eSSLErrorWaitWritable, "write would block");
1698
1730
  }
1699
1731
 
1700
1732
  static void
1701
1733
  read_would_block(int nonblock)
1702
1734
  {
1703
1735
  if (nonblock)
1704
- ossl_raise(eSSLErrorWaitReadable, "read would block");
1736
+ ossl_raise(eSSLErrorWaitReadable, "read would block");
1705
1737
  }
1706
1738
 
1707
1739
  static int
@@ -1709,7 +1741,7 @@ no_exception_p(VALUE opts)
1709
1741
  {
1710
1742
  if (RB_TYPE_P(opts, T_HASH) &&
1711
1743
  rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse)
1712
- return 1;
1744
+ return 1;
1713
1745
  return 0;
1714
1746
  }
1715
1747
 
@@ -1729,13 +1761,13 @@ static void
1729
1761
  io_wait_writable(VALUE io)
1730
1762
  {
1731
1763
  #ifdef HAVE_RB_IO_MAYBE_WAIT
1732
- if (!rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) {
1764
+ if (!rb_io_wait(io, INT2NUM(RUBY_IO_WRITABLE), RUBY_IO_TIMEOUT_DEFAULT)) {
1733
1765
  rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become writable!");
1734
1766
  }
1735
1767
  #else
1736
1768
  rb_io_t *fptr;
1737
1769
  GetOpenFile(io, fptr);
1738
- rb_io_wait_writable(fptr->fd);
1770
+ rb_thread_fd_writable(fptr->fd);
1739
1771
  #endif
1740
1772
  }
1741
1773
 
@@ -1743,13 +1775,13 @@ static void
1743
1775
  io_wait_readable(VALUE io)
1744
1776
  {
1745
1777
  #ifdef HAVE_RB_IO_MAYBE_WAIT
1746
- if (!rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) {
1778
+ if (!rb_io_wait(io, INT2NUM(RUBY_IO_READABLE), RUBY_IO_TIMEOUT_DEFAULT)) {
1747
1779
  rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become readable!");
1748
1780
  }
1749
1781
  #else
1750
1782
  rb_io_t *fptr;
1751
1783
  GetOpenFile(io, fptr);
1752
- rb_io_wait_readable(fptr->fd);
1784
+ rb_thread_wait_fd(fptr->fd);
1753
1785
  #endif
1754
1786
  }
1755
1787
 
@@ -1757,7 +1789,6 @@ static VALUE
1757
1789
  ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
1758
1790
  {
1759
1791
  SSL *ssl;
1760
- int ret, ret2;
1761
1792
  VALUE cb_state;
1762
1793
  int nonblock = opts != Qfalse;
1763
1794
 
@@ -1767,7 +1798,8 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
1767
1798
 
1768
1799
  VALUE io = rb_attr_get(self, id_i_io);
1769
1800
  for (;;) {
1770
- ret = func(ssl);
1801
+ int ret = func(ssl);
1802
+ int saved_errno = errno_mapped();
1771
1803
 
1772
1804
  cb_state = rb_attr_get(self, ID_callback_state);
1773
1805
  if (!NIL_P(cb_state)) {
@@ -1779,7 +1811,8 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
1779
1811
  if (ret > 0)
1780
1812
  break;
1781
1813
 
1782
- switch ((ret2 = ssl_get_error(ssl, ret))) {
1814
+ int code = SSL_get_error(ssl, ret);
1815
+ switch (code) {
1783
1816
  case SSL_ERROR_WANT_WRITE:
1784
1817
  if (no_exception_p(opts)) { return sym_wait_writable; }
1785
1818
  write_would_block(nonblock);
@@ -1793,10 +1826,11 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
1793
1826
  case SSL_ERROR_SYSCALL:
1794
1827
  #ifdef __APPLE__
1795
1828
  /* See ossl_ssl_write_internal() */
1796
- if (errno == EPROTOTYPE)
1829
+ if (saved_errno == EPROTOTYPE)
1797
1830
  continue;
1798
1831
  #endif
1799
- if (errno) rb_sys_fail(funcname);
1832
+ if (saved_errno)
1833
+ rb_exc_raise(rb_syserr_new(saved_errno, funcname));
1800
1834
  /* fallthrough */
1801
1835
  default: {
1802
1836
  VALUE error_append = Qnil;
@@ -1817,10 +1851,10 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
1817
1851
  ossl_raise(eSSLError,
1818
1852
  "%s%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s%"PRIsVALUE,
1819
1853
  funcname,
1820
- ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "",
1821
- ret2,
1822
- errno,
1823
- peeraddr_ip_str(self),
1854
+ code == SSL_ERROR_SYSCALL ? " SYSCALL" : "",
1855
+ code,
1856
+ saved_errno,
1857
+ peeraddr_ip_str(io),
1824
1858
  SSL_state_string_long(ssl),
1825
1859
  error_append);
1826
1860
  }
@@ -1933,9 +1967,9 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1933
1967
  VALUE opts = Qnil;
1934
1968
 
1935
1969
  if (nonblock) {
1936
- rb_scan_args(argc, argv, "11:", &len, &str, &opts);
1970
+ rb_scan_args(argc, argv, "11:", &len, &str, &opts);
1937
1971
  } else {
1938
- rb_scan_args(argc, argv, "11", &len, &str);
1972
+ rb_scan_args(argc, argv, "11", &len, &str);
1939
1973
  }
1940
1974
  GetSSL(self, ssl);
1941
1975
  if (!ssl_started(ssl))
@@ -1943,13 +1977,13 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1943
1977
 
1944
1978
  ilen = NUM2INT(len);
1945
1979
  if (NIL_P(str))
1946
- str = rb_str_new(0, ilen);
1980
+ str = rb_str_new(0, ilen);
1947
1981
  else {
1948
- StringValue(str);
1949
- if (RSTRING_LEN(str) >= ilen)
1950
- rb_str_modify(str);
1951
- else
1952
- rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
1982
+ StringValue(str);
1983
+ if (RSTRING_LEN(str) >= ilen)
1984
+ rb_str_modify(str);
1985
+ else
1986
+ rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
1953
1987
  }
1954
1988
 
1955
1989
  if (ilen == 0) {
@@ -1959,9 +1993,11 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1959
1993
 
1960
1994
  VALUE io = rb_attr_get(self, id_i_io);
1961
1995
 
1962
- rb_str_locktmp(str);
1963
1996
  for (;;) {
1997
+ rb_str_locktmp(str);
1964
1998
  int nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1999
+ int saved_errno = errno_mapped();
2000
+ rb_str_unlocktmp(str);
1965
2001
 
1966
2002
  cb_state = rb_attr_get(self, ID_callback_state);
1967
2003
  if (!NIL_P(cb_state)) {
@@ -1970,36 +2006,31 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1970
2006
  rb_jump_tag(NUM2INT(cb_state));
1971
2007
  }
1972
2008
 
1973
- switch (ssl_get_error(ssl, nread)) {
2009
+ switch (SSL_get_error(ssl, nread)) {
1974
2010
  case SSL_ERROR_NONE:
1975
- rb_str_unlocktmp(str);
1976
2011
  rb_str_set_len(str, nread);
1977
2012
  return str;
1978
2013
  case SSL_ERROR_ZERO_RETURN:
1979
- rb_str_unlocktmp(str);
1980
2014
  if (no_exception_p(opts)) { return Qnil; }
1981
2015
  rb_eof_error();
1982
2016
  case SSL_ERROR_WANT_WRITE:
1983
2017
  if (nonblock) {
1984
- rb_str_unlocktmp(str);
1985
2018
  if (no_exception_p(opts)) { return sym_wait_writable; }
1986
2019
  write_would_block(nonblock);
1987
2020
  }
1988
2021
  io_wait_writable(io);
1989
- continue;
2022
+ break;
1990
2023
  case SSL_ERROR_WANT_READ:
1991
2024
  if (nonblock) {
1992
- rb_str_unlocktmp(str);
1993
2025
  if (no_exception_p(opts)) { return sym_wait_readable; }
1994
2026
  read_would_block(nonblock);
1995
2027
  }
1996
2028
  io_wait_readable(io);
1997
- continue;
2029
+ break;
1998
2030
  case SSL_ERROR_SYSCALL:
1999
2031
  if (!ERR_peek_error()) {
2000
- rb_str_unlocktmp(str);
2001
- if (errno)
2002
- rb_sys_fail(0);
2032
+ if (saved_errno)
2033
+ rb_exc_raise(rb_syserr_new(saved_errno, "SSL_read"));
2003
2034
  else {
2004
2035
  /*
2005
2036
  * The underlying BIO returned 0. This is actually a
@@ -2014,9 +2045,13 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
2014
2045
  }
2015
2046
  /* fall through */
2016
2047
  default:
2017
- rb_str_unlocktmp(str);
2018
2048
  ossl_raise(eSSLError, "SSL_read");
2019
2049
  }
2050
+
2051
+ // Ensure the buffer is not modified during io_wait_*able()
2052
+ rb_str_modify(str);
2053
+ if (rb_str_capacity(str) < (size_t)ilen)
2054
+ rb_raise(eSSLError, "read buffer was modified");
2020
2055
  }
2021
2056
  }
2022
2057
 
@@ -2054,28 +2089,33 @@ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
2054
2089
  }
2055
2090
 
2056
2091
  static VALUE
2057
- ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
2092
+ ossl_ssl_write_internal_safe(VALUE _args)
2058
2093
  {
2094
+ VALUE *args = (VALUE*)_args;
2095
+ VALUE self = args[0];
2096
+ VALUE str = args[1];
2097
+ VALUE opts = args[2];
2098
+
2059
2099
  SSL *ssl;
2060
2100
  rb_io_t *fptr;
2061
2101
  int num, nonblock = opts != Qfalse;
2062
- VALUE tmp, cb_state;
2102
+ VALUE cb_state;
2063
2103
 
2064
2104
  GetSSL(self, ssl);
2065
2105
  if (!ssl_started(ssl))
2066
2106
  rb_raise(eSSLError, "SSL session is not started yet");
2067
2107
 
2068
- tmp = rb_str_new_frozen(StringValue(str));
2069
2108
  VALUE io = rb_attr_get(self, id_i_io);
2070
2109
  GetOpenFile(io, fptr);
2071
2110
 
2072
2111
  /* SSL_write(3ssl) manpage states num == 0 is undefined */
2073
- num = RSTRING_LENINT(tmp);
2112
+ num = RSTRING_LENINT(str);
2074
2113
  if (num == 0)
2075
2114
  return INT2FIX(0);
2076
2115
 
2077
2116
  for (;;) {
2078
- int nwritten = SSL_write(ssl, RSTRING_PTR(tmp), num);
2117
+ int nwritten = SSL_write(ssl, RSTRING_PTR(str), num);
2118
+ int saved_errno = errno_mapped();
2079
2119
 
2080
2120
  cb_state = rb_attr_get(self, ID_callback_state);
2081
2121
  if (!NIL_P(cb_state)) {
@@ -2084,7 +2124,7 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
2084
2124
  rb_jump_tag(NUM2INT(cb_state));
2085
2125
  }
2086
2126
 
2087
- switch (ssl_get_error(ssl, nwritten)) {
2127
+ switch (SSL_get_error(ssl, nwritten)) {
2088
2128
  case SSL_ERROR_NONE:
2089
2129
  return INT2NUM(nwritten);
2090
2130
  case SSL_ERROR_WANT_WRITE:
@@ -2105,10 +2145,11 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
2105
2145
  * make the error handling in line with the socket library.
2106
2146
  * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
2107
2147
  */
2108
- if (errno == EPROTOTYPE)
2148
+ if (saved_errno == EPROTOTYPE)
2109
2149
  continue;
2110
2150
  #endif
2111
- if (errno) rb_sys_fail(0);
2151
+ if (saved_errno)
2152
+ rb_exc_raise(rb_syserr_new(saved_errno, "SSL_write"));
2112
2153
  /* fallthrough */
2113
2154
  default:
2114
2155
  ossl_raise(eSSLError, "SSL_write");
@@ -2116,6 +2157,28 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
2116
2157
  }
2117
2158
  }
2118
2159
 
2160
+
2161
+ static VALUE
2162
+ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
2163
+ {
2164
+ StringValue(str);
2165
+ int frozen = RB_OBJ_FROZEN(str);
2166
+ if (!frozen) {
2167
+ rb_str_locktmp(str);
2168
+ }
2169
+ int state;
2170
+ VALUE args[3] = {self, str, opts};
2171
+ VALUE result = rb_protect(ossl_ssl_write_internal_safe, (VALUE)args, &state);
2172
+ if (!frozen) {
2173
+ rb_str_unlocktmp(str);
2174
+ }
2175
+
2176
+ if (state) {
2177
+ rb_jump_tag(state);
2178
+ }
2179
+ return result;
2180
+ }
2181
+
2119
2182
  /*
2120
2183
  * call-seq:
2121
2184
  * ssl.syswrite(string) => Integer
@@ -2160,12 +2223,12 @@ ossl_ssl_stop(VALUE self)
2160
2223
 
2161
2224
  GetSSL(self, ssl);
2162
2225
  if (!ssl_started(ssl))
2163
- return Qnil;
2226
+ return Qnil;
2164
2227
  ret = SSL_shutdown(ssl);
2165
2228
  if (ret == 1) /* Have already received close_notify */
2166
- return Qnil;
2229
+ return Qnil;
2167
2230
  if (ret == 0) /* Sent close_notify, but we don't wait for reply */
2168
- return Qnil;
2231
+ return Qnil;
2169
2232
 
2170
2233
  /*
2171
2234
  * XXX: Something happened. Possibly it failed because the underlying socket
@@ -2251,20 +2314,20 @@ ossl_ssl_get_peer_cert_chain(VALUE self)
2251
2314
  num = sk_X509_num(chain);
2252
2315
  ary = rb_ary_new2(num);
2253
2316
  for (i = 0; i < num; i++){
2254
- cert = sk_X509_value(chain, i);
2255
- rb_ary_push(ary, ossl_x509_new(cert));
2317
+ cert = sk_X509_value(chain, i);
2318
+ rb_ary_push(ary, ossl_x509_new(cert));
2256
2319
  }
2257
2320
 
2258
2321
  return ary;
2259
2322
  }
2260
2323
 
2261
2324
  /*
2262
- * call-seq:
2263
- * ssl.ssl_version => String
2264
- *
2265
- * Returns a String representing the SSL/TLS version that was negotiated
2266
- * for the connection, for example "TLSv1.2".
2267
- */
2325
+ * call-seq:
2326
+ * ssl.ssl_version => String
2327
+ *
2328
+ * Returns a String representing the SSL/TLS version that was negotiated
2329
+ * for the connection, for example "TLSv1.2".
2330
+ */
2268
2331
  static VALUE
2269
2332
  ossl_ssl_get_version(VALUE self)
2270
2333
  {
@@ -2385,10 +2448,10 @@ ossl_ssl_set_hostname(VALUE self, VALUE arg)
2385
2448
  GetSSL(self, ssl);
2386
2449
 
2387
2450
  if (!NIL_P(arg))
2388
- hostname = StringValueCStr(arg);
2451
+ hostname = StringValueCStr(arg);
2389
2452
 
2390
2453
  if (!SSL_set_tlsext_host_name(ssl, hostname))
2391
- ossl_raise(eSSLError, NULL);
2454
+ ossl_raise(eSSLError, NULL);
2392
2455
 
2393
2456
  /* for SSLSocket#hostname */
2394
2457
  rb_ivar_set(self, id_i_hostname, arg);
@@ -2467,7 +2530,7 @@ ossl_ssl_get_peer_finished(VALUE self)
2467
2530
 
2468
2531
  /*
2469
2532
  * call-seq:
2470
- * ssl.client_ca => [x509name, ...]
2533
+ * ssl.client_ca => [x509name, ...] or nil
2471
2534
  *
2472
2535
  * Returns the list of client CAs. Please note that in contrast to
2473
2536
  * SSLContext#client_ca= no array of X509::Certificate is returned but
@@ -2485,6 +2548,8 @@ ossl_ssl_get_client_ca_list(VALUE self)
2485
2548
  GetSSL(self, ssl);
2486
2549
 
2487
2550
  ca = SSL_get_client_CA_list(ssl);
2551
+ if (!ca)
2552
+ return Qnil;
2488
2553
  return ossl_x509name_sk2ary(ca);
2489
2554
  }
2490
2555
 
@@ -2507,9 +2572,9 @@ ossl_ssl_npn_protocol(VALUE self)
2507
2572
 
2508
2573
  SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
2509
2574
  if (!outlen)
2510
- return Qnil;
2575
+ return Qnil;
2511
2576
  else
2512
- return rb_str_new((const char *) out, outlen);
2577
+ return rb_str_new((const char *) out, outlen);
2513
2578
  }
2514
2579
  # endif
2515
2580
 
@@ -2531,9 +2596,9 @@ ossl_ssl_alpn_protocol(VALUE self)
2531
2596
 
2532
2597
  SSL_get0_alpn_selected(ssl, &out, &outlen);
2533
2598
  if (!outlen)
2534
- return Qnil;
2599
+ return Qnil;
2535
2600
  else
2536
- return rb_str_new((const char *) out, outlen);
2601
+ return rb_str_new((const char *) out, outlen);
2537
2602
  }
2538
2603
 
2539
2604
  /*
@@ -2566,15 +2631,15 @@ ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self)
2566
2631
  str = rb_str_new(0, len);
2567
2632
  p = (unsigned char *)RSTRING_PTR(str);
2568
2633
  if (!NIL_P(context)) {
2569
- use_ctx = 1;
2570
- StringValue(context);
2571
- ctx = (unsigned char *)RSTRING_PTR(context);
2572
- ctx_len = RSTRING_LEN(context);
2634
+ use_ctx = 1;
2635
+ StringValue(context);
2636
+ ctx = (unsigned char *)RSTRING_PTR(context);
2637
+ ctx_len = RSTRING_LEN(context);
2573
2638
  }
2574
2639
  ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label),
2575
- RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
2640
+ RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
2576
2641
  if (ret == 0 || ret == -1) {
2577
- ossl_raise(eSSLError, "SSL_export_keying_material");
2642
+ ossl_raise(eSSLError, "SSL_export_keying_material");
2578
2643
  }
2579
2644
  return str;
2580
2645
  }
@@ -2593,17 +2658,77 @@ ossl_ssl_tmp_key(VALUE self)
2593
2658
 
2594
2659
  GetSSL(self, ssl);
2595
2660
  if (!SSL_get_server_tmp_key(ssl, &key))
2596
- return Qnil;
2597
- return ossl_pkey_new(key);
2661
+ return Qnil;
2662
+ return ossl_pkey_wrap(key);
2598
2663
  }
2664
+
2665
+ #ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
2666
+ /*
2667
+ * call-seq:
2668
+ * ssl.sigalg => String or nil
2669
+ *
2670
+ * Returns the signature algorithm name, the IANA name of the signature scheme
2671
+ * used by the local to sign the TLS handshake.
2672
+ */
2673
+ static VALUE
2674
+ ossl_ssl_get_sigalg(VALUE self)
2675
+ {
2676
+ SSL *ssl;
2677
+ const char *name;
2678
+
2679
+ GetSSL(self, ssl);
2680
+ if (!SSL_get0_signature_name(ssl, &name))
2681
+ return Qnil;
2682
+ return rb_str_new_cstr(name);
2683
+ }
2684
+
2685
+ /*
2686
+ * call-seq:
2687
+ * ssl.peer_sigalg => String or nil
2688
+ *
2689
+ * Returns the signature algorithm name, the IANA name of the signature scheme
2690
+ * used by the peer to sign the TLS handshake.
2691
+ */
2692
+ static VALUE
2693
+ ossl_ssl_get_peer_sigalg(VALUE self)
2694
+ {
2695
+ SSL *ssl;
2696
+ const char *name;
2697
+
2698
+ GetSSL(self, ssl);
2699
+ if (!SSL_get0_peer_signature_name(ssl, &name))
2700
+ return Qnil;
2701
+ return rb_str_new_cstr(name);
2702
+ }
2703
+ #endif
2704
+
2705
+ #ifdef HAVE_SSL_GET0_GROUP_NAME
2706
+ /*
2707
+ * call-seq:
2708
+ * ssl.group => String or nil
2709
+ *
2710
+ * Returns the name of the group that was used for the key agreement of the
2711
+ * current TLS session establishment.
2712
+ */
2713
+ static VALUE
2714
+ ossl_ssl_get_group(VALUE self)
2715
+ {
2716
+ SSL *ssl;
2717
+ const char *name;
2718
+
2719
+ GetSSL(self, ssl);
2720
+ if (!(name = SSL_get0_group_name(ssl)))
2721
+ return Qnil;
2722
+ return rb_str_new_cstr(name);
2723
+ }
2724
+ #endif
2725
+
2599
2726
  #endif /* !defined(OPENSSL_NO_SOCK) */
2600
2727
 
2601
2728
  void
2602
2729
  Init_ossl_ssl(void)
2603
2730
  {
2604
2731
  #if 0
2605
- mOSSL = rb_define_module("OpenSSL");
2606
- eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
2607
2732
  rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
2608
2733
  rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
2609
2734
  #endif
@@ -2614,10 +2739,10 @@ Init_ossl_ssl(void)
2614
2739
 
2615
2740
  ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_ptr_idx", 0, 0, 0);
2616
2741
  if (ossl_ssl_ex_ptr_idx < 0)
2617
- ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
2742
+ ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
2618
2743
  ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2619
2744
  if (ossl_sslctx_ex_ptr_idx < 0)
2620
- ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2745
+ ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2621
2746
 
2622
2747
  /* Document-module: OpenSSL::SSL
2623
2748
  *
@@ -2755,6 +2880,23 @@ Init_ossl_ssl(void)
2755
2880
  */
2756
2881
  rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
2757
2882
 
2883
+ #ifndef OPENSSL_NO_DH
2884
+ /*
2885
+ * A callback invoked when DH parameters are required for ephemeral DH key
2886
+ * exchange.
2887
+ *
2888
+ * The callback is invoked with the SSLSocket, a
2889
+ * flag indicating the use of an export cipher and the keylength
2890
+ * required.
2891
+ *
2892
+ * The callback must return an OpenSSL::PKey::DH instance of the correct
2893
+ * key length.
2894
+ *
2895
+ * <b>Deprecated in version 3.0.</b> Use #tmp_dh= instead.
2896
+ */
2897
+ rb_attr(cSSLContext, rb_intern_const("tmp_dh_callback"), 1, 1, Qfalse);
2898
+ #endif
2899
+
2758
2900
  /*
2759
2901
  * Sets the context in which a session can be reused. This allows
2760
2902
  * sessions for multiple applications to be distinguished, for example, by
@@ -2897,17 +3039,22 @@ Init_ossl_ssl(void)
2897
3039
 
2898
3040
  rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2899
3041
  rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
2900
- rb_define_private_method(cSSLContext, "set_minmax_proto_version",
2901
- ossl_sslctx_set_minmax_proto_version, 2);
3042
+ rb_define_method(cSSLContext, "min_version=", ossl_sslctx_set_min_version, 1);
3043
+ rb_define_method(cSSLContext, "max_version=", ossl_sslctx_set_max_version, 1);
2902
3044
  rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2903
3045
  rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
2904
- #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
2905
3046
  rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1);
3047
+ #ifdef HAVE_SSL_CTX_SET1_SIGALGS_LIST // Not in LibreSSL yet
3048
+ rb_define_method(cSSLContext, "sigalgs=", ossl_sslctx_set_sigalgs, 1);
3049
+ #endif
3050
+ #ifdef HAVE_SSL_CTX_SET1_CLIENT_SIGALGS_LIST // Not in LibreSSL or AWS-LC yet
3051
+ rb_define_method(cSSLContext, "client_sigalgs=", ossl_sslctx_set_client_sigalgs, 1);
2906
3052
  #endif
2907
3053
  #ifndef OPENSSL_NO_DH
2908
3054
  rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
2909
3055
  #endif
2910
- rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
3056
+ rb_define_method(cSSLContext, "groups=", ossl_sslctx_set_groups, 1);
3057
+ rb_define_alias(cSSLContext, "ecdh_curves=", "groups=");
2911
3058
  rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
2912
3059
  rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
2913
3060
  #ifdef SSL_MODE_SEND_FALLBACK_SCSV
@@ -3014,6 +3161,13 @@ Init_ossl_ssl(void)
3014
3161
  # ifdef OSSL_USE_NEXTPROTONEG
3015
3162
  rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
3016
3163
  # endif
3164
+ #ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
3165
+ rb_define_method(cSSLSocket, "sigalg", ossl_ssl_get_sigalg, 0);
3166
+ rb_define_method(cSSLSocket, "peer_sigalg", ossl_ssl_get_peer_sigalg, 0);
3167
+ #endif
3168
+ #ifdef HAVE_SSL_GET0_GROUP_NAME
3169
+ rb_define_method(cSSLSocket, "group", ossl_ssl_get_group, 0);
3170
+ #endif
3017
3171
 
3018
3172
  rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
3019
3173
  rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
@@ -3039,7 +3193,7 @@ Init_ossl_ssl(void)
3039
3193
  #ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */
3040
3194
  rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES));
3041
3195
  #endif
3042
- #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
3196
+ #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1, missing in LibreSSL */
3043
3197
  rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
3044
3198
  #endif
3045
3199
  rb_define_const(mSSL, "OP_DONT_INSERT_EMPTY_FRAGMENTS", ULONG2NUM(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
@@ -3047,28 +3201,26 @@ Init_ossl_ssl(void)
3047
3201
  rb_define_const(mSSL, "OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION));
3048
3202
  rb_define_const(mSSL, "OP_NO_COMPRESSION", ULONG2NUM(SSL_OP_NO_COMPRESSION));
3049
3203
  rb_define_const(mSSL, "OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
3050
- #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
3204
+ #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1, missing in LibreSSL */
3051
3205
  rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
3052
3206
  #endif
3053
- #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */
3207
+ #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1, missing in LibreSSL */
3054
3208
  rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT));
3055
3209
  #endif
3056
- #ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */
3210
+ #ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1, missing in LibreSSL */
3057
3211
  rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA));
3058
3212
  #endif
3059
- #ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */
3213
+ #ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1, missing in LibreSSL */
3060
3214
  rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY));
3061
3215
  #endif
3062
3216
  rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
3063
3217
  rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
3064
3218
  rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
3065
3219
  rb_define_const(mSSL, "OP_NO_TLSv1_2", ULONG2NUM(SSL_OP_NO_TLSv1_2));
3066
- #ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
3067
3220
  rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
3068
- #endif
3069
3221
  rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
3070
3222
  rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
3071
- #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
3223
+ #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1, missing in LibreSSL */
3072
3224
  rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
3073
3225
  #endif
3074
3226
  rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
@@ -3130,17 +3282,14 @@ Init_ossl_ssl(void)
3130
3282
  rb_define_const(mSSL, "TLS1_1_VERSION", INT2NUM(TLS1_1_VERSION));
3131
3283
  /* TLS 1.2 */
3132
3284
  rb_define_const(mSSL, "TLS1_2_VERSION", INT2NUM(TLS1_2_VERSION));
3133
- #ifdef TLS1_3_VERSION /* OpenSSL 1.1.1 */
3134
3285
  /* TLS 1.3 */
3135
3286
  rb_define_const(mSSL, "TLS1_3_VERSION", INT2NUM(TLS1_3_VERSION));
3136
- #endif
3137
3287
 
3138
3288
 
3139
3289
  sym_exception = ID2SYM(rb_intern_const("exception"));
3140
3290
  sym_wait_readable = ID2SYM(rb_intern_const("wait_readable"));
3141
3291
  sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
3142
3292
 
3143
- id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
3144
3293
  id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
3145
3294
  id_each = rb_intern_const("each");
3146
3295
 
@@ -3171,9 +3320,11 @@ Init_ossl_ssl(void)
3171
3320
  DefIVarID(servername_cb);
3172
3321
  DefIVarID(verify_hostname);
3173
3322
  DefIVarID(keylog_cb);
3323
+ DefIVarID(tmp_dh_callback);
3174
3324
 
3175
3325
  DefIVarID(io);
3176
3326
  DefIVarID(context);
3177
3327
  DefIVarID(hostname);
3328
+ DefIVarID(sync_close);
3178
3329
  #endif /* !defined(OPENSSL_NO_SOCK) */
3179
3330
  }