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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +3 -0
- data/History.md +85 -0
- data/README.md +12 -11
- data/ext/openssl/extconf.rb +30 -69
- data/ext/openssl/openssl_missing.h +0 -206
- data/ext/openssl/ossl.c +280 -301
- data/ext/openssl/ossl.h +15 -10
- data/ext/openssl/ossl_asn1.c +598 -406
- data/ext/openssl/ossl_asn1.h +15 -1
- data/ext/openssl/ossl_bio.c +3 -3
- data/ext/openssl/ossl_bn.c +286 -291
- data/ext/openssl/ossl_cipher.c +252 -203
- data/ext/openssl/ossl_cipher.h +10 -1
- data/ext/openssl/ossl_config.c +1 -6
- data/ext/openssl/ossl_digest.c +74 -43
- data/ext/openssl/ossl_digest.h +9 -1
- data/ext/openssl/ossl_engine.c +39 -103
- data/ext/openssl/ossl_hmac.c +30 -36
- data/ext/openssl/ossl_kdf.c +42 -53
- data/ext/openssl/ossl_ns_spki.c +31 -37
- data/ext/openssl/ossl_ocsp.c +214 -241
- data/ext/openssl/ossl_pkcs12.c +26 -26
- data/ext/openssl/ossl_pkcs7.c +175 -145
- data/ext/openssl/ossl_pkey.c +162 -178
- data/ext/openssl/ossl_pkey.h +99 -99
- data/ext/openssl/ossl_pkey_dh.c +31 -68
- data/ext/openssl/ossl_pkey_dsa.c +15 -54
- data/ext/openssl/ossl_pkey_ec.c +179 -237
- data/ext/openssl/ossl_pkey_rsa.c +56 -103
- data/ext/openssl/ossl_provider.c +0 -7
- data/ext/openssl/ossl_rand.c +7 -14
- data/ext/openssl/ossl_ssl.c +478 -353
- data/ext/openssl/ossl_ssl.h +8 -8
- data/ext/openssl/ossl_ssl_session.c +93 -97
- data/ext/openssl/ossl_ts.c +81 -127
- data/ext/openssl/ossl_x509.c +9 -28
- data/ext/openssl/ossl_x509attr.c +33 -54
- data/ext/openssl/ossl_x509cert.c +69 -100
- data/ext/openssl/ossl_x509crl.c +78 -89
- data/ext/openssl/ossl_x509ext.c +45 -66
- data/ext/openssl/ossl_x509name.c +63 -88
- data/ext/openssl/ossl_x509req.c +55 -62
- data/ext/openssl/ossl_x509revoked.c +27 -41
- data/ext/openssl/ossl_x509store.c +38 -56
- data/lib/openssl/buffering.rb +30 -24
- data/lib/openssl/digest.rb +1 -1
- data/lib/openssl/pkey.rb +71 -49
- data/lib/openssl/ssl.rb +12 -79
- data/lib/openssl/version.rb +2 -1
- data/lib/openssl/x509.rb +9 -0
- data/lib/openssl.rb +9 -6
- metadata +1 -3
- data/ext/openssl/openssl_missing.c +0 -40
- data/lib/openssl/asn1.rb +0 -188
data/ext/openssl/ossl_ssl.c
CHANGED
|
@@ -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
|
-
|
|
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,
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
256
|
-
|
|
144
|
+
VALUE ctx_obj, cb, obj;
|
|
145
|
+
const DH *dh;
|
|
257
146
|
|
|
258
|
-
|
|
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
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if
|
|
265
|
-
|
|
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)
|
|
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
|
-
|
|
281
|
-
|
|
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
|
-
|
|
291
|
-
|
|
170
|
+
rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
|
|
171
|
+
return NULL;
|
|
292
172
|
}
|
|
293
|
-
|
|
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
|
-
|
|
313
|
-
|
|
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
|
-
|
|
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
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
582
|
-
|
|
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
|
-
|
|
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
|
-
|
|
657
|
-
|
|
658
|
-
|
|
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
|
-
|
|
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
|
-
|
|
674
|
-
|
|
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
|
-
|
|
556
|
+
VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
|
|
687
557
|
|
|
688
|
-
|
|
689
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
660
|
+
SSL_CTX_set_options(ctx, SSL_OP_ALL);
|
|
791
661
|
} else {
|
|
792
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
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
|
-
|
|
832
|
-
|
|
833
|
-
|
|
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
|
-
|
|
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
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
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
|
-
|
|
872
|
-
|
|
744
|
+
else{
|
|
745
|
+
client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
|
|
873
746
|
if (!SSL_CTX_add_client_CA(ctx, client_ca)){
|
|
874
|
-
|
|
875
|
-
|
|
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
|
-
|
|
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
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
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
|
-
|
|
918
|
-
|
|
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
|
-
|
|
797
|
+
VALUE rprotos = ssl_encode_npn_protocols(val);
|
|
925
798
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
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
|
-
|
|
934
|
-
|
|
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
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
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
|
-
|
|
950
|
-
|
|
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
|
-
|
|
954
|
-
|
|
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
|
-
|
|
958
|
-
|
|
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
|
-
|
|
837
|
+
OSSL_Debug("SSL TLSEXT servername callback added");
|
|
965
838
|
}
|
|
966
839
|
|
|
967
|
-
#if
|
|
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
|
|
1057
|
-
* context
|
|
1058
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
1179
|
+
* ctx.groups = groups_list
|
|
1180
|
+
* ctx.ecdh_curves = groups_list
|
|
1158
1181
|
*
|
|
1159
|
-
* Sets the list of
|
|
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
|
|
1162
|
-
*
|
|
1163
|
-
* shared
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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 (!
|
|
1189
|
-
|
|
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
|
-
|
|
1347
|
+
rb_raise(rb_eArgError, "certificate does not contain public key");
|
|
1336
1348
|
if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
|
|
1337
|
-
|
|
1349
|
+
rb_raise(rb_eArgError, "public key mismatch");
|
|
1338
1350
|
|
|
1339
1351
|
if (argc >= 3)
|
|
1340
|
-
|
|
1352
|
+
extra_chain = ossl_x509_ary2sk(extra_chain_ary);
|
|
1341
1353
|
|
|
1342
1354
|
if (!SSL_CTX_use_certificate(ctx, x509)) {
|
|
1343
|
-
|
|
1344
|
-
|
|
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
|
-
|
|
1348
|
-
|
|
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
|
-
|
|
1640
|
+
ossl_raise(eSSLError, "SSL already initialized");
|
|
1629
1641
|
|
|
1630
1642
|
if (rb_scan_args(argc, argv, "11", &io, &v_ctx) == 1)
|
|
1631
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1948
|
+
rb_scan_args(argc, argv, "11:", &len, &str, &opts);
|
|
1937
1949
|
} else {
|
|
1938
|
-
|
|
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
|
-
|
|
1958
|
+
str = rb_str_new(0, ilen);
|
|
1947
1959
|
else {
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
2201
|
+
return Qnil;
|
|
2164
2202
|
ret = SSL_shutdown(ssl);
|
|
2165
2203
|
if (ret == 1) /* Have already received close_notify */
|
|
2166
|
-
|
|
2204
|
+
return Qnil;
|
|
2167
2205
|
if (ret == 0) /* Sent close_notify, but we don't wait for reply */
|
|
2168
|
-
|
|
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
|
-
|
|
2255
|
-
|
|
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
|
-
|
|
2426
|
+
hostname = StringValueCStr(arg);
|
|
2389
2427
|
|
|
2390
2428
|
if (!SSL_set_tlsext_host_name(ssl, hostname))
|
|
2391
|
-
|
|
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
|
-
|
|
2550
|
+
return Qnil;
|
|
2511
2551
|
else
|
|
2512
|
-
|
|
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
|
-
|
|
2574
|
+
return Qnil;
|
|
2535
2575
|
else
|
|
2536
|
-
|
|
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
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
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
|
-
|
|
2615
|
+
RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
|
|
2576
2616
|
if (ret == 0 || ret == -1) {
|
|
2577
|
-
|
|
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
|
-
|
|
2597
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2901
|
-
|
|
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, "
|
|
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);
|