openssl 3.3.2 → 4.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -0
  3. data/History.md +85 -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 +252 -203
  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 +175 -145
  25. data/ext/openssl/ossl_pkey.c +162 -178
  26. data/ext/openssl/ossl_pkey.h +99 -99
  27. data/ext/openssl/ossl_pkey_dh.c +31 -68
  28. data/ext/openssl/ossl_pkey_dsa.c +15 -54
  29. data/ext/openssl/ossl_pkey_ec.c +179 -237
  30. data/ext/openssl/ossl_pkey_rsa.c +56 -103
  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 +478 -353
  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 -79
  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 +1 -3
  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,18 +36,17 @@ 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;
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;
56
50
  static ID id_i_io, id_i_context, id_i_hostname;
57
51
 
58
52
  static int ossl_ssl_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
1158
1181
  *
1159
- * Sets the list of "supported elliptic curves" for this context.
1182
+ * Sets the list of supported groups for key agreement for this context.
1160
1183
  *
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.
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.
1187
+ *
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);
@@ -1625,23 +1637,23 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1625
1637
 
1626
1638
  TypedData_Get_Struct(self, SSL, &ossl_ssl_type, ssl);
1627
1639
  if (ssl)
1628
- ossl_raise(eSSLError, "SSL already initialized");
1640
+ ossl_raise(eSSLError, "SSL already initialized");
1629
1641
 
1630
1642
  if (rb_scan_args(argc, argv, "11", &io, &v_ctx) == 1)
1631
- v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
1643
+ v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
1632
1644
 
1633
1645
  GetSSLCTX(v_ctx, ctx);
1634
1646
  rb_ivar_set(self, id_i_context, v_ctx);
1635
1647
  ossl_sslctx_setup(v_ctx);
1636
1648
 
1637
1649
  if (rb_respond_to(io, rb_intern("nonblock=")))
1638
- rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
1650
+ rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
1639
1651
  Check_Type(io, T_FILE);
1640
1652
  rb_ivar_set(self, id_i_io, io);
1641
1653
 
1642
1654
  ssl = SSL_new(ctx);
1643
1655
  if (!ssl)
1644
- ossl_raise(eSSLError, NULL);
1656
+ ossl_raise(eSSLError, NULL);
1645
1657
  RTYPEDDATA_DATA(self) = ssl;
1646
1658
 
1647
1659
  SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
@@ -1672,7 +1684,7 @@ ossl_ssl_setup(VALUE self)
1672
1684
 
1673
1685
  GetSSL(self, ssl);
1674
1686
  if (ssl_started(ssl))
1675
- return Qtrue;
1687
+ return Qtrue;
1676
1688
 
1677
1689
  io = rb_attr_get(self, id_i_io);
1678
1690
  GetOpenFile(io, fptr);
@@ -1694,14 +1706,14 @@ static void
1694
1706
  write_would_block(int nonblock)
1695
1707
  {
1696
1708
  if (nonblock)
1697
- ossl_raise(eSSLErrorWaitWritable, "write would block");
1709
+ ossl_raise(eSSLErrorWaitWritable, "write would block");
1698
1710
  }
1699
1711
 
1700
1712
  static void
1701
1713
  read_would_block(int nonblock)
1702
1714
  {
1703
1715
  if (nonblock)
1704
- ossl_raise(eSSLErrorWaitReadable, "read would block");
1716
+ ossl_raise(eSSLErrorWaitReadable, "read would block");
1705
1717
  }
1706
1718
 
1707
1719
  static int
@@ -1709,7 +1721,7 @@ no_exception_p(VALUE opts)
1709
1721
  {
1710
1722
  if (RB_TYPE_P(opts, T_HASH) &&
1711
1723
  rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse)
1712
- return 1;
1724
+ return 1;
1713
1725
  return 0;
1714
1726
  }
1715
1727
 
@@ -1933,9 +1945,9 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1933
1945
  VALUE opts = Qnil;
1934
1946
 
1935
1947
  if (nonblock) {
1936
- rb_scan_args(argc, argv, "11:", &len, &str, &opts);
1948
+ rb_scan_args(argc, argv, "11:", &len, &str, &opts);
1937
1949
  } else {
1938
- rb_scan_args(argc, argv, "11", &len, &str);
1950
+ rb_scan_args(argc, argv, "11", &len, &str);
1939
1951
  }
1940
1952
  GetSSL(self, ssl);
1941
1953
  if (!ssl_started(ssl))
@@ -1943,13 +1955,13 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1943
1955
 
1944
1956
  ilen = NUM2INT(len);
1945
1957
  if (NIL_P(str))
1946
- str = rb_str_new(0, ilen);
1958
+ str = rb_str_new(0, ilen);
1947
1959
  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));
1960
+ StringValue(str);
1961
+ if (RSTRING_LEN(str) >= ilen)
1962
+ rb_str_modify(str);
1963
+ else
1964
+ rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
1953
1965
  }
1954
1966
 
1955
1967
  if (ilen == 0) {
@@ -2054,28 +2066,32 @@ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
2054
2066
  }
2055
2067
 
2056
2068
  static VALUE
2057
- ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
2069
+ ossl_ssl_write_internal_safe(VALUE _args)
2058
2070
  {
2071
+ VALUE *args = (VALUE*)_args;
2072
+ VALUE self = args[0];
2073
+ VALUE str = args[1];
2074
+ VALUE opts = args[2];
2075
+
2059
2076
  SSL *ssl;
2060
2077
  rb_io_t *fptr;
2061
2078
  int num, nonblock = opts != Qfalse;
2062
- VALUE tmp, cb_state;
2079
+ VALUE cb_state;
2063
2080
 
2064
2081
  GetSSL(self, ssl);
2065
2082
  if (!ssl_started(ssl))
2066
2083
  rb_raise(eSSLError, "SSL session is not started yet");
2067
2084
 
2068
- tmp = rb_str_new_frozen(StringValue(str));
2069
2085
  VALUE io = rb_attr_get(self, id_i_io);
2070
2086
  GetOpenFile(io, fptr);
2071
2087
 
2072
2088
  /* SSL_write(3ssl) manpage states num == 0 is undefined */
2073
- num = RSTRING_LENINT(tmp);
2089
+ num = RSTRING_LENINT(str);
2074
2090
  if (num == 0)
2075
2091
  return INT2FIX(0);
2076
2092
 
2077
2093
  for (;;) {
2078
- int nwritten = SSL_write(ssl, RSTRING_PTR(tmp), num);
2094
+ int nwritten = SSL_write(ssl, RSTRING_PTR(str), num);
2079
2095
 
2080
2096
  cb_state = rb_attr_get(self, ID_callback_state);
2081
2097
  if (!NIL_P(cb_state)) {
@@ -2116,6 +2132,28 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
2116
2132
  }
2117
2133
  }
2118
2134
 
2135
+
2136
+ static VALUE
2137
+ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
2138
+ {
2139
+ StringValue(str);
2140
+ int frozen = RB_OBJ_FROZEN(str);
2141
+ if (!frozen) {
2142
+ rb_str_locktmp(str);
2143
+ }
2144
+ int state;
2145
+ VALUE args[3] = {self, str, opts};
2146
+ VALUE result = rb_protect(ossl_ssl_write_internal_safe, (VALUE)args, &state);
2147
+ if (!frozen) {
2148
+ rb_str_unlocktmp(str);
2149
+ }
2150
+
2151
+ if (state) {
2152
+ rb_jump_tag(state);
2153
+ }
2154
+ return result;
2155
+ }
2156
+
2119
2157
  /*
2120
2158
  * call-seq:
2121
2159
  * ssl.syswrite(string) => Integer
@@ -2160,12 +2198,12 @@ ossl_ssl_stop(VALUE self)
2160
2198
 
2161
2199
  GetSSL(self, ssl);
2162
2200
  if (!ssl_started(ssl))
2163
- return Qnil;
2201
+ return Qnil;
2164
2202
  ret = SSL_shutdown(ssl);
2165
2203
  if (ret == 1) /* Have already received close_notify */
2166
- return Qnil;
2204
+ return Qnil;
2167
2205
  if (ret == 0) /* Sent close_notify, but we don't wait for reply */
2168
- return Qnil;
2206
+ return Qnil;
2169
2207
 
2170
2208
  /*
2171
2209
  * XXX: Something happened. Possibly it failed because the underlying socket
@@ -2251,20 +2289,20 @@ ossl_ssl_get_peer_cert_chain(VALUE self)
2251
2289
  num = sk_X509_num(chain);
2252
2290
  ary = rb_ary_new2(num);
2253
2291
  for (i = 0; i < num; i++){
2254
- cert = sk_X509_value(chain, i);
2255
- rb_ary_push(ary, ossl_x509_new(cert));
2292
+ cert = sk_X509_value(chain, i);
2293
+ rb_ary_push(ary, ossl_x509_new(cert));
2256
2294
  }
2257
2295
 
2258
2296
  return ary;
2259
2297
  }
2260
2298
 
2261
2299
  /*
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
- */
2300
+ * call-seq:
2301
+ * ssl.ssl_version => String
2302
+ *
2303
+ * Returns a String representing the SSL/TLS version that was negotiated
2304
+ * for the connection, for example "TLSv1.2".
2305
+ */
2268
2306
  static VALUE
2269
2307
  ossl_ssl_get_version(VALUE self)
2270
2308
  {
@@ -2385,10 +2423,10 @@ ossl_ssl_set_hostname(VALUE self, VALUE arg)
2385
2423
  GetSSL(self, ssl);
2386
2424
 
2387
2425
  if (!NIL_P(arg))
2388
- hostname = StringValueCStr(arg);
2426
+ hostname = StringValueCStr(arg);
2389
2427
 
2390
2428
  if (!SSL_set_tlsext_host_name(ssl, hostname))
2391
- ossl_raise(eSSLError, NULL);
2429
+ ossl_raise(eSSLError, NULL);
2392
2430
 
2393
2431
  /* for SSLSocket#hostname */
2394
2432
  rb_ivar_set(self, id_i_hostname, arg);
@@ -2467,7 +2505,7 @@ ossl_ssl_get_peer_finished(VALUE self)
2467
2505
 
2468
2506
  /*
2469
2507
  * call-seq:
2470
- * ssl.client_ca => [x509name, ...]
2508
+ * ssl.client_ca => [x509name, ...] or nil
2471
2509
  *
2472
2510
  * Returns the list of client CAs. Please note that in contrast to
2473
2511
  * SSLContext#client_ca= no array of X509::Certificate is returned but
@@ -2485,6 +2523,8 @@ ossl_ssl_get_client_ca_list(VALUE self)
2485
2523
  GetSSL(self, ssl);
2486
2524
 
2487
2525
  ca = SSL_get_client_CA_list(ssl);
2526
+ if (!ca)
2527
+ return Qnil;
2488
2528
  return ossl_x509name_sk2ary(ca);
2489
2529
  }
2490
2530
 
@@ -2507,9 +2547,9 @@ ossl_ssl_npn_protocol(VALUE self)
2507
2547
 
2508
2548
  SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
2509
2549
  if (!outlen)
2510
- return Qnil;
2550
+ return Qnil;
2511
2551
  else
2512
- return rb_str_new((const char *) out, outlen);
2552
+ return rb_str_new((const char *) out, outlen);
2513
2553
  }
2514
2554
  # endif
2515
2555
 
@@ -2531,9 +2571,9 @@ ossl_ssl_alpn_protocol(VALUE self)
2531
2571
 
2532
2572
  SSL_get0_alpn_selected(ssl, &out, &outlen);
2533
2573
  if (!outlen)
2534
- return Qnil;
2574
+ return Qnil;
2535
2575
  else
2536
- return rb_str_new((const char *) out, outlen);
2576
+ return rb_str_new((const char *) out, outlen);
2537
2577
  }
2538
2578
 
2539
2579
  /*
@@ -2566,15 +2606,15 @@ ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self)
2566
2606
  str = rb_str_new(0, len);
2567
2607
  p = (unsigned char *)RSTRING_PTR(str);
2568
2608
  if (!NIL_P(context)) {
2569
- use_ctx = 1;
2570
- StringValue(context);
2571
- ctx = (unsigned char *)RSTRING_PTR(context);
2572
- ctx_len = RSTRING_LEN(context);
2609
+ use_ctx = 1;
2610
+ StringValue(context);
2611
+ ctx = (unsigned char *)RSTRING_PTR(context);
2612
+ ctx_len = RSTRING_LEN(context);
2573
2613
  }
2574
2614
  ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label),
2575
- RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
2615
+ RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
2576
2616
  if (ret == 0 || ret == -1) {
2577
- ossl_raise(eSSLError, "SSL_export_keying_material");
2617
+ ossl_raise(eSSLError, "SSL_export_keying_material");
2578
2618
  }
2579
2619
  return str;
2580
2620
  }
@@ -2593,17 +2633,77 @@ ossl_ssl_tmp_key(VALUE self)
2593
2633
 
2594
2634
  GetSSL(self, ssl);
2595
2635
  if (!SSL_get_server_tmp_key(ssl, &key))
2596
- return Qnil;
2597
- return ossl_pkey_new(key);
2636
+ return Qnil;
2637
+ return ossl_pkey_wrap(key);
2598
2638
  }
2639
+
2640
+ #ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
2641
+ /*
2642
+ * call-seq:
2643
+ * ssl.sigalg => String or nil
2644
+ *
2645
+ * Returns the signature algorithm name, the IANA name of the signature scheme
2646
+ * used by the local to sign the TLS handshake.
2647
+ */
2648
+ static VALUE
2649
+ ossl_ssl_get_sigalg(VALUE self)
2650
+ {
2651
+ SSL *ssl;
2652
+ const char *name;
2653
+
2654
+ GetSSL(self, ssl);
2655
+ if (!SSL_get0_signature_name(ssl, &name))
2656
+ return Qnil;
2657
+ return rb_str_new_cstr(name);
2658
+ }
2659
+
2660
+ /*
2661
+ * call-seq:
2662
+ * ssl.peer_sigalg => String or nil
2663
+ *
2664
+ * Returns the signature algorithm name, the IANA name of the signature scheme
2665
+ * used by the peer to sign the TLS handshake.
2666
+ */
2667
+ static VALUE
2668
+ ossl_ssl_get_peer_sigalg(VALUE self)
2669
+ {
2670
+ SSL *ssl;
2671
+ const char *name;
2672
+
2673
+ GetSSL(self, ssl);
2674
+ if (!SSL_get0_peer_signature_name(ssl, &name))
2675
+ return Qnil;
2676
+ return rb_str_new_cstr(name);
2677
+ }
2678
+ #endif
2679
+
2680
+ #ifdef HAVE_SSL_GET0_GROUP_NAME
2681
+ /*
2682
+ * call-seq:
2683
+ * ssl.group => String or nil
2684
+ *
2685
+ * Returns the name of the group that was used for the key agreement of the
2686
+ * current TLS session establishment.
2687
+ */
2688
+ static VALUE
2689
+ ossl_ssl_get_group(VALUE self)
2690
+ {
2691
+ SSL *ssl;
2692
+ const char *name;
2693
+
2694
+ GetSSL(self, ssl);
2695
+ if (!(name = SSL_get0_group_name(ssl)))
2696
+ return Qnil;
2697
+ return rb_str_new_cstr(name);
2698
+ }
2699
+ #endif
2700
+
2599
2701
  #endif /* !defined(OPENSSL_NO_SOCK) */
2600
2702
 
2601
2703
  void
2602
2704
  Init_ossl_ssl(void)
2603
2705
  {
2604
2706
  #if 0
2605
- mOSSL = rb_define_module("OpenSSL");
2606
- eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
2607
2707
  rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
2608
2708
  rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
2609
2709
  #endif
@@ -2614,10 +2714,10 @@ Init_ossl_ssl(void)
2614
2714
 
2615
2715
  ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_ptr_idx", 0, 0, 0);
2616
2716
  if (ossl_ssl_ex_ptr_idx < 0)
2617
- ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
2717
+ ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
2618
2718
  ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2619
2719
  if (ossl_sslctx_ex_ptr_idx < 0)
2620
- ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2720
+ ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2621
2721
 
2622
2722
  /* Document-module: OpenSSL::SSL
2623
2723
  *
@@ -2755,6 +2855,23 @@ Init_ossl_ssl(void)
2755
2855
  */
2756
2856
  rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
2757
2857
 
2858
+ #ifndef OPENSSL_NO_DH
2859
+ /*
2860
+ * A callback invoked when DH parameters are required for ephemeral DH key
2861
+ * exchange.
2862
+ *
2863
+ * The callback is invoked with the SSLSocket, a
2864
+ * flag indicating the use of an export cipher and the keylength
2865
+ * required.
2866
+ *
2867
+ * The callback must return an OpenSSL::PKey::DH instance of the correct
2868
+ * key length.
2869
+ *
2870
+ * <b>Deprecated in version 3.0.</b> Use #tmp_dh= instead.
2871
+ */
2872
+ rb_attr(cSSLContext, rb_intern_const("tmp_dh_callback"), 1, 1, Qfalse);
2873
+ #endif
2874
+
2758
2875
  /*
2759
2876
  * Sets the context in which a session can be reused. This allows
2760
2877
  * sessions for multiple applications to be distinguished, for example, by
@@ -2897,17 +3014,22 @@ Init_ossl_ssl(void)
2897
3014
 
2898
3015
  rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2899
3016
  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);
3017
+ rb_define_method(cSSLContext, "min_version=", ossl_sslctx_set_min_version, 1);
3018
+ rb_define_method(cSSLContext, "max_version=", ossl_sslctx_set_max_version, 1);
2902
3019
  rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2903
3020
  rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
2904
- #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
2905
3021
  rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1);
3022
+ #ifdef HAVE_SSL_CTX_SET1_SIGALGS_LIST // Not in LibreSSL yet
3023
+ rb_define_method(cSSLContext, "sigalgs=", ossl_sslctx_set_sigalgs, 1);
3024
+ #endif
3025
+ #ifdef HAVE_SSL_CTX_SET1_CLIENT_SIGALGS_LIST // Not in LibreSSL or AWS-LC yet
3026
+ rb_define_method(cSSLContext, "client_sigalgs=", ossl_sslctx_set_client_sigalgs, 1);
2906
3027
  #endif
2907
3028
  #ifndef OPENSSL_NO_DH
2908
3029
  rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
2909
3030
  #endif
2910
- rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
3031
+ rb_define_method(cSSLContext, "groups=", ossl_sslctx_set_groups, 1);
3032
+ rb_define_alias(cSSLContext, "ecdh_curves=", "groups=");
2911
3033
  rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
2912
3034
  rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
2913
3035
  #ifdef SSL_MODE_SEND_FALLBACK_SCSV
@@ -3014,6 +3136,13 @@ Init_ossl_ssl(void)
3014
3136
  # ifdef OSSL_USE_NEXTPROTONEG
3015
3137
  rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
3016
3138
  # endif
3139
+ #ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
3140
+ rb_define_method(cSSLSocket, "sigalg", ossl_ssl_get_sigalg, 0);
3141
+ rb_define_method(cSSLSocket, "peer_sigalg", ossl_ssl_get_peer_sigalg, 0);
3142
+ #endif
3143
+ #ifdef HAVE_SSL_GET0_GROUP_NAME
3144
+ rb_define_method(cSSLSocket, "group", ossl_ssl_get_group, 0);
3145
+ #endif
3017
3146
 
3018
3147
  rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
3019
3148
  rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
@@ -3039,7 +3168,7 @@ Init_ossl_ssl(void)
3039
3168
  #ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */
3040
3169
  rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES));
3041
3170
  #endif
3042
- #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
3171
+ #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1, missing in LibreSSL */
3043
3172
  rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
3044
3173
  #endif
3045
3174
  rb_define_const(mSSL, "OP_DONT_INSERT_EMPTY_FRAGMENTS", ULONG2NUM(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
@@ -3047,28 +3176,26 @@ Init_ossl_ssl(void)
3047
3176
  rb_define_const(mSSL, "OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION));
3048
3177
  rb_define_const(mSSL, "OP_NO_COMPRESSION", ULONG2NUM(SSL_OP_NO_COMPRESSION));
3049
3178
  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 */
3179
+ #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1, missing in LibreSSL */
3051
3180
  rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
3052
3181
  #endif
3053
- #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */
3182
+ #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1, missing in LibreSSL */
3054
3183
  rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT));
3055
3184
  #endif
3056
- #ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */
3185
+ #ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1, missing in LibreSSL */
3057
3186
  rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA));
3058
3187
  #endif
3059
- #ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */
3188
+ #ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1, missing in LibreSSL */
3060
3189
  rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY));
3061
3190
  #endif
3062
3191
  rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
3063
3192
  rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
3064
3193
  rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
3065
3194
  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
3195
  rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
3068
- #endif
3069
3196
  rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
3070
3197
  rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
3071
- #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
3198
+ #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1, missing in LibreSSL */
3072
3199
  rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
3073
3200
  #endif
3074
3201
  rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
@@ -3130,17 +3257,14 @@ Init_ossl_ssl(void)
3130
3257
  rb_define_const(mSSL, "TLS1_1_VERSION", INT2NUM(TLS1_1_VERSION));
3131
3258
  /* TLS 1.2 */
3132
3259
  rb_define_const(mSSL, "TLS1_2_VERSION", INT2NUM(TLS1_2_VERSION));
3133
- #ifdef TLS1_3_VERSION /* OpenSSL 1.1.1 */
3134
3260
  /* TLS 1.3 */
3135
3261
  rb_define_const(mSSL, "TLS1_3_VERSION", INT2NUM(TLS1_3_VERSION));
3136
- #endif
3137
3262
 
3138
3263
 
3139
3264
  sym_exception = ID2SYM(rb_intern_const("exception"));
3140
3265
  sym_wait_readable = ID2SYM(rb_intern_const("wait_readable"));
3141
3266
  sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
3142
3267
 
3143
- id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
3144
3268
  id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
3145
3269
  id_each = rb_intern_const("each");
3146
3270
 
@@ -3171,6 +3295,7 @@ Init_ossl_ssl(void)
3171
3295
  DefIVarID(servername_cb);
3172
3296
  DefIVarID(verify_hostname);
3173
3297
  DefIVarID(keylog_cb);
3298
+ DefIVarID(tmp_dh_callback);
3174
3299
 
3175
3300
  DefIVarID(io);
3176
3301
  DefIVarID(context);