openssl 3.3.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +3 -0
- data/History.md +156 -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 +257 -209
- 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 +176 -146
- data/ext/openssl/ossl_pkey.c +163 -178
- data/ext/openssl/ossl_pkey.h +99 -99
- data/ext/openssl/ossl_pkey_dh.c +32 -67
- data/ext/openssl/ossl_pkey_dsa.c +16 -53
- data/ext/openssl/ossl_pkey_ec.c +181 -237
- data/ext/openssl/ossl_pkey_rsa.c +57 -102
- data/ext/openssl/ossl_provider.c +0 -7
- data/ext/openssl/ossl_rand.c +7 -14
- data/ext/openssl/ossl_ssl.c +544 -393
- 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 -80
- data/lib/openssl/version.rb +2 -1
- data/lib/openssl/x509.rb +9 -0
- data/lib/openssl.rb +9 -6
- metadata +3 -8
- 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,19 +36,18 @@ VALUE cSSLSocket;
|
|
|
41
36
|
static VALUE eSSLErrorWaitReadable;
|
|
42
37
|
static VALUE eSSLErrorWaitWritable;
|
|
43
38
|
|
|
44
|
-
static ID id_call, ID_callback_state,
|
|
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
|
-
|
|
56
|
-
static ID id_i_io, id_i_context, id_i_hostname;
|
|
43
|
+
id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
|
|
44
|
+
id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
|
|
45
|
+
id_i_client_cert_cb, id_i_timeout,
|
|
46
|
+
id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
|
|
47
|
+
id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
|
|
48
|
+
id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
|
|
49
|
+
id_i_verify_hostname, id_i_keylog_cb, id_i_tmp_dh_callback;
|
|
50
|
+
static ID id_i_io, id_i_context, id_i_hostname, id_i_sync_close;
|
|
57
51
|
|
|
58
52
|
static int ossl_ssl_ex_ptr_idx;
|
|
59
53
|
static int ossl_sslctx_ex_ptr_idx;
|
|
@@ -84,127 +78,24 @@ ossl_sslctx_s_alloc(VALUE klass)
|
|
|
84
78
|
{
|
|
85
79
|
SSL_CTX *ctx;
|
|
86
80
|
long mode = 0 |
|
|
87
|
-
|
|
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
|
|
1181
|
+
*
|
|
1182
|
+
* Sets the list of supported groups for key agreement for this context.
|
|
1158
1183
|
*
|
|
1159
|
-
*
|
|
1184
|
+
* For a TLS client, the list is directly used in the "supported_groups"
|
|
1185
|
+
* extension. For a server, the list is used by OpenSSL to determine the set of
|
|
1186
|
+
* shared supported groups. OpenSSL will pick the most appropriate one from it.
|
|
1160
1187
|
*
|
|
1161
|
-
*
|
|
1162
|
-
*
|
|
1163
|
-
*
|
|
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);
|
|
@@ -1578,32 +1590,31 @@ ossl_ssl_s_alloc(VALUE klass)
|
|
|
1578
1590
|
}
|
|
1579
1591
|
|
|
1580
1592
|
static VALUE
|
|
1581
|
-
peer_ip_address(VALUE
|
|
1593
|
+
peer_ip_address(VALUE io)
|
|
1582
1594
|
{
|
|
1583
|
-
VALUE remote_address = rb_funcall(
|
|
1595
|
+
VALUE remote_address = rb_funcall(io, rb_intern("remote_address"), 0);
|
|
1584
1596
|
|
|
1585
1597
|
return rb_funcall(remote_address, rb_intern("inspect_sockaddr"), 0);
|
|
1586
1598
|
}
|
|
1587
1599
|
|
|
1588
1600
|
static VALUE
|
|
1589
|
-
fallback_peer_ip_address(VALUE self, VALUE
|
|
1601
|
+
fallback_peer_ip_address(VALUE self, VALUE exc)
|
|
1590
1602
|
{
|
|
1591
1603
|
return rb_str_new_cstr("(null)");
|
|
1592
1604
|
}
|
|
1593
1605
|
|
|
1594
1606
|
static VALUE
|
|
1595
|
-
peeraddr_ip_str(VALUE
|
|
1607
|
+
peeraddr_ip_str(VALUE io)
|
|
1596
1608
|
{
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
return rb_rescue2(peer_ip_address, self, fallback_peer_ip_address, (VALUE)0, rb_eSystemCallError, NULL);
|
|
1609
|
+
return rb_rescue2(peer_ip_address, io, fallback_peer_ip_address, Qnil,
|
|
1610
|
+
rb_eSystemCallError, (VALUE)0);
|
|
1601
1611
|
}
|
|
1602
1612
|
|
|
1603
1613
|
/*
|
|
1604
1614
|
* call-seq:
|
|
1605
1615
|
* SSLSocket.new(io) => aSSLSocket
|
|
1606
1616
|
* SSLSocket.new(io, ctx) => aSSLSocket
|
|
1617
|
+
* SSLSocket.new(io, ctx, sync_close:) => aSSLSocket
|
|
1607
1618
|
*
|
|
1608
1619
|
* Creates a new SSL socket from _io_ which must be a real IO object (not an
|
|
1609
1620
|
* IO-like object that responds to read/write).
|
|
@@ -1611,6 +1622,10 @@ peeraddr_ip_str(VALUE self)
|
|
|
1611
1622
|
* If _ctx_ is provided the SSL Sockets initial params will be taken from
|
|
1612
1623
|
* the context.
|
|
1613
1624
|
*
|
|
1625
|
+
* The optional _sync_close_ keyword parameter sets the _sync_close_ instance
|
|
1626
|
+
* variable. Setting this to +true+ will cause the underlying socket to be
|
|
1627
|
+
* closed when the SSL/TLS connection is shut down.
|
|
1628
|
+
*
|
|
1614
1629
|
* The OpenSSL::Buffering module provides additional IO methods.
|
|
1615
1630
|
*
|
|
1616
1631
|
* This method will freeze the SSLContext if one is provided;
|
|
@@ -1619,29 +1634,42 @@ peeraddr_ip_str(VALUE self)
|
|
|
1619
1634
|
static VALUE
|
|
1620
1635
|
ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
|
|
1621
1636
|
{
|
|
1637
|
+
static ID kw_ids[1];
|
|
1638
|
+
VALUE kw_args[1];
|
|
1639
|
+
VALUE opts;
|
|
1640
|
+
|
|
1622
1641
|
VALUE io, v_ctx;
|
|
1623
1642
|
SSL *ssl;
|
|
1624
1643
|
SSL_CTX *ctx;
|
|
1625
1644
|
|
|
1626
1645
|
TypedData_Get_Struct(self, SSL, &ossl_ssl_type, ssl);
|
|
1627
1646
|
if (ssl)
|
|
1628
|
-
|
|
1647
|
+
ossl_raise(eSSLError, "SSL already initialized");
|
|
1648
|
+
|
|
1649
|
+
if (rb_scan_args(argc, argv, "11:", &io, &v_ctx, &opts) == 1)
|
|
1650
|
+
v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
|
|
1651
|
+
|
|
1652
|
+
if (!kw_ids[0]) {
|
|
1653
|
+
kw_ids[0] = rb_intern_const("sync_close");
|
|
1654
|
+
}
|
|
1629
1655
|
|
|
1630
|
-
|
|
1631
|
-
|
|
1656
|
+
rb_get_kwargs(opts, kw_ids, 0, 1, kw_args);
|
|
1657
|
+
if (kw_args[0] != Qundef) {
|
|
1658
|
+
rb_ivar_set(self, id_i_sync_close, kw_args[0]);
|
|
1659
|
+
}
|
|
1632
1660
|
|
|
1633
1661
|
GetSSLCTX(v_ctx, ctx);
|
|
1634
1662
|
rb_ivar_set(self, id_i_context, v_ctx);
|
|
1635
1663
|
ossl_sslctx_setup(v_ctx);
|
|
1636
1664
|
|
|
1637
1665
|
if (rb_respond_to(io, rb_intern("nonblock=")))
|
|
1638
|
-
|
|
1666
|
+
rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
|
|
1639
1667
|
Check_Type(io, T_FILE);
|
|
1640
1668
|
rb_ivar_set(self, id_i_io, io);
|
|
1641
1669
|
|
|
1642
1670
|
ssl = SSL_new(ctx);
|
|
1643
1671
|
if (!ssl)
|
|
1644
|
-
|
|
1672
|
+
ossl_raise(eSSLError, NULL);
|
|
1645
1673
|
RTYPEDDATA_DATA(self) = ssl;
|
|
1646
1674
|
|
|
1647
1675
|
SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
|
|
@@ -1672,7 +1700,7 @@ ossl_ssl_setup(VALUE self)
|
|
|
1672
1700
|
|
|
1673
1701
|
GetSSL(self, ssl);
|
|
1674
1702
|
if (ssl_started(ssl))
|
|
1675
|
-
|
|
1703
|
+
return Qtrue;
|
|
1676
1704
|
|
|
1677
1705
|
io = rb_attr_get(self, id_i_io);
|
|
1678
1706
|
GetOpenFile(io, fptr);
|
|
@@ -1684,24 +1712,28 @@ ossl_ssl_setup(VALUE self)
|
|
|
1684
1712
|
return Qtrue;
|
|
1685
1713
|
}
|
|
1686
1714
|
|
|
1715
|
+
static int
|
|
1716
|
+
errno_mapped(void)
|
|
1717
|
+
{
|
|
1687
1718
|
#ifdef _WIN32
|
|
1688
|
-
|
|
1719
|
+
return rb_w32_map_errno(WSAGetLastError());
|
|
1689
1720
|
#else
|
|
1690
|
-
|
|
1721
|
+
return errno;
|
|
1691
1722
|
#endif
|
|
1723
|
+
}
|
|
1692
1724
|
|
|
1693
1725
|
static void
|
|
1694
1726
|
write_would_block(int nonblock)
|
|
1695
1727
|
{
|
|
1696
1728
|
if (nonblock)
|
|
1697
|
-
|
|
1729
|
+
ossl_raise(eSSLErrorWaitWritable, "write would block");
|
|
1698
1730
|
}
|
|
1699
1731
|
|
|
1700
1732
|
static void
|
|
1701
1733
|
read_would_block(int nonblock)
|
|
1702
1734
|
{
|
|
1703
1735
|
if (nonblock)
|
|
1704
|
-
|
|
1736
|
+
ossl_raise(eSSLErrorWaitReadable, "read would block");
|
|
1705
1737
|
}
|
|
1706
1738
|
|
|
1707
1739
|
static int
|
|
@@ -1709,7 +1741,7 @@ no_exception_p(VALUE opts)
|
|
|
1709
1741
|
{
|
|
1710
1742
|
if (RB_TYPE_P(opts, T_HASH) &&
|
|
1711
1743
|
rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse)
|
|
1712
|
-
|
|
1744
|
+
return 1;
|
|
1713
1745
|
return 0;
|
|
1714
1746
|
}
|
|
1715
1747
|
|
|
@@ -1729,13 +1761,13 @@ static void
|
|
|
1729
1761
|
io_wait_writable(VALUE io)
|
|
1730
1762
|
{
|
|
1731
1763
|
#ifdef HAVE_RB_IO_MAYBE_WAIT
|
|
1732
|
-
if (!
|
|
1764
|
+
if (!rb_io_wait(io, INT2NUM(RUBY_IO_WRITABLE), RUBY_IO_TIMEOUT_DEFAULT)) {
|
|
1733
1765
|
rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become writable!");
|
|
1734
1766
|
}
|
|
1735
1767
|
#else
|
|
1736
1768
|
rb_io_t *fptr;
|
|
1737
1769
|
GetOpenFile(io, fptr);
|
|
1738
|
-
|
|
1770
|
+
rb_thread_fd_writable(fptr->fd);
|
|
1739
1771
|
#endif
|
|
1740
1772
|
}
|
|
1741
1773
|
|
|
@@ -1743,13 +1775,13 @@ static void
|
|
|
1743
1775
|
io_wait_readable(VALUE io)
|
|
1744
1776
|
{
|
|
1745
1777
|
#ifdef HAVE_RB_IO_MAYBE_WAIT
|
|
1746
|
-
if (!
|
|
1778
|
+
if (!rb_io_wait(io, INT2NUM(RUBY_IO_READABLE), RUBY_IO_TIMEOUT_DEFAULT)) {
|
|
1747
1779
|
rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become readable!");
|
|
1748
1780
|
}
|
|
1749
1781
|
#else
|
|
1750
1782
|
rb_io_t *fptr;
|
|
1751
1783
|
GetOpenFile(io, fptr);
|
|
1752
|
-
|
|
1784
|
+
rb_thread_wait_fd(fptr->fd);
|
|
1753
1785
|
#endif
|
|
1754
1786
|
}
|
|
1755
1787
|
|
|
@@ -1757,7 +1789,6 @@ static VALUE
|
|
|
1757
1789
|
ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
|
|
1758
1790
|
{
|
|
1759
1791
|
SSL *ssl;
|
|
1760
|
-
int ret, ret2;
|
|
1761
1792
|
VALUE cb_state;
|
|
1762
1793
|
int nonblock = opts != Qfalse;
|
|
1763
1794
|
|
|
@@ -1767,7 +1798,8 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
|
|
|
1767
1798
|
|
|
1768
1799
|
VALUE io = rb_attr_get(self, id_i_io);
|
|
1769
1800
|
for (;;) {
|
|
1770
|
-
ret = func(ssl);
|
|
1801
|
+
int ret = func(ssl);
|
|
1802
|
+
int saved_errno = errno_mapped();
|
|
1771
1803
|
|
|
1772
1804
|
cb_state = rb_attr_get(self, ID_callback_state);
|
|
1773
1805
|
if (!NIL_P(cb_state)) {
|
|
@@ -1779,7 +1811,8 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
|
|
|
1779
1811
|
if (ret > 0)
|
|
1780
1812
|
break;
|
|
1781
1813
|
|
|
1782
|
-
|
|
1814
|
+
int code = SSL_get_error(ssl, ret);
|
|
1815
|
+
switch (code) {
|
|
1783
1816
|
case SSL_ERROR_WANT_WRITE:
|
|
1784
1817
|
if (no_exception_p(opts)) { return sym_wait_writable; }
|
|
1785
1818
|
write_would_block(nonblock);
|
|
@@ -1793,10 +1826,11 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
|
|
|
1793
1826
|
case SSL_ERROR_SYSCALL:
|
|
1794
1827
|
#ifdef __APPLE__
|
|
1795
1828
|
/* See ossl_ssl_write_internal() */
|
|
1796
|
-
if (
|
|
1829
|
+
if (saved_errno == EPROTOTYPE)
|
|
1797
1830
|
continue;
|
|
1798
1831
|
#endif
|
|
1799
|
-
if (
|
|
1832
|
+
if (saved_errno)
|
|
1833
|
+
rb_exc_raise(rb_syserr_new(saved_errno, funcname));
|
|
1800
1834
|
/* fallthrough */
|
|
1801
1835
|
default: {
|
|
1802
1836
|
VALUE error_append = Qnil;
|
|
@@ -1817,10 +1851,10 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
|
|
|
1817
1851
|
ossl_raise(eSSLError,
|
|
1818
1852
|
"%s%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s%"PRIsVALUE,
|
|
1819
1853
|
funcname,
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
peeraddr_ip_str(
|
|
1854
|
+
code == SSL_ERROR_SYSCALL ? " SYSCALL" : "",
|
|
1855
|
+
code,
|
|
1856
|
+
saved_errno,
|
|
1857
|
+
peeraddr_ip_str(io),
|
|
1824
1858
|
SSL_state_string_long(ssl),
|
|
1825
1859
|
error_append);
|
|
1826
1860
|
}
|
|
@@ -1933,9 +1967,9 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
|
1933
1967
|
VALUE opts = Qnil;
|
|
1934
1968
|
|
|
1935
1969
|
if (nonblock) {
|
|
1936
|
-
|
|
1970
|
+
rb_scan_args(argc, argv, "11:", &len, &str, &opts);
|
|
1937
1971
|
} else {
|
|
1938
|
-
|
|
1972
|
+
rb_scan_args(argc, argv, "11", &len, &str);
|
|
1939
1973
|
}
|
|
1940
1974
|
GetSSL(self, ssl);
|
|
1941
1975
|
if (!ssl_started(ssl))
|
|
@@ -1943,13 +1977,13 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
|
1943
1977
|
|
|
1944
1978
|
ilen = NUM2INT(len);
|
|
1945
1979
|
if (NIL_P(str))
|
|
1946
|
-
|
|
1980
|
+
str = rb_str_new(0, ilen);
|
|
1947
1981
|
else {
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1982
|
+
StringValue(str);
|
|
1983
|
+
if (RSTRING_LEN(str) >= ilen)
|
|
1984
|
+
rb_str_modify(str);
|
|
1985
|
+
else
|
|
1986
|
+
rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
|
|
1953
1987
|
}
|
|
1954
1988
|
|
|
1955
1989
|
if (ilen == 0) {
|
|
@@ -1959,9 +1993,11 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
|
1959
1993
|
|
|
1960
1994
|
VALUE io = rb_attr_get(self, id_i_io);
|
|
1961
1995
|
|
|
1962
|
-
rb_str_locktmp(str);
|
|
1963
1996
|
for (;;) {
|
|
1997
|
+
rb_str_locktmp(str);
|
|
1964
1998
|
int nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
|
|
1999
|
+
int saved_errno = errno_mapped();
|
|
2000
|
+
rb_str_unlocktmp(str);
|
|
1965
2001
|
|
|
1966
2002
|
cb_state = rb_attr_get(self, ID_callback_state);
|
|
1967
2003
|
if (!NIL_P(cb_state)) {
|
|
@@ -1970,36 +2006,31 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
|
1970
2006
|
rb_jump_tag(NUM2INT(cb_state));
|
|
1971
2007
|
}
|
|
1972
2008
|
|
|
1973
|
-
switch (
|
|
2009
|
+
switch (SSL_get_error(ssl, nread)) {
|
|
1974
2010
|
case SSL_ERROR_NONE:
|
|
1975
|
-
rb_str_unlocktmp(str);
|
|
1976
2011
|
rb_str_set_len(str, nread);
|
|
1977
2012
|
return str;
|
|
1978
2013
|
case SSL_ERROR_ZERO_RETURN:
|
|
1979
|
-
rb_str_unlocktmp(str);
|
|
1980
2014
|
if (no_exception_p(opts)) { return Qnil; }
|
|
1981
2015
|
rb_eof_error();
|
|
1982
2016
|
case SSL_ERROR_WANT_WRITE:
|
|
1983
2017
|
if (nonblock) {
|
|
1984
|
-
rb_str_unlocktmp(str);
|
|
1985
2018
|
if (no_exception_p(opts)) { return sym_wait_writable; }
|
|
1986
2019
|
write_would_block(nonblock);
|
|
1987
2020
|
}
|
|
1988
2021
|
io_wait_writable(io);
|
|
1989
|
-
|
|
2022
|
+
break;
|
|
1990
2023
|
case SSL_ERROR_WANT_READ:
|
|
1991
2024
|
if (nonblock) {
|
|
1992
|
-
rb_str_unlocktmp(str);
|
|
1993
2025
|
if (no_exception_p(opts)) { return sym_wait_readable; }
|
|
1994
2026
|
read_would_block(nonblock);
|
|
1995
2027
|
}
|
|
1996
2028
|
io_wait_readable(io);
|
|
1997
|
-
|
|
2029
|
+
break;
|
|
1998
2030
|
case SSL_ERROR_SYSCALL:
|
|
1999
2031
|
if (!ERR_peek_error()) {
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
rb_sys_fail(0);
|
|
2032
|
+
if (saved_errno)
|
|
2033
|
+
rb_exc_raise(rb_syserr_new(saved_errno, "SSL_read"));
|
|
2003
2034
|
else {
|
|
2004
2035
|
/*
|
|
2005
2036
|
* The underlying BIO returned 0. This is actually a
|
|
@@ -2014,9 +2045,13 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
|
|
2014
2045
|
}
|
|
2015
2046
|
/* fall through */
|
|
2016
2047
|
default:
|
|
2017
|
-
rb_str_unlocktmp(str);
|
|
2018
2048
|
ossl_raise(eSSLError, "SSL_read");
|
|
2019
2049
|
}
|
|
2050
|
+
|
|
2051
|
+
// Ensure the buffer is not modified during io_wait_*able()
|
|
2052
|
+
rb_str_modify(str);
|
|
2053
|
+
if (rb_str_capacity(str) < (size_t)ilen)
|
|
2054
|
+
rb_raise(eSSLError, "read buffer was modified");
|
|
2020
2055
|
}
|
|
2021
2056
|
}
|
|
2022
2057
|
|
|
@@ -2054,28 +2089,33 @@ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
|
|
|
2054
2089
|
}
|
|
2055
2090
|
|
|
2056
2091
|
static VALUE
|
|
2057
|
-
|
|
2092
|
+
ossl_ssl_write_internal_safe(VALUE _args)
|
|
2058
2093
|
{
|
|
2094
|
+
VALUE *args = (VALUE*)_args;
|
|
2095
|
+
VALUE self = args[0];
|
|
2096
|
+
VALUE str = args[1];
|
|
2097
|
+
VALUE opts = args[2];
|
|
2098
|
+
|
|
2059
2099
|
SSL *ssl;
|
|
2060
2100
|
rb_io_t *fptr;
|
|
2061
2101
|
int num, nonblock = opts != Qfalse;
|
|
2062
|
-
VALUE
|
|
2102
|
+
VALUE cb_state;
|
|
2063
2103
|
|
|
2064
2104
|
GetSSL(self, ssl);
|
|
2065
2105
|
if (!ssl_started(ssl))
|
|
2066
2106
|
rb_raise(eSSLError, "SSL session is not started yet");
|
|
2067
2107
|
|
|
2068
|
-
tmp = rb_str_new_frozen(StringValue(str));
|
|
2069
2108
|
VALUE io = rb_attr_get(self, id_i_io);
|
|
2070
2109
|
GetOpenFile(io, fptr);
|
|
2071
2110
|
|
|
2072
2111
|
/* SSL_write(3ssl) manpage states num == 0 is undefined */
|
|
2073
|
-
num = RSTRING_LENINT(
|
|
2112
|
+
num = RSTRING_LENINT(str);
|
|
2074
2113
|
if (num == 0)
|
|
2075
2114
|
return INT2FIX(0);
|
|
2076
2115
|
|
|
2077
2116
|
for (;;) {
|
|
2078
|
-
int nwritten = SSL_write(ssl, RSTRING_PTR(
|
|
2117
|
+
int nwritten = SSL_write(ssl, RSTRING_PTR(str), num);
|
|
2118
|
+
int saved_errno = errno_mapped();
|
|
2079
2119
|
|
|
2080
2120
|
cb_state = rb_attr_get(self, ID_callback_state);
|
|
2081
2121
|
if (!NIL_P(cb_state)) {
|
|
@@ -2084,7 +2124,7 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|
|
2084
2124
|
rb_jump_tag(NUM2INT(cb_state));
|
|
2085
2125
|
}
|
|
2086
2126
|
|
|
2087
|
-
switch (
|
|
2127
|
+
switch (SSL_get_error(ssl, nwritten)) {
|
|
2088
2128
|
case SSL_ERROR_NONE:
|
|
2089
2129
|
return INT2NUM(nwritten);
|
|
2090
2130
|
case SSL_ERROR_WANT_WRITE:
|
|
@@ -2105,10 +2145,11 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|
|
2105
2145
|
* make the error handling in line with the socket library.
|
|
2106
2146
|
* [Bug #14713] https://bugs.ruby-lang.org/issues/14713
|
|
2107
2147
|
*/
|
|
2108
|
-
if (
|
|
2148
|
+
if (saved_errno == EPROTOTYPE)
|
|
2109
2149
|
continue;
|
|
2110
2150
|
#endif
|
|
2111
|
-
if (
|
|
2151
|
+
if (saved_errno)
|
|
2152
|
+
rb_exc_raise(rb_syserr_new(saved_errno, "SSL_write"));
|
|
2112
2153
|
/* fallthrough */
|
|
2113
2154
|
default:
|
|
2114
2155
|
ossl_raise(eSSLError, "SSL_write");
|
|
@@ -2116,6 +2157,28 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|
|
2116
2157
|
}
|
|
2117
2158
|
}
|
|
2118
2159
|
|
|
2160
|
+
|
|
2161
|
+
static VALUE
|
|
2162
|
+
ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
|
2163
|
+
{
|
|
2164
|
+
StringValue(str);
|
|
2165
|
+
int frozen = RB_OBJ_FROZEN(str);
|
|
2166
|
+
if (!frozen) {
|
|
2167
|
+
rb_str_locktmp(str);
|
|
2168
|
+
}
|
|
2169
|
+
int state;
|
|
2170
|
+
VALUE args[3] = {self, str, opts};
|
|
2171
|
+
VALUE result = rb_protect(ossl_ssl_write_internal_safe, (VALUE)args, &state);
|
|
2172
|
+
if (!frozen) {
|
|
2173
|
+
rb_str_unlocktmp(str);
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
if (state) {
|
|
2177
|
+
rb_jump_tag(state);
|
|
2178
|
+
}
|
|
2179
|
+
return result;
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2119
2182
|
/*
|
|
2120
2183
|
* call-seq:
|
|
2121
2184
|
* ssl.syswrite(string) => Integer
|
|
@@ -2160,12 +2223,12 @@ ossl_ssl_stop(VALUE self)
|
|
|
2160
2223
|
|
|
2161
2224
|
GetSSL(self, ssl);
|
|
2162
2225
|
if (!ssl_started(ssl))
|
|
2163
|
-
|
|
2226
|
+
return Qnil;
|
|
2164
2227
|
ret = SSL_shutdown(ssl);
|
|
2165
2228
|
if (ret == 1) /* Have already received close_notify */
|
|
2166
|
-
|
|
2229
|
+
return Qnil;
|
|
2167
2230
|
if (ret == 0) /* Sent close_notify, but we don't wait for reply */
|
|
2168
|
-
|
|
2231
|
+
return Qnil;
|
|
2169
2232
|
|
|
2170
2233
|
/*
|
|
2171
2234
|
* XXX: Something happened. Possibly it failed because the underlying socket
|
|
@@ -2251,20 +2314,20 @@ ossl_ssl_get_peer_cert_chain(VALUE self)
|
|
|
2251
2314
|
num = sk_X509_num(chain);
|
|
2252
2315
|
ary = rb_ary_new2(num);
|
|
2253
2316
|
for (i = 0; i < num; i++){
|
|
2254
|
-
|
|
2255
|
-
|
|
2317
|
+
cert = sk_X509_value(chain, i);
|
|
2318
|
+
rb_ary_push(ary, ossl_x509_new(cert));
|
|
2256
2319
|
}
|
|
2257
2320
|
|
|
2258
2321
|
return ary;
|
|
2259
2322
|
}
|
|
2260
2323
|
|
|
2261
2324
|
/*
|
|
2262
|
-
* call-seq:
|
|
2263
|
-
* ssl.ssl_version => String
|
|
2264
|
-
*
|
|
2265
|
-
* Returns a String representing the SSL/TLS version that was negotiated
|
|
2266
|
-
* for the connection, for example "TLSv1.2".
|
|
2267
|
-
*/
|
|
2325
|
+
* call-seq:
|
|
2326
|
+
* ssl.ssl_version => String
|
|
2327
|
+
*
|
|
2328
|
+
* Returns a String representing the SSL/TLS version that was negotiated
|
|
2329
|
+
* for the connection, for example "TLSv1.2".
|
|
2330
|
+
*/
|
|
2268
2331
|
static VALUE
|
|
2269
2332
|
ossl_ssl_get_version(VALUE self)
|
|
2270
2333
|
{
|
|
@@ -2385,10 +2448,10 @@ ossl_ssl_set_hostname(VALUE self, VALUE arg)
|
|
|
2385
2448
|
GetSSL(self, ssl);
|
|
2386
2449
|
|
|
2387
2450
|
if (!NIL_P(arg))
|
|
2388
|
-
|
|
2451
|
+
hostname = StringValueCStr(arg);
|
|
2389
2452
|
|
|
2390
2453
|
if (!SSL_set_tlsext_host_name(ssl, hostname))
|
|
2391
|
-
|
|
2454
|
+
ossl_raise(eSSLError, NULL);
|
|
2392
2455
|
|
|
2393
2456
|
/* for SSLSocket#hostname */
|
|
2394
2457
|
rb_ivar_set(self, id_i_hostname, arg);
|
|
@@ -2467,7 +2530,7 @@ ossl_ssl_get_peer_finished(VALUE self)
|
|
|
2467
2530
|
|
|
2468
2531
|
/*
|
|
2469
2532
|
* call-seq:
|
|
2470
|
-
* ssl.client_ca => [x509name, ...]
|
|
2533
|
+
* ssl.client_ca => [x509name, ...] or nil
|
|
2471
2534
|
*
|
|
2472
2535
|
* Returns the list of client CAs. Please note that in contrast to
|
|
2473
2536
|
* SSLContext#client_ca= no array of X509::Certificate is returned but
|
|
@@ -2485,6 +2548,8 @@ ossl_ssl_get_client_ca_list(VALUE self)
|
|
|
2485
2548
|
GetSSL(self, ssl);
|
|
2486
2549
|
|
|
2487
2550
|
ca = SSL_get_client_CA_list(ssl);
|
|
2551
|
+
if (!ca)
|
|
2552
|
+
return Qnil;
|
|
2488
2553
|
return ossl_x509name_sk2ary(ca);
|
|
2489
2554
|
}
|
|
2490
2555
|
|
|
@@ -2507,9 +2572,9 @@ ossl_ssl_npn_protocol(VALUE self)
|
|
|
2507
2572
|
|
|
2508
2573
|
SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
|
|
2509
2574
|
if (!outlen)
|
|
2510
|
-
|
|
2575
|
+
return Qnil;
|
|
2511
2576
|
else
|
|
2512
|
-
|
|
2577
|
+
return rb_str_new((const char *) out, outlen);
|
|
2513
2578
|
}
|
|
2514
2579
|
# endif
|
|
2515
2580
|
|
|
@@ -2531,9 +2596,9 @@ ossl_ssl_alpn_protocol(VALUE self)
|
|
|
2531
2596
|
|
|
2532
2597
|
SSL_get0_alpn_selected(ssl, &out, &outlen);
|
|
2533
2598
|
if (!outlen)
|
|
2534
|
-
|
|
2599
|
+
return Qnil;
|
|
2535
2600
|
else
|
|
2536
|
-
|
|
2601
|
+
return rb_str_new((const char *) out, outlen);
|
|
2537
2602
|
}
|
|
2538
2603
|
|
|
2539
2604
|
/*
|
|
@@ -2566,15 +2631,15 @@ ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self)
|
|
|
2566
2631
|
str = rb_str_new(0, len);
|
|
2567
2632
|
p = (unsigned char *)RSTRING_PTR(str);
|
|
2568
2633
|
if (!NIL_P(context)) {
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2634
|
+
use_ctx = 1;
|
|
2635
|
+
StringValue(context);
|
|
2636
|
+
ctx = (unsigned char *)RSTRING_PTR(context);
|
|
2637
|
+
ctx_len = RSTRING_LEN(context);
|
|
2573
2638
|
}
|
|
2574
2639
|
ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label),
|
|
2575
|
-
|
|
2640
|
+
RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
|
|
2576
2641
|
if (ret == 0 || ret == -1) {
|
|
2577
|
-
|
|
2642
|
+
ossl_raise(eSSLError, "SSL_export_keying_material");
|
|
2578
2643
|
}
|
|
2579
2644
|
return str;
|
|
2580
2645
|
}
|
|
@@ -2593,17 +2658,77 @@ ossl_ssl_tmp_key(VALUE self)
|
|
|
2593
2658
|
|
|
2594
2659
|
GetSSL(self, ssl);
|
|
2595
2660
|
if (!SSL_get_server_tmp_key(ssl, &key))
|
|
2596
|
-
|
|
2597
|
-
return
|
|
2661
|
+
return Qnil;
|
|
2662
|
+
return ossl_pkey_wrap(key);
|
|
2598
2663
|
}
|
|
2664
|
+
|
|
2665
|
+
#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
|
|
2666
|
+
/*
|
|
2667
|
+
* call-seq:
|
|
2668
|
+
* ssl.sigalg => String or nil
|
|
2669
|
+
*
|
|
2670
|
+
* Returns the signature algorithm name, the IANA name of the signature scheme
|
|
2671
|
+
* used by the local to sign the TLS handshake.
|
|
2672
|
+
*/
|
|
2673
|
+
static VALUE
|
|
2674
|
+
ossl_ssl_get_sigalg(VALUE self)
|
|
2675
|
+
{
|
|
2676
|
+
SSL *ssl;
|
|
2677
|
+
const char *name;
|
|
2678
|
+
|
|
2679
|
+
GetSSL(self, ssl);
|
|
2680
|
+
if (!SSL_get0_signature_name(ssl, &name))
|
|
2681
|
+
return Qnil;
|
|
2682
|
+
return rb_str_new_cstr(name);
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2685
|
+
/*
|
|
2686
|
+
* call-seq:
|
|
2687
|
+
* ssl.peer_sigalg => String or nil
|
|
2688
|
+
*
|
|
2689
|
+
* Returns the signature algorithm name, the IANA name of the signature scheme
|
|
2690
|
+
* used by the peer to sign the TLS handshake.
|
|
2691
|
+
*/
|
|
2692
|
+
static VALUE
|
|
2693
|
+
ossl_ssl_get_peer_sigalg(VALUE self)
|
|
2694
|
+
{
|
|
2695
|
+
SSL *ssl;
|
|
2696
|
+
const char *name;
|
|
2697
|
+
|
|
2698
|
+
GetSSL(self, ssl);
|
|
2699
|
+
if (!SSL_get0_peer_signature_name(ssl, &name))
|
|
2700
|
+
return Qnil;
|
|
2701
|
+
return rb_str_new_cstr(name);
|
|
2702
|
+
}
|
|
2703
|
+
#endif
|
|
2704
|
+
|
|
2705
|
+
#ifdef HAVE_SSL_GET0_GROUP_NAME
|
|
2706
|
+
/*
|
|
2707
|
+
* call-seq:
|
|
2708
|
+
* ssl.group => String or nil
|
|
2709
|
+
*
|
|
2710
|
+
* Returns the name of the group that was used for the key agreement of the
|
|
2711
|
+
* current TLS session establishment.
|
|
2712
|
+
*/
|
|
2713
|
+
static VALUE
|
|
2714
|
+
ossl_ssl_get_group(VALUE self)
|
|
2715
|
+
{
|
|
2716
|
+
SSL *ssl;
|
|
2717
|
+
const char *name;
|
|
2718
|
+
|
|
2719
|
+
GetSSL(self, ssl);
|
|
2720
|
+
if (!(name = SSL_get0_group_name(ssl)))
|
|
2721
|
+
return Qnil;
|
|
2722
|
+
return rb_str_new_cstr(name);
|
|
2723
|
+
}
|
|
2724
|
+
#endif
|
|
2725
|
+
|
|
2599
2726
|
#endif /* !defined(OPENSSL_NO_SOCK) */
|
|
2600
2727
|
|
|
2601
2728
|
void
|
|
2602
2729
|
Init_ossl_ssl(void)
|
|
2603
2730
|
{
|
|
2604
2731
|
#if 0
|
|
2605
|
-
mOSSL = rb_define_module("OpenSSL");
|
|
2606
|
-
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
|
2607
2732
|
rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
|
|
2608
2733
|
rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
|
|
2609
2734
|
#endif
|
|
@@ -2614,10 +2739,10 @@ Init_ossl_ssl(void)
|
|
|
2614
2739
|
|
|
2615
2740
|
ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_ptr_idx", 0, 0, 0);
|
|
2616
2741
|
if (ossl_ssl_ex_ptr_idx < 0)
|
|
2617
|
-
|
|
2742
|
+
ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
|
|
2618
2743
|
ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
|
|
2619
2744
|
if (ossl_sslctx_ex_ptr_idx < 0)
|
|
2620
|
-
|
|
2745
|
+
ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
|
|
2621
2746
|
|
|
2622
2747
|
/* Document-module: OpenSSL::SSL
|
|
2623
2748
|
*
|
|
@@ -2755,6 +2880,23 @@ Init_ossl_ssl(void)
|
|
|
2755
2880
|
*/
|
|
2756
2881
|
rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
|
|
2757
2882
|
|
|
2883
|
+
#ifndef OPENSSL_NO_DH
|
|
2884
|
+
/*
|
|
2885
|
+
* A callback invoked when DH parameters are required for ephemeral DH key
|
|
2886
|
+
* exchange.
|
|
2887
|
+
*
|
|
2888
|
+
* The callback is invoked with the SSLSocket, a
|
|
2889
|
+
* flag indicating the use of an export cipher and the keylength
|
|
2890
|
+
* required.
|
|
2891
|
+
*
|
|
2892
|
+
* The callback must return an OpenSSL::PKey::DH instance of the correct
|
|
2893
|
+
* key length.
|
|
2894
|
+
*
|
|
2895
|
+
* <b>Deprecated in version 3.0.</b> Use #tmp_dh= instead.
|
|
2896
|
+
*/
|
|
2897
|
+
rb_attr(cSSLContext, rb_intern_const("tmp_dh_callback"), 1, 1, Qfalse);
|
|
2898
|
+
#endif
|
|
2899
|
+
|
|
2758
2900
|
/*
|
|
2759
2901
|
* Sets the context in which a session can be reused. This allows
|
|
2760
2902
|
* sessions for multiple applications to be distinguished, for example, by
|
|
@@ -2897,17 +3039,22 @@ Init_ossl_ssl(void)
|
|
|
2897
3039
|
|
|
2898
3040
|
rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
|
|
2899
3041
|
rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
|
|
2900
|
-
|
|
2901
|
-
|
|
3042
|
+
rb_define_method(cSSLContext, "min_version=", ossl_sslctx_set_min_version, 1);
|
|
3043
|
+
rb_define_method(cSSLContext, "max_version=", ossl_sslctx_set_max_version, 1);
|
|
2902
3044
|
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
|
|
2903
3045
|
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
|
|
2904
|
-
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
|
|
2905
3046
|
rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1);
|
|
3047
|
+
#ifdef HAVE_SSL_CTX_SET1_SIGALGS_LIST // Not in LibreSSL yet
|
|
3048
|
+
rb_define_method(cSSLContext, "sigalgs=", ossl_sslctx_set_sigalgs, 1);
|
|
3049
|
+
#endif
|
|
3050
|
+
#ifdef HAVE_SSL_CTX_SET1_CLIENT_SIGALGS_LIST // Not in LibreSSL or AWS-LC yet
|
|
3051
|
+
rb_define_method(cSSLContext, "client_sigalgs=", ossl_sslctx_set_client_sigalgs, 1);
|
|
2906
3052
|
#endif
|
|
2907
3053
|
#ifndef OPENSSL_NO_DH
|
|
2908
3054
|
rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
|
|
2909
3055
|
#endif
|
|
2910
|
-
rb_define_method(cSSLContext, "
|
|
3056
|
+
rb_define_method(cSSLContext, "groups=", ossl_sslctx_set_groups, 1);
|
|
3057
|
+
rb_define_alias(cSSLContext, "ecdh_curves=", "groups=");
|
|
2911
3058
|
rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
|
|
2912
3059
|
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
|
|
2913
3060
|
#ifdef SSL_MODE_SEND_FALLBACK_SCSV
|
|
@@ -3014,6 +3161,13 @@ Init_ossl_ssl(void)
|
|
|
3014
3161
|
# ifdef OSSL_USE_NEXTPROTONEG
|
|
3015
3162
|
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
|
|
3016
3163
|
# endif
|
|
3164
|
+
#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
|
|
3165
|
+
rb_define_method(cSSLSocket, "sigalg", ossl_ssl_get_sigalg, 0);
|
|
3166
|
+
rb_define_method(cSSLSocket, "peer_sigalg", ossl_ssl_get_peer_sigalg, 0);
|
|
3167
|
+
#endif
|
|
3168
|
+
#ifdef HAVE_SSL_GET0_GROUP_NAME
|
|
3169
|
+
rb_define_method(cSSLSocket, "group", ossl_ssl_get_group, 0);
|
|
3170
|
+
#endif
|
|
3017
3171
|
|
|
3018
3172
|
rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
|
|
3019
3173
|
rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
|
|
@@ -3039,7 +3193,7 @@ Init_ossl_ssl(void)
|
|
|
3039
3193
|
#ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */
|
|
3040
3194
|
rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES));
|
|
3041
3195
|
#endif
|
|
3042
|
-
#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
|
|
3196
|
+
#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1, missing in LibreSSL */
|
|
3043
3197
|
rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
|
|
3044
3198
|
#endif
|
|
3045
3199
|
rb_define_const(mSSL, "OP_DONT_INSERT_EMPTY_FRAGMENTS", ULONG2NUM(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
|
|
@@ -3047,28 +3201,26 @@ Init_ossl_ssl(void)
|
|
|
3047
3201
|
rb_define_const(mSSL, "OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION));
|
|
3048
3202
|
rb_define_const(mSSL, "OP_NO_COMPRESSION", ULONG2NUM(SSL_OP_NO_COMPRESSION));
|
|
3049
3203
|
rb_define_const(mSSL, "OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
|
|
3050
|
-
#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
|
|
3204
|
+
#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1, missing in LibreSSL */
|
|
3051
3205
|
rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
|
|
3052
3206
|
#endif
|
|
3053
|
-
#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */
|
|
3207
|
+
#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1, missing in LibreSSL */
|
|
3054
3208
|
rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT));
|
|
3055
3209
|
#endif
|
|
3056
|
-
#ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */
|
|
3210
|
+
#ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1, missing in LibreSSL */
|
|
3057
3211
|
rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA));
|
|
3058
3212
|
#endif
|
|
3059
|
-
#ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */
|
|
3213
|
+
#ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1, missing in LibreSSL */
|
|
3060
3214
|
rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY));
|
|
3061
3215
|
#endif
|
|
3062
3216
|
rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
|
|
3063
3217
|
rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
|
|
3064
3218
|
rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
|
|
3065
3219
|
rb_define_const(mSSL, "OP_NO_TLSv1_2", ULONG2NUM(SSL_OP_NO_TLSv1_2));
|
|
3066
|
-
#ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
|
|
3067
3220
|
rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
|
|
3068
|
-
#endif
|
|
3069
3221
|
rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
|
|
3070
3222
|
rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
|
|
3071
|
-
#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
|
|
3223
|
+
#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1, missing in LibreSSL */
|
|
3072
3224
|
rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
|
|
3073
3225
|
#endif
|
|
3074
3226
|
rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
|
|
@@ -3130,17 +3282,14 @@ Init_ossl_ssl(void)
|
|
|
3130
3282
|
rb_define_const(mSSL, "TLS1_1_VERSION", INT2NUM(TLS1_1_VERSION));
|
|
3131
3283
|
/* TLS 1.2 */
|
|
3132
3284
|
rb_define_const(mSSL, "TLS1_2_VERSION", INT2NUM(TLS1_2_VERSION));
|
|
3133
|
-
#ifdef TLS1_3_VERSION /* OpenSSL 1.1.1 */
|
|
3134
3285
|
/* TLS 1.3 */
|
|
3135
3286
|
rb_define_const(mSSL, "TLS1_3_VERSION", INT2NUM(TLS1_3_VERSION));
|
|
3136
|
-
#endif
|
|
3137
3287
|
|
|
3138
3288
|
|
|
3139
3289
|
sym_exception = ID2SYM(rb_intern_const("exception"));
|
|
3140
3290
|
sym_wait_readable = ID2SYM(rb_intern_const("wait_readable"));
|
|
3141
3291
|
sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
|
|
3142
3292
|
|
|
3143
|
-
id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
|
|
3144
3293
|
id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
|
|
3145
3294
|
id_each = rb_intern_const("each");
|
|
3146
3295
|
|
|
@@ -3171,9 +3320,11 @@ Init_ossl_ssl(void)
|
|
|
3171
3320
|
DefIVarID(servername_cb);
|
|
3172
3321
|
DefIVarID(verify_hostname);
|
|
3173
3322
|
DefIVarID(keylog_cb);
|
|
3323
|
+
DefIVarID(tmp_dh_callback);
|
|
3174
3324
|
|
|
3175
3325
|
DefIVarID(io);
|
|
3176
3326
|
DefIVarID(context);
|
|
3177
3327
|
DefIVarID(hostname);
|
|
3328
|
+
DefIVarID(sync_close);
|
|
3178
3329
|
#endif /* !defined(OPENSSL_NO_SOCK) */
|
|
3179
3330
|
}
|