zig_example 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/ext/mkmf.rb +2734 -0
  3. data/ext/openssl/openssl_missing.c +40 -0
  4. data/ext/openssl/openssl_missing.h +238 -0
  5. data/ext/openssl/ossl.c +1295 -0
  6. data/ext/openssl/ossl.h +201 -0
  7. data/ext/openssl/ossl_asn1.c +1891 -0
  8. data/ext/openssl/ossl_asn1.h +62 -0
  9. data/ext/openssl/ossl_bio.c +42 -0
  10. data/ext/openssl/ossl_bio.h +16 -0
  11. data/ext/openssl/ossl_bn.c +1344 -0
  12. data/ext/openssl/ossl_bn.h +26 -0
  13. data/ext/openssl/ossl_cipher.c +1074 -0
  14. data/ext/openssl/ossl_cipher.h +20 -0
  15. data/ext/openssl/ossl_config.c +460 -0
  16. data/ext/openssl/ossl_config.h +16 -0
  17. data/ext/openssl/ossl_digest.c +425 -0
  18. data/ext/openssl/ossl_digest.h +20 -0
  19. data/ext/openssl/ossl_engine.c +568 -0
  20. data/ext/openssl/ossl_engine.h +19 -0
  21. data/ext/openssl/ossl_hmac.c +310 -0
  22. data/ext/openssl/ossl_hmac.h +18 -0
  23. data/ext/openssl/ossl_kdf.c +311 -0
  24. data/ext/openssl/ossl_kdf.h +6 -0
  25. data/ext/openssl/ossl_ns_spki.c +405 -0
  26. data/ext/openssl/ossl_ns_spki.h +19 -0
  27. data/ext/openssl/ossl_ocsp.c +1965 -0
  28. data/ext/openssl/ossl_ocsp.h +23 -0
  29. data/ext/openssl/ossl_pkcs12.c +275 -0
  30. data/ext/openssl/ossl_pkcs12.h +13 -0
  31. data/ext/openssl/ossl_pkcs7.c +1081 -0
  32. data/ext/openssl/ossl_pkcs7.h +36 -0
  33. data/ext/openssl/ossl_pkey.c +1624 -0
  34. data/ext/openssl/ossl_pkey.h +204 -0
  35. data/ext/openssl/ossl_pkey_dh.c +440 -0
  36. data/ext/openssl/ossl_pkey_dsa.c +359 -0
  37. data/ext/openssl/ossl_pkey_ec.c +1655 -0
  38. data/ext/openssl/ossl_pkey_rsa.c +579 -0
  39. data/ext/openssl/ossl_rand.c +200 -0
  40. data/ext/openssl/ossl_rand.h +18 -0
  41. data/ext/openssl/ossl_ssl.c +3142 -0
  42. data/ext/openssl/ossl_ssl.h +36 -0
  43. data/ext/openssl/ossl_ssl_session.c +331 -0
  44. data/ext/openssl/ossl_ts.c +1539 -0
  45. data/ext/openssl/ossl_ts.h +16 -0
  46. data/ext/openssl/ossl_x509.c +256 -0
  47. data/ext/openssl/ossl_x509.h +115 -0
  48. data/ext/openssl/ossl_x509attr.c +324 -0
  49. data/ext/openssl/ossl_x509cert.c +1002 -0
  50. data/ext/openssl/ossl_x509crl.c +545 -0
  51. data/ext/openssl/ossl_x509ext.c +490 -0
  52. data/ext/openssl/ossl_x509name.c +597 -0
  53. data/ext/openssl/ossl_x509req.c +444 -0
  54. data/ext/openssl/ossl_x509revoked.c +300 -0
  55. data/ext/openssl/ossl_x509store.c +986 -0
  56. data/ext/zigrb_100doors/build.zig +0 -12
  57. data/ext/zigrb_100doors/extconf.rb +2 -19
  58. data/ext/zigrb_ackermann/build.zig +0 -12
  59. data/ext/zigrb_ackermann/extconf.rb +2 -19
  60. data/ext/zigrb_lucas_lehmer/build.zig +0 -12
  61. data/ext/zigrb_lucas_lehmer/extconf.rb +2 -19
  62. data/lib/zig_example/version.rb +1 -1
  63. metadata +56 -2
@@ -0,0 +1,3142 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' project
3
+ * Copyright (C) 2000-2002 GOTOU Yuuzou <gotoyuzo@notwork.org>
4
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
+ * Copyright (C) 2001-2007 Technorama Ltd. <oss-ruby@technorama.net>
6
+ * All rights reserved.
7
+ */
8
+ /*
9
+ * This program is licensed under the same licence as Ruby.
10
+ * (See the file 'LICENCE'.)
11
+ */
12
+ #include "ossl.h"
13
+
14
+ #ifndef OPENSSL_NO_SOCK
15
+ #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
16
+
17
+ #if !defined(OPENSSL_NO_NEXTPROTONEG) && !OSSL_IS_LIBRESSL
18
+ # define OSSL_USE_NEXTPROTONEG
19
+ #endif
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
+ #ifdef _WIN32
27
+ # define TO_SOCKET(s) _get_osfhandle(s)
28
+ #else
29
+ # define TO_SOCKET(s) (s)
30
+ #endif
31
+
32
+ #define GetSSLCTX(obj, ctx) do { \
33
+ TypedData_Get_Struct((obj), SSL_CTX, &ossl_sslctx_type, (ctx)); \
34
+ } while (0)
35
+
36
+ VALUE mSSL;
37
+ static VALUE eSSLError;
38
+ VALUE cSSLContext;
39
+ VALUE cSSLSocket;
40
+
41
+ static VALUE eSSLErrorWaitReadable;
42
+ static VALUE eSSLErrorWaitWritable;
43
+
44
+ static ID id_call, ID_callback_state, id_tmp_dh_callback,
45
+ id_npn_protocols_encoded, id_each;
46
+ static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
47
+
48
+ static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
49
+ id_i_verify_depth, id_i_verify_callback, id_i_client_ca,
50
+ id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert,
51
+ id_i_client_cert_cb, id_i_timeout,
52
+ id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb,
53
+ id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
54
+ id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
55
+ id_i_verify_hostname, id_i_keylog_cb;
56
+ static ID id_i_io, id_i_context, id_i_hostname;
57
+
58
+ static int ossl_ssl_ex_vcb_idx;
59
+ static int ossl_ssl_ex_ptr_idx;
60
+ static int ossl_sslctx_ex_ptr_idx;
61
+
62
+ static void
63
+ ossl_sslctx_mark(void *ptr)
64
+ {
65
+ SSL_CTX *ctx = ptr;
66
+ rb_gc_mark((VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx));
67
+ }
68
+
69
+ static void
70
+ ossl_sslctx_free(void *ptr)
71
+ {
72
+ SSL_CTX_free(ptr);
73
+ }
74
+
75
+ static const rb_data_type_t ossl_sslctx_type = {
76
+ "OpenSSL/SSL/CTX",
77
+ {
78
+ ossl_sslctx_mark, ossl_sslctx_free,
79
+ },
80
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
81
+ };
82
+
83
+ static VALUE
84
+ ossl_sslctx_s_alloc(VALUE klass)
85
+ {
86
+ SSL_CTX *ctx;
87
+ long mode = 0 |
88
+ SSL_MODE_ENABLE_PARTIAL_WRITE |
89
+ SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
90
+ SSL_MODE_RELEASE_BUFFERS;
91
+ VALUE obj;
92
+
93
+ obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
94
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
95
+ ctx = SSL_CTX_new(TLS_method());
96
+ #else
97
+ ctx = SSL_CTX_new(SSLv23_method());
98
+ #endif
99
+ if (!ctx) {
100
+ ossl_raise(eSSLError, "SSL_CTX_new");
101
+ }
102
+ SSL_CTX_set_mode(ctx, mode);
103
+ RTYPEDDATA_DATA(obj) = ctx;
104
+ SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj);
105
+
106
+ #if !defined(OPENSSL_NO_EC) && OPENSSL_VERSION_NUMBER < 0x10100000 && \
107
+ !defined(LIBRESSL_VERSION_NUMBER)
108
+ /* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
109
+ * allows to specify multiple curve names and OpenSSL will select
110
+ * automatically from them. In OpenSSL 1.0.2, the automatic selection has to
111
+ * be enabled explicitly. OpenSSL 1.1.0 and LibreSSL 2.6.1 removed the knob
112
+ * and it is always enabled. To uniform the behavior, we enable the
113
+ * automatic selection also in 1.0.2. Users can still disable ECDH by
114
+ * removing ECDH cipher suites by SSLContext#ciphers=. */
115
+ if (!SSL_CTX_set_ecdh_auto(ctx, 1))
116
+ ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
117
+ #endif
118
+
119
+ return obj;
120
+ }
121
+
122
+ static int
123
+ parse_proto_version(VALUE str)
124
+ {
125
+ int i;
126
+ static const struct {
127
+ const char *name;
128
+ int version;
129
+ } map[] = {
130
+ { "SSL2", SSL2_VERSION },
131
+ { "SSL3", SSL3_VERSION },
132
+ { "TLS1", TLS1_VERSION },
133
+ { "TLS1_1", TLS1_1_VERSION },
134
+ { "TLS1_2", TLS1_2_VERSION },
135
+ #ifdef TLS1_3_VERSION
136
+ { "TLS1_3", TLS1_3_VERSION },
137
+ #endif
138
+ };
139
+
140
+ if (NIL_P(str))
141
+ return 0;
142
+ if (RB_INTEGER_TYPE_P(str))
143
+ return NUM2INT(str);
144
+
145
+ if (SYMBOL_P(str))
146
+ str = rb_sym2str(str);
147
+ StringValue(str);
148
+ for (i = 0; i < numberof(map); i++)
149
+ if (!strncmp(map[i].name, RSTRING_PTR(str), RSTRING_LEN(str)))
150
+ return map[i].version;
151
+ rb_raise(rb_eArgError, "unrecognized version %+"PRIsVALUE, str);
152
+ }
153
+
154
+ /*
155
+ * call-seq:
156
+ * ctx.set_minmax_proto_version(min, max) -> nil
157
+ *
158
+ * Sets the minimum and maximum supported protocol versions. See #min_version=
159
+ * and #max_version=.
160
+ */
161
+ static VALUE
162
+ ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
163
+ {
164
+ SSL_CTX *ctx;
165
+ int min, max;
166
+
167
+ GetSSLCTX(self, ctx);
168
+ min = parse_proto_version(min_v);
169
+ max = parse_proto_version(max_v);
170
+
171
+ #ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
172
+ if (!SSL_CTX_set_min_proto_version(ctx, min))
173
+ ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
174
+ if (!SSL_CTX_set_max_proto_version(ctx, max))
175
+ ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
176
+ #else
177
+ {
178
+ unsigned long sum = 0, opts = 0;
179
+ int i;
180
+ static const struct {
181
+ int ver;
182
+ unsigned long opts;
183
+ } options_map[] = {
184
+ { SSL2_VERSION, SSL_OP_NO_SSLv2 },
185
+ { SSL3_VERSION, SSL_OP_NO_SSLv3 },
186
+ { TLS1_VERSION, SSL_OP_NO_TLSv1 },
187
+ { TLS1_1_VERSION, SSL_OP_NO_TLSv1_1 },
188
+ { TLS1_2_VERSION, SSL_OP_NO_TLSv1_2 },
189
+ # if defined(TLS1_3_VERSION)
190
+ { TLS1_3_VERSION, SSL_OP_NO_TLSv1_3 },
191
+ # endif
192
+ };
193
+
194
+ for (i = 0; i < numberof(options_map); i++) {
195
+ sum |= options_map[i].opts;
196
+ if ((min && min > options_map[i].ver) ||
197
+ (max && max < options_map[i].ver)) {
198
+ opts |= options_map[i].opts;
199
+ }
200
+ }
201
+ SSL_CTX_clear_options(ctx, sum);
202
+ SSL_CTX_set_options(ctx, opts);
203
+ }
204
+ #endif
205
+
206
+ return Qnil;
207
+ }
208
+
209
+ static VALUE
210
+ ossl_call_client_cert_cb(VALUE obj)
211
+ {
212
+ VALUE ctx_obj, cb, ary, cert, key;
213
+
214
+ ctx_obj = rb_attr_get(obj, id_i_context);
215
+ cb = rb_attr_get(ctx_obj, id_i_client_cert_cb);
216
+ if (NIL_P(cb))
217
+ return Qnil;
218
+
219
+ ary = rb_funcallv(cb, id_call, 1, &obj);
220
+ Check_Type(ary, T_ARRAY);
221
+ GetX509CertPtr(cert = rb_ary_entry(ary, 0));
222
+ GetPrivPKeyPtr(key = rb_ary_entry(ary, 1));
223
+
224
+ return rb_ary_new3(2, cert, key);
225
+ }
226
+
227
+ static int
228
+ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
229
+ {
230
+ VALUE obj, ret;
231
+
232
+ obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
233
+ ret = rb_protect(ossl_call_client_cert_cb, obj, NULL);
234
+ if (NIL_P(ret))
235
+ return 0;
236
+
237
+ *x509 = DupX509CertPtr(RARRAY_AREF(ret, 0));
238
+ *pkey = DupPKeyPtr(RARRAY_AREF(ret, 1));
239
+
240
+ return 1;
241
+ }
242
+
243
+ #if !defined(OPENSSL_NO_DH)
244
+ struct tmp_dh_callback_args {
245
+ VALUE ssl_obj;
246
+ ID id;
247
+ int type;
248
+ int is_export;
249
+ int keylength;
250
+ };
251
+
252
+ static VALUE
253
+ ossl_call_tmp_dh_callback(VALUE arg)
254
+ {
255
+ struct tmp_dh_callback_args *args = (struct tmp_dh_callback_args *)arg;
256
+ VALUE cb, dh;
257
+ EVP_PKEY *pkey;
258
+
259
+ cb = rb_funcall(args->ssl_obj, args->id, 0);
260
+ if (NIL_P(cb))
261
+ return (VALUE)NULL;
262
+ dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export),
263
+ INT2NUM(args->keylength));
264
+ pkey = GetPKeyPtr(dh);
265
+ if (EVP_PKEY_base_id(pkey) != args->type)
266
+ return (VALUE)NULL;
267
+
268
+ return (VALUE)pkey;
269
+ }
270
+ #endif
271
+
272
+ #if !defined(OPENSSL_NO_DH)
273
+ static DH *
274
+ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
275
+ {
276
+ VALUE rb_ssl;
277
+ EVP_PKEY *pkey;
278
+ struct tmp_dh_callback_args args;
279
+ int state;
280
+
281
+ rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
282
+ args.ssl_obj = rb_ssl;
283
+ args.id = id_tmp_dh_callback;
284
+ args.is_export = is_export;
285
+ args.keylength = keylength;
286
+ args.type = EVP_PKEY_DH;
287
+
288
+ pkey = (EVP_PKEY *)rb_protect(ossl_call_tmp_dh_callback,
289
+ (VALUE)&args, &state);
290
+ if (state) {
291
+ rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state));
292
+ return NULL;
293
+ }
294
+ if (!pkey)
295
+ return NULL;
296
+
297
+ return (DH *)EVP_PKEY_get0_DH(pkey);
298
+ }
299
+ #endif /* OPENSSL_NO_DH */
300
+
301
+ static VALUE
302
+ call_verify_certificate_identity(VALUE ctx_v)
303
+ {
304
+ X509_STORE_CTX *ctx = (X509_STORE_CTX *)ctx_v;
305
+ SSL *ssl;
306
+ VALUE ssl_obj, hostname, cert_obj;
307
+
308
+ ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
309
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
310
+ hostname = rb_attr_get(ssl_obj, id_i_hostname);
311
+
312
+ if (!RTEST(hostname)) {
313
+ rb_warning("verify_hostname requires hostname to be set");
314
+ return Qtrue;
315
+ }
316
+
317
+ cert_obj = ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx));
318
+ return rb_funcall(mSSL, rb_intern("verify_certificate_identity"), 2,
319
+ cert_obj, hostname);
320
+ }
321
+
322
+ static int
323
+ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
324
+ {
325
+ VALUE cb, ssl_obj, sslctx_obj, verify_hostname, ret;
326
+ SSL *ssl;
327
+ int status;
328
+
329
+ ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
330
+ cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx);
331
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
332
+ sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
333
+ verify_hostname = rb_attr_get(sslctx_obj, id_i_verify_hostname);
334
+
335
+ if (preverify_ok && RTEST(verify_hostname) && !SSL_is_server(ssl) &&
336
+ !X509_STORE_CTX_get_error_depth(ctx)) {
337
+ ret = rb_protect(call_verify_certificate_identity, (VALUE)ctx, &status);
338
+ if (status) {
339
+ rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
340
+ return 0;
341
+ }
342
+ if (ret != Qtrue) {
343
+ preverify_ok = 0;
344
+ #if defined(X509_V_ERR_HOSTNAME_MISMATCH)
345
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
346
+ #else
347
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
348
+ #endif
349
+ }
350
+ }
351
+
352
+ return ossl_verify_cb_call(cb, preverify_ok, ctx);
353
+ }
354
+
355
+ static VALUE
356
+ ossl_call_session_get_cb(VALUE ary)
357
+ {
358
+ VALUE ssl_obj, cb;
359
+
360
+ Check_Type(ary, T_ARRAY);
361
+ ssl_obj = rb_ary_entry(ary, 0);
362
+
363
+ cb = rb_funcall(ssl_obj, rb_intern("session_get_cb"), 0);
364
+ if (NIL_P(cb)) return Qnil;
365
+
366
+ return rb_funcallv(cb, id_call, 1, &ary);
367
+ }
368
+
369
+ static SSL_SESSION *
370
+ #if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
371
+ ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
372
+ #else
373
+ ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
374
+ #endif
375
+ {
376
+ VALUE ary, ssl_obj, ret_obj;
377
+ SSL_SESSION *sess;
378
+ int state = 0;
379
+
380
+ OSSL_Debug("SSL SESSION get callback entered");
381
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
382
+ ary = rb_ary_new2(2);
383
+ rb_ary_push(ary, ssl_obj);
384
+ rb_ary_push(ary, rb_str_new((const char *)buf, len));
385
+
386
+ ret_obj = rb_protect(ossl_call_session_get_cb, ary, &state);
387
+ if (state) {
388
+ rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
389
+ return NULL;
390
+ }
391
+ if (!rb_obj_is_instance_of(ret_obj, cSSLSession))
392
+ return NULL;
393
+
394
+ GetSSLSession(ret_obj, sess);
395
+ *copy = 1;
396
+
397
+ return sess;
398
+ }
399
+
400
+ static VALUE
401
+ ossl_call_session_new_cb(VALUE ary)
402
+ {
403
+ VALUE ssl_obj, cb;
404
+
405
+ Check_Type(ary, T_ARRAY);
406
+ ssl_obj = rb_ary_entry(ary, 0);
407
+
408
+ cb = rb_funcall(ssl_obj, rb_intern("session_new_cb"), 0);
409
+ if (NIL_P(cb)) return Qnil;
410
+
411
+ return rb_funcallv(cb, id_call, 1, &ary);
412
+ }
413
+
414
+ /* return 1 normal. return 0 removes the session */
415
+ static int
416
+ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
417
+ {
418
+ VALUE ary, ssl_obj, sess_obj;
419
+ int state = 0;
420
+
421
+ OSSL_Debug("SSL SESSION new callback entered");
422
+
423
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
424
+ sess_obj = rb_obj_alloc(cSSLSession);
425
+ SSL_SESSION_up_ref(sess);
426
+ DATA_PTR(sess_obj) = sess;
427
+
428
+ ary = rb_ary_new2(2);
429
+ rb_ary_push(ary, ssl_obj);
430
+ rb_ary_push(ary, sess_obj);
431
+
432
+ rb_protect(ossl_call_session_new_cb, ary, &state);
433
+ if (state) {
434
+ rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
435
+ }
436
+
437
+ /*
438
+ * return 0 which means to OpenSSL that the session is still
439
+ * valid (since we created Ruby Session object) and was not freed by us
440
+ * with SSL_SESSION_free(). Call SSLContext#remove_session(sess) in
441
+ * session_get_cb block if you don't want OpenSSL to cache the session
442
+ * internally.
443
+ */
444
+ return 0;
445
+ }
446
+
447
+ #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
448
+ /*
449
+ * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
450
+ * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
451
+ * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
452
+ */
453
+
454
+ struct ossl_call_keylog_cb_args {
455
+ VALUE ssl_obj;
456
+ const char * line;
457
+ };
458
+
459
+ static VALUE
460
+ ossl_call_keylog_cb(VALUE args_v)
461
+ {
462
+ VALUE sslctx_obj, cb, line_v;
463
+ struct ossl_call_keylog_cb_args *args = (struct ossl_call_keylog_cb_args *) args_v;
464
+
465
+ sslctx_obj = rb_attr_get(args->ssl_obj, id_i_context);
466
+
467
+ cb = rb_attr_get(sslctx_obj, id_i_keylog_cb);
468
+ if (NIL_P(cb)) return Qnil;
469
+
470
+ line_v = rb_str_new_cstr(args->line);
471
+
472
+ return rb_funcall(cb, id_call, 2, args->ssl_obj, line_v);
473
+ }
474
+
475
+ static void
476
+ ossl_sslctx_keylog_cb(const SSL *ssl, const char *line)
477
+ {
478
+ VALUE ssl_obj;
479
+ struct ossl_call_keylog_cb_args args;
480
+ int state = 0;
481
+
482
+ OSSL_Debug("SSL keylog callback entered");
483
+
484
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
485
+ args.ssl_obj = ssl_obj;
486
+ args.line = line;
487
+
488
+ rb_protect(ossl_call_keylog_cb, (VALUE)&args, &state);
489
+ if (state) {
490
+ rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
491
+ }
492
+ }
493
+ #endif
494
+
495
+ static VALUE
496
+ ossl_call_session_remove_cb(VALUE ary)
497
+ {
498
+ VALUE sslctx_obj, cb;
499
+
500
+ Check_Type(ary, T_ARRAY);
501
+ sslctx_obj = rb_ary_entry(ary, 0);
502
+
503
+ cb = rb_attr_get(sslctx_obj, id_i_session_remove_cb);
504
+ if (NIL_P(cb)) return Qnil;
505
+
506
+ return rb_funcallv(cb, id_call, 1, &ary);
507
+ }
508
+
509
+ static void
510
+ ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
511
+ {
512
+ VALUE ary, sslctx_obj, sess_obj;
513
+ int state = 0;
514
+
515
+ /*
516
+ * This callback is also called for all sessions in the internal store
517
+ * when SSL_CTX_free() is called.
518
+ */
519
+ if (rb_during_gc())
520
+ return;
521
+
522
+ OSSL_Debug("SSL SESSION remove callback entered");
523
+
524
+ sslctx_obj = (VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx);
525
+ sess_obj = rb_obj_alloc(cSSLSession);
526
+ SSL_SESSION_up_ref(sess);
527
+ DATA_PTR(sess_obj) = sess;
528
+
529
+ ary = rb_ary_new2(2);
530
+ rb_ary_push(ary, sslctx_obj);
531
+ rb_ary_push(ary, sess_obj);
532
+
533
+ rb_protect(ossl_call_session_remove_cb, ary, &state);
534
+ if (state) {
535
+ /*
536
+ the SSL_CTX is frozen, nowhere to save state.
537
+ there is no common accessor method to check it either.
538
+ rb_ivar_set(sslctx_obj, ID_callback_state, INT2NUM(state));
539
+ */
540
+ }
541
+ }
542
+
543
+ static VALUE
544
+ ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
545
+ {
546
+ X509 *x509;
547
+ SSL_CTX *ctx;
548
+
549
+ GetSSLCTX(arg, ctx);
550
+ x509 = DupX509CertPtr(i);
551
+ if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){
552
+ ossl_raise(eSSLError, NULL);
553
+ }
554
+
555
+ return i;
556
+ }
557
+
558
+ static VALUE ossl_sslctx_setup(VALUE self);
559
+
560
+ static VALUE
561
+ ossl_call_servername_cb(VALUE ary)
562
+ {
563
+ VALUE ssl_obj, sslctx_obj, cb, ret_obj;
564
+
565
+ Check_Type(ary, T_ARRAY);
566
+ ssl_obj = rb_ary_entry(ary, 0);
567
+
568
+ sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
569
+ cb = rb_attr_get(sslctx_obj, id_i_servername_cb);
570
+ if (NIL_P(cb)) return Qnil;
571
+
572
+ ret_obj = rb_funcallv(cb, id_call, 1, &ary);
573
+ if (rb_obj_is_kind_of(ret_obj, cSSLContext)) {
574
+ SSL *ssl;
575
+ SSL_CTX *ctx2;
576
+
577
+ ossl_sslctx_setup(ret_obj);
578
+ GetSSL(ssl_obj, ssl);
579
+ GetSSLCTX(ret_obj, ctx2);
580
+ SSL_set_SSL_CTX(ssl, ctx2);
581
+ rb_ivar_set(ssl_obj, id_i_context, ret_obj);
582
+ } else if (!NIL_P(ret_obj)) {
583
+ ossl_raise(rb_eArgError, "servername_cb must return an "
584
+ "OpenSSL::SSL::SSLContext object or nil");
585
+ }
586
+
587
+ return ret_obj;
588
+ }
589
+
590
+ static int
591
+ ssl_servername_cb(SSL *ssl, int *ad, void *arg)
592
+ {
593
+ VALUE ary, ssl_obj;
594
+ int state = 0;
595
+ const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
596
+
597
+ if (!servername)
598
+ return SSL_TLSEXT_ERR_OK;
599
+
600
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
601
+ ary = rb_ary_new2(2);
602
+ rb_ary_push(ary, ssl_obj);
603
+ rb_ary_push(ary, rb_str_new2(servername));
604
+
605
+ rb_protect(ossl_call_servername_cb, ary, &state);
606
+ if (state) {
607
+ rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
608
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
609
+ }
610
+
611
+ return SSL_TLSEXT_ERR_OK;
612
+ }
613
+
614
+ static void
615
+ ssl_renegotiation_cb(const SSL *ssl)
616
+ {
617
+ VALUE ssl_obj, sslctx_obj, cb;
618
+
619
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
620
+ sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
621
+ cb = rb_attr_get(sslctx_obj, id_i_renegotiation_cb);
622
+ if (NIL_P(cb)) return;
623
+
624
+ rb_funcallv(cb, id_call, 1, &ssl_obj);
625
+ }
626
+
627
+ static VALUE
628
+ ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
629
+ {
630
+ int len = RSTRING_LENINT(cur);
631
+ char len_byte;
632
+ if (len < 1 || len > 255)
633
+ ossl_raise(eSSLError, "Advertised protocol must have length 1..255");
634
+ /* Encode the length byte */
635
+ len_byte = len;
636
+ rb_str_buf_cat(encoded, &len_byte, 1);
637
+ rb_str_buf_cat(encoded, RSTRING_PTR(cur), len);
638
+ return Qnil;
639
+ }
640
+
641
+ static VALUE
642
+ ssl_encode_npn_protocols(VALUE protocols)
643
+ {
644
+ VALUE encoded = rb_str_new(NULL, 0);
645
+ rb_block_call(protocols, id_each, 0, 0, ssl_npn_encode_protocol_i, encoded);
646
+ return encoded;
647
+ }
648
+
649
+ struct npn_select_cb_common_args {
650
+ VALUE cb;
651
+ const unsigned char *in;
652
+ unsigned inlen;
653
+ };
654
+
655
+ static VALUE
656
+ npn_select_cb_common_i(VALUE tmp)
657
+ {
658
+ struct npn_select_cb_common_args *args = (void *)tmp;
659
+ const unsigned char *in = args->in, *in_end = in + args->inlen;
660
+ unsigned char l;
661
+ long len;
662
+ VALUE selected, protocols = rb_ary_new();
663
+
664
+ /* assume OpenSSL verifies this format */
665
+ /* The format is len_1|proto_1|...|len_n|proto_n */
666
+ while (in < in_end) {
667
+ l = *in++;
668
+ rb_ary_push(protocols, rb_str_new((const char *)in, l));
669
+ in += l;
670
+ }
671
+
672
+ selected = rb_funcallv(args->cb, id_call, 1, &protocols);
673
+ StringValue(selected);
674
+ len = RSTRING_LEN(selected);
675
+ if (len < 1 || len >= 256) {
676
+ ossl_raise(eSSLError, "Selected protocol name must have length 1..255");
677
+ }
678
+
679
+ return selected;
680
+ }
681
+
682
+ static int
683
+ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
684
+ unsigned char *outlen, const unsigned char *in,
685
+ unsigned int inlen)
686
+ {
687
+ VALUE selected;
688
+ int status;
689
+ struct npn_select_cb_common_args args;
690
+
691
+ args.cb = cb;
692
+ args.in = in;
693
+ args.inlen = inlen;
694
+
695
+ selected = rb_protect(npn_select_cb_common_i, (VALUE)&args, &status);
696
+ if (status) {
697
+ VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
698
+
699
+ rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
700
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
701
+ }
702
+
703
+ *out = (unsigned char *)RSTRING_PTR(selected);
704
+ *outlen = (unsigned char)RSTRING_LEN(selected);
705
+
706
+ return SSL_TLSEXT_ERR_OK;
707
+ }
708
+
709
+ #ifdef OSSL_USE_NEXTPROTONEG
710
+ static int
711
+ ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
712
+ void *arg)
713
+ {
714
+ VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded);
715
+
716
+ *out = (const unsigned char *) RSTRING_PTR(protocols);
717
+ *outlen = RSTRING_LENINT(protocols);
718
+
719
+ return SSL_TLSEXT_ERR_OK;
720
+ }
721
+
722
+ static int
723
+ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
724
+ const unsigned char *in, unsigned int inlen, void *arg)
725
+ {
726
+ VALUE sslctx_obj, cb;
727
+
728
+ sslctx_obj = (VALUE) arg;
729
+ cb = rb_attr_get(sslctx_obj, id_i_npn_select_cb);
730
+
731
+ return ssl_npn_select_cb_common(ssl, cb, (const unsigned char **)out,
732
+ outlen, in, inlen);
733
+ }
734
+ #endif
735
+
736
+ static int
737
+ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
738
+ const unsigned char *in, unsigned int inlen, void *arg)
739
+ {
740
+ VALUE sslctx_obj, cb;
741
+
742
+ sslctx_obj = (VALUE) arg;
743
+ cb = rb_attr_get(sslctx_obj, id_i_alpn_select_cb);
744
+
745
+ return ssl_npn_select_cb_common(ssl, cb, out, outlen, in, inlen);
746
+ }
747
+
748
+ /* This function may serve as the entry point to support further callbacks. */
749
+ static void
750
+ ssl_info_cb(const SSL *ssl, int where, int val)
751
+ {
752
+ int is_server = SSL_is_server((SSL *)ssl);
753
+
754
+ if (is_server && where & SSL_CB_HANDSHAKE_START) {
755
+ ssl_renegotiation_cb(ssl);
756
+ }
757
+ }
758
+
759
+ /*
760
+ * Gets various OpenSSL options.
761
+ */
762
+ static VALUE
763
+ ossl_sslctx_get_options(VALUE self)
764
+ {
765
+ SSL_CTX *ctx;
766
+ GetSSLCTX(self, ctx);
767
+ /*
768
+ * Do explicit cast because SSL_CTX_get_options() returned (signed) long in
769
+ * OpenSSL before 1.1.0.
770
+ */
771
+ return ULONG2NUM((unsigned long)SSL_CTX_get_options(ctx));
772
+ }
773
+
774
+ /*
775
+ * Sets various OpenSSL options.
776
+ */
777
+ static VALUE
778
+ ossl_sslctx_set_options(VALUE self, VALUE options)
779
+ {
780
+ SSL_CTX *ctx;
781
+
782
+ rb_check_frozen(self);
783
+ GetSSLCTX(self, ctx);
784
+
785
+ SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx));
786
+
787
+ if (NIL_P(options)) {
788
+ SSL_CTX_set_options(ctx, SSL_OP_ALL);
789
+ } else {
790
+ SSL_CTX_set_options(ctx, NUM2ULONG(options));
791
+ }
792
+
793
+ return self;
794
+ }
795
+
796
+ /*
797
+ * call-seq:
798
+ * ctx.setup => Qtrue # first time
799
+ * ctx.setup => nil # thereafter
800
+ *
801
+ * This method is called automatically when a new SSLSocket is created.
802
+ * However, it is not thread-safe and must be called before creating
803
+ * SSLSocket objects in a multi-threaded program.
804
+ */
805
+ static VALUE
806
+ ossl_sslctx_setup(VALUE self)
807
+ {
808
+ SSL_CTX *ctx;
809
+ X509 *cert = NULL, *client_ca = NULL;
810
+ EVP_PKEY *key = NULL;
811
+ char *ca_path = NULL, *ca_file = NULL;
812
+ int verify_mode;
813
+ long i;
814
+ VALUE val;
815
+
816
+ if(OBJ_FROZEN(self)) return Qnil;
817
+ GetSSLCTX(self, ctx);
818
+
819
+ #if !defined(OPENSSL_NO_DH)
820
+ SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
821
+ #endif
822
+
823
+ #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
824
+ SSL_CTX_set_post_handshake_auth(ctx, 1);
825
+ #endif
826
+
827
+ val = rb_attr_get(self, id_i_cert_store);
828
+ if (!NIL_P(val)) {
829
+ X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */
830
+ SSL_CTX_set_cert_store(ctx, store);
831
+ X509_STORE_up_ref(store);
832
+ }
833
+
834
+ val = rb_attr_get(self, id_i_extra_chain_cert);
835
+ if(!NIL_P(val)){
836
+ rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
837
+ }
838
+
839
+ /* private key may be bundled in certificate file. */
840
+ val = rb_attr_get(self, id_i_cert);
841
+ cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
842
+ val = rb_attr_get(self, id_i_key);
843
+ key = NIL_P(val) ? NULL : GetPrivPKeyPtr(val); /* NO DUP NEEDED */
844
+ if (cert && key) {
845
+ if (!SSL_CTX_use_certificate(ctx, cert)) {
846
+ /* Adds a ref => Safe to FREE */
847
+ ossl_raise(eSSLError, "SSL_CTX_use_certificate");
848
+ }
849
+ if (!SSL_CTX_use_PrivateKey(ctx, key)) {
850
+ /* Adds a ref => Safe to FREE */
851
+ ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
852
+ }
853
+ if (!SSL_CTX_check_private_key(ctx)) {
854
+ ossl_raise(eSSLError, "SSL_CTX_check_private_key");
855
+ }
856
+ }
857
+
858
+ val = rb_attr_get(self, id_i_client_ca);
859
+ if(!NIL_P(val)){
860
+ if (RB_TYPE_P(val, T_ARRAY)) {
861
+ for(i = 0; i < RARRAY_LEN(val); i++){
862
+ client_ca = GetX509CertPtr(RARRAY_AREF(val, i));
863
+ if (!SSL_CTX_add_client_CA(ctx, client_ca)){
864
+ /* Copies X509_NAME => FREE it. */
865
+ ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
866
+ }
867
+ }
868
+ }
869
+ else{
870
+ client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
871
+ if (!SSL_CTX_add_client_CA(ctx, client_ca)){
872
+ /* Copies X509_NAME => FREE it. */
873
+ ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
874
+ }
875
+ }
876
+ }
877
+
878
+ val = rb_attr_get(self, id_i_ca_file);
879
+ ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
880
+ val = rb_attr_get(self, id_i_ca_path);
881
+ ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
882
+ #ifdef HAVE_SSL_CTX_LOAD_VERIFY_FILE
883
+ if (ca_file && !SSL_CTX_load_verify_file(ctx, ca_file))
884
+ ossl_raise(eSSLError, "SSL_CTX_load_verify_file");
885
+ if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path))
886
+ ossl_raise(eSSLError, "SSL_CTX_load_verify_dir");
887
+ #else
888
+ if(ca_file || ca_path){
889
+ if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
890
+ rb_warning("can't set verify locations");
891
+ }
892
+ #endif
893
+
894
+ val = rb_attr_get(self, id_i_verify_mode);
895
+ verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
896
+ SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
897
+ if (RTEST(rb_attr_get(self, id_i_client_cert_cb)))
898
+ SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
899
+
900
+ val = rb_attr_get(self, id_i_timeout);
901
+ if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));
902
+
903
+ val = rb_attr_get(self, id_i_verify_depth);
904
+ if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
905
+
906
+ #ifdef OSSL_USE_NEXTPROTONEG
907
+ val = rb_attr_get(self, id_i_npn_protocols);
908
+ if (!NIL_P(val)) {
909
+ VALUE encoded = ssl_encode_npn_protocols(val);
910
+ rb_ivar_set(self, id_npn_protocols_encoded, encoded);
911
+ SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
912
+ OSSL_Debug("SSL NPN advertise callback added");
913
+ }
914
+ if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
915
+ SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
916
+ OSSL_Debug("SSL NPN select callback added");
917
+ }
918
+ #endif
919
+
920
+ val = rb_attr_get(self, id_i_alpn_protocols);
921
+ if (!NIL_P(val)) {
922
+ VALUE rprotos = ssl_encode_npn_protocols(val);
923
+
924
+ /* returns 0 on success */
925
+ if (SSL_CTX_set_alpn_protos(ctx, (unsigned char *)RSTRING_PTR(rprotos),
926
+ RSTRING_LENINT(rprotos)))
927
+ ossl_raise(eSSLError, "SSL_CTX_set_alpn_protos");
928
+ OSSL_Debug("SSL ALPN values added");
929
+ }
930
+ if (RTEST(rb_attr_get(self, id_i_alpn_select_cb))) {
931
+ SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
932
+ OSSL_Debug("SSL ALPN select callback added");
933
+ }
934
+
935
+ rb_obj_freeze(self);
936
+
937
+ val = rb_attr_get(self, id_i_session_id_context);
938
+ if (!NIL_P(val)){
939
+ StringValue(val);
940
+ if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
941
+ RSTRING_LENINT(val))){
942
+ ossl_raise(eSSLError, "SSL_CTX_set_session_id_context");
943
+ }
944
+ }
945
+
946
+ if (RTEST(rb_attr_get(self, id_i_session_get_cb))) {
947
+ SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
948
+ OSSL_Debug("SSL SESSION get callback added");
949
+ }
950
+ if (RTEST(rb_attr_get(self, id_i_session_new_cb))) {
951
+ SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
952
+ OSSL_Debug("SSL SESSION new callback added");
953
+ }
954
+ if (RTEST(rb_attr_get(self, id_i_session_remove_cb))) {
955
+ SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
956
+ OSSL_Debug("SSL SESSION remove callback added");
957
+ }
958
+
959
+ val = rb_attr_get(self, id_i_servername_cb);
960
+ if (!NIL_P(val)) {
961
+ SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
962
+ OSSL_Debug("SSL TLSEXT servername callback added");
963
+ }
964
+
965
+ #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
966
+ /*
967
+ * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
968
+ * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
969
+ * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
970
+ */
971
+ if (RTEST(rb_attr_get(self, id_i_keylog_cb))) {
972
+ SSL_CTX_set_keylog_callback(ctx, ossl_sslctx_keylog_cb);
973
+ OSSL_Debug("SSL keylog callback added");
974
+ }
975
+ #endif
976
+
977
+ return Qtrue;
978
+ }
979
+
980
+ static VALUE
981
+ ossl_ssl_cipher_to_ary(const SSL_CIPHER *cipher)
982
+ {
983
+ VALUE ary;
984
+ int bits, alg_bits;
985
+
986
+ ary = rb_ary_new2(4);
987
+ rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_name(cipher)));
988
+ rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_version(cipher)));
989
+ bits = SSL_CIPHER_get_bits(cipher, &alg_bits);
990
+ rb_ary_push(ary, INT2NUM(bits));
991
+ rb_ary_push(ary, INT2NUM(alg_bits));
992
+
993
+ return ary;
994
+ }
995
+
996
+ /*
997
+ * call-seq:
998
+ * ctx.ciphers => [[name, version, bits, alg_bits], ...]
999
+ *
1000
+ * The list of cipher suites configured for this context.
1001
+ */
1002
+ static VALUE
1003
+ ossl_sslctx_get_ciphers(VALUE self)
1004
+ {
1005
+ SSL_CTX *ctx;
1006
+ STACK_OF(SSL_CIPHER) *ciphers;
1007
+ const SSL_CIPHER *cipher;
1008
+ VALUE ary;
1009
+ int i, num;
1010
+
1011
+ GetSSLCTX(self, ctx);
1012
+ ciphers = SSL_CTX_get_ciphers(ctx);
1013
+ if (!ciphers)
1014
+ return rb_ary_new();
1015
+
1016
+ num = sk_SSL_CIPHER_num(ciphers);
1017
+ ary = rb_ary_new2(num);
1018
+ for(i = 0; i < num; i++){
1019
+ cipher = sk_SSL_CIPHER_value(ciphers, i);
1020
+ rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher));
1021
+ }
1022
+ return ary;
1023
+ }
1024
+
1025
+ static VALUE
1026
+ build_cipher_string(VALUE v)
1027
+ {
1028
+ VALUE str, elem;
1029
+ int i;
1030
+
1031
+ if (RB_TYPE_P(v, T_ARRAY)) {
1032
+ str = rb_str_new(0, 0);
1033
+ for (i = 0; i < RARRAY_LEN(v); i++) {
1034
+ elem = rb_ary_entry(v, i);
1035
+ if (RB_TYPE_P(elem, T_ARRAY)) elem = rb_ary_entry(elem, 0);
1036
+ elem = rb_String(elem);
1037
+ rb_str_append(str, elem);
1038
+ if (i < RARRAY_LEN(v)-1) rb_str_cat2(str, ":");
1039
+ }
1040
+ } else {
1041
+ str = v;
1042
+ StringValue(str);
1043
+ }
1044
+
1045
+ return str;
1046
+ }
1047
+
1048
+ /*
1049
+ * call-seq:
1050
+ * ctx.ciphers = "cipher1:cipher2:..."
1051
+ * ctx.ciphers = [name, ...]
1052
+ * ctx.ciphers = [[name, version, bits, alg_bits], ...]
1053
+ *
1054
+ * Sets the list of available cipher suites for this context. Note in a server
1055
+ * context some ciphers require the appropriate certificates. For example, an
1056
+ * RSA cipher suite can only be chosen when an RSA certificate is available.
1057
+ */
1058
+ static VALUE
1059
+ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
1060
+ {
1061
+ SSL_CTX *ctx;
1062
+ VALUE str;
1063
+
1064
+ rb_check_frozen(self);
1065
+ if (NIL_P(v))
1066
+ return v;
1067
+
1068
+ str = build_cipher_string(v);
1069
+
1070
+ GetSSLCTX(self, ctx);
1071
+ if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str)))
1072
+ ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
1073
+
1074
+ return v;
1075
+ }
1076
+
1077
+ #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
1078
+ /*
1079
+ * call-seq:
1080
+ * ctx.ciphersuites = "cipher1:cipher2:..."
1081
+ * ctx.ciphersuites = [name, ...]
1082
+ * ctx.ciphersuites = [[name, version, bits, alg_bits], ...]
1083
+ *
1084
+ * Sets the list of available TLSv1.3 cipher suites for this context.
1085
+ */
1086
+ static VALUE
1087
+ ossl_sslctx_set_ciphersuites(VALUE self, VALUE v)
1088
+ {
1089
+ SSL_CTX *ctx;
1090
+ VALUE str;
1091
+
1092
+ rb_check_frozen(self);
1093
+ if (NIL_P(v))
1094
+ return v;
1095
+
1096
+ str = build_cipher_string(v);
1097
+
1098
+ GetSSLCTX(self, ctx);
1099
+ if (!SSL_CTX_set_ciphersuites(ctx, StringValueCStr(str)))
1100
+ ossl_raise(eSSLError, "SSL_CTX_set_ciphersuites");
1101
+
1102
+ return v;
1103
+ }
1104
+ #endif
1105
+
1106
+ #ifndef OPENSSL_NO_DH
1107
+ /*
1108
+ * call-seq:
1109
+ * ctx.tmp_dh = pkey
1110
+ *
1111
+ * Sets DH parameters used for ephemeral DH key exchange. This is relevant for
1112
+ * servers only.
1113
+ *
1114
+ * +pkey+ is an instance of OpenSSL::PKey::DH. Note that key components
1115
+ * contained in the key object, if any, are ignored. The server will always
1116
+ * generate a new key pair for each handshake.
1117
+ *
1118
+ * Added in version 3.0. See also the man page SSL_set0_tmp_dh_pkey(3).
1119
+ *
1120
+ * Example:
1121
+ * ctx = OpenSSL::SSL::SSLContext.new
1122
+ * ctx.tmp_dh = OpenSSL::DH.generate(2048)
1123
+ * svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx)
1124
+ * Thread.new { svr.accept }
1125
+ */
1126
+ static VALUE
1127
+ ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg)
1128
+ {
1129
+ SSL_CTX *ctx;
1130
+ EVP_PKEY *pkey;
1131
+
1132
+ rb_check_frozen(self);
1133
+ GetSSLCTX(self, ctx);
1134
+ pkey = GetPKeyPtr(arg);
1135
+
1136
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH)
1137
+ rb_raise(eSSLError, "invalid pkey type %s (expected DH)",
1138
+ OBJ_nid2sn(EVP_PKEY_base_id(pkey)));
1139
+ #ifdef HAVE_SSL_SET0_TMP_DH_PKEY
1140
+ if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkey))
1141
+ ossl_raise(eSSLError, "SSL_CTX_set0_tmp_dh_pkey");
1142
+ EVP_PKEY_up_ref(pkey);
1143
+ #else
1144
+ if (!SSL_CTX_set_tmp_dh(ctx, EVP_PKEY_get0_DH(pkey)))
1145
+ ossl_raise(eSSLError, "SSL_CTX_set_tmp_dh");
1146
+ #endif
1147
+
1148
+ return arg;
1149
+ }
1150
+ #endif
1151
+
1152
+ #if !defined(OPENSSL_NO_EC)
1153
+ /*
1154
+ * call-seq:
1155
+ * ctx.ecdh_curves = curve_list -> curve_list
1156
+ *
1157
+ * Sets the list of "supported elliptic curves" for this context.
1158
+ *
1159
+ * For a TLS client, the list is directly used in the Supported Elliptic Curves
1160
+ * Extension. For a server, the list is used by OpenSSL to determine the set of
1161
+ * shared curves. OpenSSL will pick the most appropriate one from it.
1162
+ *
1163
+ * === Example
1164
+ * ctx1 = OpenSSL::SSL::SSLContext.new
1165
+ * ctx1.ecdh_curves = "X25519:P-256:P-224"
1166
+ * svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx1)
1167
+ * Thread.new { svr.accept }
1168
+ *
1169
+ * ctx2 = OpenSSL::SSL::SSLContext.new
1170
+ * ctx2.ecdh_curves = "P-256"
1171
+ * cli = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx2)
1172
+ * cli.connect
1173
+ *
1174
+ * p cli.tmp_key.group.curve_name
1175
+ * # => "prime256v1" (is an alias for NIST P-256)
1176
+ */
1177
+ static VALUE
1178
+ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
1179
+ {
1180
+ SSL_CTX *ctx;
1181
+
1182
+ rb_check_frozen(self);
1183
+ GetSSLCTX(self, ctx);
1184
+ StringValueCStr(arg);
1185
+
1186
+ if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
1187
+ ossl_raise(eSSLError, NULL);
1188
+ return arg;
1189
+ }
1190
+ #else
1191
+ #define ossl_sslctx_set_ecdh_curves rb_f_notimplement
1192
+ #endif
1193
+
1194
+ /*
1195
+ * call-seq:
1196
+ * ctx.security_level -> Integer
1197
+ *
1198
+ * Returns the security level for the context.
1199
+ *
1200
+ * See also OpenSSL::SSL::SSLContext#security_level=.
1201
+ */
1202
+ static VALUE
1203
+ ossl_sslctx_get_security_level(VALUE self)
1204
+ {
1205
+ SSL_CTX *ctx;
1206
+
1207
+ GetSSLCTX(self, ctx);
1208
+
1209
+ #if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
1210
+ return INT2NUM(SSL_CTX_get_security_level(ctx));
1211
+ #else
1212
+ (void)ctx;
1213
+ return INT2FIX(0);
1214
+ #endif
1215
+ }
1216
+
1217
+ /*
1218
+ * call-seq:
1219
+ * ctx.security_level = integer
1220
+ *
1221
+ * Sets the security level for the context. OpenSSL limits parameters according
1222
+ * to the level. The "parameters" include: ciphersuites, curves, key sizes,
1223
+ * certificate signature algorithms, protocol version and so on. For example,
1224
+ * level 1 rejects parameters offering below 80 bits of security, such as
1225
+ * ciphersuites using MD5 for the MAC or RSA keys shorter than 1024 bits.
1226
+ *
1227
+ * Note that attempts to set such parameters with insufficient security are
1228
+ * also blocked. You need to lower the level first.
1229
+ *
1230
+ * This feature is not supported in OpenSSL < 1.1.0, and setting the level to
1231
+ * other than 0 will raise NotImplementedError. Level 0 means everything is
1232
+ * permitted, the same behavior as previous versions of OpenSSL.
1233
+ *
1234
+ * See the manpage of SSL_CTX_set_security_level(3) for details.
1235
+ */
1236
+ static VALUE
1237
+ ossl_sslctx_set_security_level(VALUE self, VALUE value)
1238
+ {
1239
+ SSL_CTX *ctx;
1240
+
1241
+ rb_check_frozen(self);
1242
+ GetSSLCTX(self, ctx);
1243
+
1244
+ #if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL)
1245
+ SSL_CTX_set_security_level(ctx, NUM2INT(value));
1246
+ #else
1247
+ (void)ctx;
1248
+ if (NUM2INT(value) != 0)
1249
+ ossl_raise(rb_eNotImpError, "setting security level to other than 0 is "
1250
+ "not supported in this version of OpenSSL");
1251
+ #endif
1252
+
1253
+ return value;
1254
+ }
1255
+
1256
+ #ifdef SSL_MODE_SEND_FALLBACK_SCSV
1257
+ /*
1258
+ * call-seq:
1259
+ * ctx.enable_fallback_scsv() => nil
1260
+ *
1261
+ * Activate TLS_FALLBACK_SCSV for this context.
1262
+ * See RFC 7507.
1263
+ */
1264
+ static VALUE
1265
+ ossl_sslctx_enable_fallback_scsv(VALUE self)
1266
+ {
1267
+ SSL_CTX *ctx;
1268
+
1269
+ GetSSLCTX(self, ctx);
1270
+ SSL_CTX_set_mode(ctx, SSL_MODE_SEND_FALLBACK_SCSV);
1271
+
1272
+ return Qnil;
1273
+ }
1274
+ #endif
1275
+
1276
+ /*
1277
+ * call-seq:
1278
+ * ctx.add_certificate(certificate, pkey [, extra_certs]) -> self
1279
+ *
1280
+ * Adds a certificate to the context. _pkey_ must be a corresponding private
1281
+ * key with _certificate_.
1282
+ *
1283
+ * Multiple certificates with different public key type can be added by
1284
+ * repeated calls of this method, and OpenSSL will choose the most appropriate
1285
+ * certificate during the handshake.
1286
+ *
1287
+ * #cert=, #key=, and #extra_chain_cert= are old accessor methods for setting
1288
+ * certificate and internally call this method.
1289
+ *
1290
+ * === Parameters
1291
+ * _certificate_::
1292
+ * A certificate. An instance of OpenSSL::X509::Certificate.
1293
+ * _pkey_::
1294
+ * The private key for _certificate_. An instance of OpenSSL::PKey::PKey.
1295
+ * _extra_certs_::
1296
+ * Optional. An array of OpenSSL::X509::Certificate. When sending a
1297
+ * certificate chain, the certificates specified by this are sent following
1298
+ * _certificate_, in the order in the array.
1299
+ *
1300
+ * === Example
1301
+ * rsa_cert = OpenSSL::X509::Certificate.new(...)
1302
+ * rsa_pkey = OpenSSL::PKey.read(...)
1303
+ * ca_intermediate_cert = OpenSSL::X509::Certificate.new(...)
1304
+ * ctx.add_certificate(rsa_cert, rsa_pkey, [ca_intermediate_cert])
1305
+ *
1306
+ * ecdsa_cert = ...
1307
+ * ecdsa_pkey = ...
1308
+ * another_ca_cert = ...
1309
+ * ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert])
1310
+ */
1311
+ static VALUE
1312
+ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self)
1313
+ {
1314
+ VALUE cert, key, extra_chain_ary;
1315
+ SSL_CTX *ctx;
1316
+ X509 *x509;
1317
+ STACK_OF(X509) *extra_chain = NULL;
1318
+ EVP_PKEY *pkey, *pub_pkey;
1319
+
1320
+ GetSSLCTX(self, ctx);
1321
+ rb_scan_args(argc, argv, "21", &cert, &key, &extra_chain_ary);
1322
+ rb_check_frozen(self);
1323
+ x509 = GetX509CertPtr(cert);
1324
+ pkey = GetPrivPKeyPtr(key);
1325
+
1326
+ /*
1327
+ * The reference counter is bumped, and decremented immediately.
1328
+ * X509_get0_pubkey() is only available in OpenSSL >= 1.1.0.
1329
+ */
1330
+ pub_pkey = X509_get_pubkey(x509);
1331
+ EVP_PKEY_free(pub_pkey);
1332
+ if (!pub_pkey)
1333
+ rb_raise(rb_eArgError, "certificate does not contain public key");
1334
+ if (EVP_PKEY_eq(pub_pkey, pkey) != 1)
1335
+ rb_raise(rb_eArgError, "public key mismatch");
1336
+
1337
+ if (argc >= 3)
1338
+ extra_chain = ossl_x509_ary2sk(extra_chain_ary);
1339
+
1340
+ if (!SSL_CTX_use_certificate(ctx, x509)) {
1341
+ sk_X509_pop_free(extra_chain, X509_free);
1342
+ ossl_raise(eSSLError, "SSL_CTX_use_certificate");
1343
+ }
1344
+ if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
1345
+ sk_X509_pop_free(extra_chain, X509_free);
1346
+ ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
1347
+ }
1348
+ if (extra_chain && !SSL_CTX_set0_chain(ctx, extra_chain)) {
1349
+ sk_X509_pop_free(extra_chain, X509_free);
1350
+ ossl_raise(eSSLError, "SSL_CTX_set0_chain");
1351
+ }
1352
+ return self;
1353
+ }
1354
+
1355
+ /*
1356
+ * call-seq:
1357
+ * ctx.session_add(session) -> true | false
1358
+ *
1359
+ * Adds _session_ to the session cache.
1360
+ */
1361
+ static VALUE
1362
+ ossl_sslctx_session_add(VALUE self, VALUE arg)
1363
+ {
1364
+ SSL_CTX *ctx;
1365
+ SSL_SESSION *sess;
1366
+
1367
+ GetSSLCTX(self, ctx);
1368
+ GetSSLSession(arg, sess);
1369
+
1370
+ return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse;
1371
+ }
1372
+
1373
+ /*
1374
+ * call-seq:
1375
+ * ctx.session_remove(session) -> true | false
1376
+ *
1377
+ * Removes _session_ from the session cache.
1378
+ */
1379
+ static VALUE
1380
+ ossl_sslctx_session_remove(VALUE self, VALUE arg)
1381
+ {
1382
+ SSL_CTX *ctx;
1383
+ SSL_SESSION *sess;
1384
+
1385
+ GetSSLCTX(self, ctx);
1386
+ GetSSLSession(arg, sess);
1387
+
1388
+ return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse;
1389
+ }
1390
+
1391
+ /*
1392
+ * call-seq:
1393
+ * ctx.session_cache_mode -> Integer
1394
+ *
1395
+ * The current session cache mode.
1396
+ */
1397
+ static VALUE
1398
+ ossl_sslctx_get_session_cache_mode(VALUE self)
1399
+ {
1400
+ SSL_CTX *ctx;
1401
+
1402
+ GetSSLCTX(self, ctx);
1403
+
1404
+ return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx));
1405
+ }
1406
+
1407
+ /*
1408
+ * call-seq:
1409
+ * ctx.session_cache_mode=(integer) -> Integer
1410
+ *
1411
+ * Sets the SSL session cache mode. Bitwise-or together the desired
1412
+ * SESSION_CACHE_* constants to set. See SSL_CTX_set_session_cache_mode(3) for
1413
+ * details.
1414
+ */
1415
+ static VALUE
1416
+ ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg)
1417
+ {
1418
+ SSL_CTX *ctx;
1419
+
1420
+ GetSSLCTX(self, ctx);
1421
+
1422
+ SSL_CTX_set_session_cache_mode(ctx, NUM2LONG(arg));
1423
+
1424
+ return arg;
1425
+ }
1426
+
1427
+ /*
1428
+ * call-seq:
1429
+ * ctx.session_cache_size -> Integer
1430
+ *
1431
+ * Returns the current session cache size. Zero is used to represent an
1432
+ * unlimited cache size.
1433
+ */
1434
+ static VALUE
1435
+ ossl_sslctx_get_session_cache_size(VALUE self)
1436
+ {
1437
+ SSL_CTX *ctx;
1438
+
1439
+ GetSSLCTX(self, ctx);
1440
+
1441
+ return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx));
1442
+ }
1443
+
1444
+ /*
1445
+ * call-seq:
1446
+ * ctx.session_cache_size=(integer) -> Integer
1447
+ *
1448
+ * Sets the session cache size. Returns the previously valid session cache
1449
+ * size. Zero is used to represent an unlimited session cache size.
1450
+ */
1451
+ static VALUE
1452
+ ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg)
1453
+ {
1454
+ SSL_CTX *ctx;
1455
+
1456
+ GetSSLCTX(self, ctx);
1457
+
1458
+ SSL_CTX_sess_set_cache_size(ctx, NUM2LONG(arg));
1459
+
1460
+ return arg;
1461
+ }
1462
+
1463
+ /*
1464
+ * call-seq:
1465
+ * ctx.session_cache_stats -> Hash
1466
+ *
1467
+ * Returns a Hash containing the following keys:
1468
+ *
1469
+ * :accept:: Number of started SSL/TLS handshakes in server mode
1470
+ * :accept_good:: Number of established SSL/TLS sessions in server mode
1471
+ * :accept_renegotiate:: Number of start renegotiations in server mode
1472
+ * :cache_full:: Number of sessions that were removed due to cache overflow
1473
+ * :cache_hits:: Number of successfully reused connections
1474
+ * :cache_misses:: Number of sessions proposed by clients that were not found
1475
+ * in the cache
1476
+ * :cache_num:: Number of sessions in the internal session cache
1477
+ * :cb_hits:: Number of sessions retrieved from the external cache in server
1478
+ * mode
1479
+ * :connect:: Number of started SSL/TLS handshakes in client mode
1480
+ * :connect_good:: Number of established SSL/TLS sessions in client mode
1481
+ * :connect_renegotiate:: Number of start renegotiations in client mode
1482
+ * :timeouts:: Number of sessions proposed by clients that were found in the
1483
+ * cache but had expired due to timeouts
1484
+ */
1485
+ static VALUE
1486
+ ossl_sslctx_get_session_cache_stats(VALUE self)
1487
+ {
1488
+ SSL_CTX *ctx;
1489
+ VALUE hash;
1490
+
1491
+ GetSSLCTX(self, ctx);
1492
+
1493
+ hash = rb_hash_new();
1494
+ rb_hash_aset(hash, ID2SYM(rb_intern("cache_num")), LONG2NUM(SSL_CTX_sess_number(ctx)));
1495
+ rb_hash_aset(hash, ID2SYM(rb_intern("connect")), LONG2NUM(SSL_CTX_sess_connect(ctx)));
1496
+ rb_hash_aset(hash, ID2SYM(rb_intern("connect_good")), LONG2NUM(SSL_CTX_sess_connect_good(ctx)));
1497
+ rb_hash_aset(hash, ID2SYM(rb_intern("connect_renegotiate")), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx)));
1498
+ rb_hash_aset(hash, ID2SYM(rb_intern("accept")), LONG2NUM(SSL_CTX_sess_accept(ctx)));
1499
+ rb_hash_aset(hash, ID2SYM(rb_intern("accept_good")), LONG2NUM(SSL_CTX_sess_accept_good(ctx)));
1500
+ rb_hash_aset(hash, ID2SYM(rb_intern("accept_renegotiate")), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx)));
1501
+ rb_hash_aset(hash, ID2SYM(rb_intern("cache_hits")), LONG2NUM(SSL_CTX_sess_hits(ctx)));
1502
+ rb_hash_aset(hash, ID2SYM(rb_intern("cb_hits")), LONG2NUM(SSL_CTX_sess_cb_hits(ctx)));
1503
+ rb_hash_aset(hash, ID2SYM(rb_intern("cache_misses")), LONG2NUM(SSL_CTX_sess_misses(ctx)));
1504
+ rb_hash_aset(hash, ID2SYM(rb_intern("cache_full")), LONG2NUM(SSL_CTX_sess_cache_full(ctx)));
1505
+ rb_hash_aset(hash, ID2SYM(rb_intern("timeouts")), LONG2NUM(SSL_CTX_sess_timeouts(ctx)));
1506
+
1507
+ return hash;
1508
+ }
1509
+
1510
+
1511
+ /*
1512
+ * call-seq:
1513
+ * ctx.flush_sessions(time) -> self
1514
+ *
1515
+ * Removes sessions in the internal cache that have expired at _time_.
1516
+ */
1517
+ static VALUE
1518
+ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
1519
+ {
1520
+ VALUE arg1;
1521
+ SSL_CTX *ctx;
1522
+ time_t tm = 0;
1523
+
1524
+ rb_scan_args(argc, argv, "01", &arg1);
1525
+
1526
+ GetSSLCTX(self, ctx);
1527
+
1528
+ if (NIL_P(arg1)) {
1529
+ tm = time(0);
1530
+ } else if (rb_obj_is_instance_of(arg1, rb_cTime)) {
1531
+ tm = NUM2LONG(rb_funcall(arg1, rb_intern("to_i"), 0));
1532
+ } else {
1533
+ ossl_raise(rb_eArgError, "arg must be Time or nil");
1534
+ }
1535
+
1536
+ SSL_CTX_flush_sessions(ctx, (long)tm);
1537
+
1538
+ return self;
1539
+ }
1540
+
1541
+ /*
1542
+ * SSLSocket class
1543
+ */
1544
+ static inline int
1545
+ ssl_started(SSL *ssl)
1546
+ {
1547
+ /* BIO is created through ossl_ssl_setup(), called by #connect or #accept */
1548
+ return SSL_get_rbio(ssl) != NULL;
1549
+ }
1550
+
1551
+ static void
1552
+ ossl_ssl_mark(void *ptr)
1553
+ {
1554
+ SSL *ssl = ptr;
1555
+ rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
1556
+ rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
1557
+ }
1558
+
1559
+ static void
1560
+ ossl_ssl_free(void *ssl)
1561
+ {
1562
+ SSL_free(ssl);
1563
+ }
1564
+
1565
+ const rb_data_type_t ossl_ssl_type = {
1566
+ "OpenSSL/SSL",
1567
+ {
1568
+ ossl_ssl_mark, ossl_ssl_free,
1569
+ },
1570
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
1571
+ };
1572
+
1573
+ static VALUE
1574
+ ossl_ssl_s_alloc(VALUE klass)
1575
+ {
1576
+ return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
1577
+ }
1578
+
1579
+ static VALUE
1580
+ peer_ip_address(VALUE self)
1581
+ {
1582
+ VALUE remote_address = rb_funcall(rb_attr_get(self, id_i_io), rb_intern("remote_address"), 0);
1583
+
1584
+ return rb_funcall(remote_address, rb_intern("inspect_sockaddr"), 0);
1585
+ }
1586
+
1587
+ static VALUE
1588
+ fallback_peer_ip_address(VALUE self, VALUE args)
1589
+ {
1590
+ return rb_str_new_cstr("(null)");
1591
+ }
1592
+
1593
+ static VALUE
1594
+ peeraddr_ip_str(VALUE self)
1595
+ {
1596
+ VALUE rb_mErrno = rb_const_get(rb_cObject, rb_intern("Errno"));
1597
+ VALUE rb_eSystemCallError = rb_const_get(rb_mErrno, rb_intern("SystemCallError"));
1598
+
1599
+ return rb_rescue2(peer_ip_address, self, fallback_peer_ip_address, (VALUE)0, rb_eSystemCallError, NULL);
1600
+ }
1601
+
1602
+ /*
1603
+ * call-seq:
1604
+ * SSLSocket.new(io) => aSSLSocket
1605
+ * SSLSocket.new(io, ctx) => aSSLSocket
1606
+ *
1607
+ * Creates a new SSL socket from _io_ which must be a real IO object (not an
1608
+ * IO-like object that responds to read/write).
1609
+ *
1610
+ * If _ctx_ is provided the SSL Sockets initial params will be taken from
1611
+ * the context.
1612
+ *
1613
+ * The OpenSSL::Buffering module provides additional IO methods.
1614
+ *
1615
+ * This method will freeze the SSLContext if one is provided;
1616
+ * however, session management is still allowed in the frozen SSLContext.
1617
+ */
1618
+ static VALUE
1619
+ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1620
+ {
1621
+ VALUE io, v_ctx, verify_cb;
1622
+ SSL *ssl;
1623
+ SSL_CTX *ctx;
1624
+
1625
+ TypedData_Get_Struct(self, SSL, &ossl_ssl_type, ssl);
1626
+ if (ssl)
1627
+ ossl_raise(eSSLError, "SSL already initialized");
1628
+
1629
+ if (rb_scan_args(argc, argv, "11", &io, &v_ctx) == 1)
1630
+ v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
1631
+
1632
+ GetSSLCTX(v_ctx, ctx);
1633
+ rb_ivar_set(self, id_i_context, v_ctx);
1634
+ ossl_sslctx_setup(v_ctx);
1635
+
1636
+ if (rb_respond_to(io, rb_intern("nonblock=")))
1637
+ rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
1638
+ Check_Type(io, T_FILE);
1639
+ rb_ivar_set(self, id_i_io, io);
1640
+
1641
+ ssl = SSL_new(ctx);
1642
+ if (!ssl)
1643
+ ossl_raise(eSSLError, NULL);
1644
+ RTYPEDDATA_DATA(self) = ssl;
1645
+
1646
+ SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
1647
+ SSL_set_info_callback(ssl, ssl_info_cb);
1648
+ verify_cb = rb_attr_get(v_ctx, id_i_verify_callback);
1649
+ SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
1650
+
1651
+ rb_call_super(0, NULL);
1652
+
1653
+ return self;
1654
+ }
1655
+
1656
+ static VALUE
1657
+ ossl_ssl_setup(VALUE self)
1658
+ {
1659
+ VALUE io;
1660
+ SSL *ssl;
1661
+ rb_io_t *fptr;
1662
+
1663
+ GetSSL(self, ssl);
1664
+ if (ssl_started(ssl))
1665
+ return Qtrue;
1666
+
1667
+ io = rb_attr_get(self, id_i_io);
1668
+ GetOpenFile(io, fptr);
1669
+ rb_io_check_readable(fptr);
1670
+ rb_io_check_writable(fptr);
1671
+ if (!SSL_set_fd(ssl, TO_SOCKET(fptr->fd)))
1672
+ ossl_raise(eSSLError, "SSL_set_fd");
1673
+
1674
+ return Qtrue;
1675
+ }
1676
+
1677
+ #ifdef _WIN32
1678
+ #define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
1679
+ #else
1680
+ #define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret))
1681
+ #endif
1682
+
1683
+ static void
1684
+ write_would_block(int nonblock)
1685
+ {
1686
+ if (nonblock)
1687
+ ossl_raise(eSSLErrorWaitWritable, "write would block");
1688
+ }
1689
+
1690
+ static void
1691
+ read_would_block(int nonblock)
1692
+ {
1693
+ if (nonblock)
1694
+ ossl_raise(eSSLErrorWaitReadable, "read would block");
1695
+ }
1696
+
1697
+ static int
1698
+ no_exception_p(VALUE opts)
1699
+ {
1700
+ if (RB_TYPE_P(opts, T_HASH) &&
1701
+ rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse)
1702
+ return 1;
1703
+ return 0;
1704
+ }
1705
+
1706
+ // Provided by Ruby 3.2.0 and later in order to support the default IO#timeout.
1707
+ #ifndef RUBY_IO_TIMEOUT_DEFAULT
1708
+ #define RUBY_IO_TIMEOUT_DEFAULT Qnil
1709
+ #endif
1710
+
1711
+ static void
1712
+ io_wait_writable(rb_io_t *fptr)
1713
+ {
1714
+ #ifdef HAVE_RB_IO_MAYBE_WAIT
1715
+ rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT);
1716
+ #else
1717
+ rb_io_wait_writable(fptr->fd);
1718
+ #endif
1719
+ }
1720
+
1721
+ static void
1722
+ io_wait_readable(rb_io_t *fptr)
1723
+ {
1724
+ #ifdef HAVE_RB_IO_MAYBE_WAIT
1725
+ rb_io_maybe_wait_readable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT);
1726
+ #else
1727
+ rb_io_wait_readable(fptr->fd);
1728
+ #endif
1729
+ }
1730
+
1731
+ static VALUE
1732
+ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
1733
+ {
1734
+ SSL *ssl;
1735
+ rb_io_t *fptr;
1736
+ int ret, ret2;
1737
+ VALUE cb_state;
1738
+ int nonblock = opts != Qfalse;
1739
+ #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1740
+ unsigned long err;
1741
+ #endif
1742
+
1743
+ rb_ivar_set(self, ID_callback_state, Qnil);
1744
+
1745
+ GetSSL(self, ssl);
1746
+
1747
+ GetOpenFile(rb_attr_get(self, id_i_io), fptr);
1748
+ for(;;){
1749
+ ret = func(ssl);
1750
+
1751
+ cb_state = rb_attr_get(self, ID_callback_state);
1752
+ if (!NIL_P(cb_state)) {
1753
+ /* must cleanup OpenSSL error stack before re-raising */
1754
+ ossl_clear_error();
1755
+ rb_jump_tag(NUM2INT(cb_state));
1756
+ }
1757
+
1758
+ if (ret > 0)
1759
+ break;
1760
+
1761
+ switch((ret2 = ssl_get_error(ssl, ret))){
1762
+ case SSL_ERROR_WANT_WRITE:
1763
+ if (no_exception_p(opts)) { return sym_wait_writable; }
1764
+ write_would_block(nonblock);
1765
+ io_wait_writable(fptr);
1766
+ continue;
1767
+ case SSL_ERROR_WANT_READ:
1768
+ if (no_exception_p(opts)) { return sym_wait_readable; }
1769
+ read_would_block(nonblock);
1770
+ io_wait_readable(fptr);
1771
+ continue;
1772
+ case SSL_ERROR_SYSCALL:
1773
+ #ifdef __APPLE__
1774
+ /* See ossl_ssl_write_internal() */
1775
+ if (errno == EPROTOTYPE)
1776
+ continue;
1777
+ #endif
1778
+ if (errno) rb_sys_fail(funcname);
1779
+ ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
1780
+ funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
1781
+
1782
+ #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1783
+ case SSL_ERROR_SSL:
1784
+ err = ERR_peek_last_error();
1785
+ if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
1786
+ ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1787
+ const char *err_msg = ERR_reason_error_string(err),
1788
+ *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1789
+ if (!err_msg)
1790
+ err_msg = "(null)";
1791
+ if (!verify_msg)
1792
+ verify_msg = "(null)";
1793
+ ossl_clear_error(); /* let ossl_raise() not append message */
1794
+ ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s: %s (%s)",
1795
+ funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl),
1796
+ err_msg, verify_msg);
1797
+ }
1798
+ #endif
1799
+ /* fallthrough */
1800
+ default:
1801
+ ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
1802
+ funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
1803
+ }
1804
+ }
1805
+
1806
+ return self;
1807
+ }
1808
+
1809
+ /*
1810
+ * call-seq:
1811
+ * ssl.connect => self
1812
+ *
1813
+ * Initiates an SSL/TLS handshake with a server.
1814
+ */
1815
+ static VALUE
1816
+ ossl_ssl_connect(VALUE self)
1817
+ {
1818
+ ossl_ssl_setup(self);
1819
+
1820
+ return ossl_start_ssl(self, SSL_connect, "SSL_connect", Qfalse);
1821
+ }
1822
+
1823
+ /*
1824
+ * call-seq:
1825
+ * ssl.connect_nonblock([options]) => self
1826
+ *
1827
+ * Initiates the SSL/TLS handshake as a client in non-blocking manner.
1828
+ *
1829
+ * # emulates blocking connect
1830
+ * begin
1831
+ * ssl.connect_nonblock
1832
+ * rescue IO::WaitReadable
1833
+ * IO.select([s2])
1834
+ * retry
1835
+ * rescue IO::WaitWritable
1836
+ * IO.select(nil, [s2])
1837
+ * retry
1838
+ * end
1839
+ *
1840
+ * By specifying a keyword argument _exception_ to +false+, you can indicate
1841
+ * that connect_nonblock should not raise an IO::WaitReadable or
1842
+ * IO::WaitWritable exception, but return the symbol +:wait_readable+ or
1843
+ * +:wait_writable+ instead.
1844
+ */
1845
+ static VALUE
1846
+ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
1847
+ {
1848
+ VALUE opts;
1849
+ rb_scan_args(argc, argv, "0:", &opts);
1850
+
1851
+ ossl_ssl_setup(self);
1852
+
1853
+ return ossl_start_ssl(self, SSL_connect, "SSL_connect", opts);
1854
+ }
1855
+
1856
+ /*
1857
+ * call-seq:
1858
+ * ssl.accept => self
1859
+ *
1860
+ * Waits for a SSL/TLS client to initiate a handshake.
1861
+ */
1862
+ static VALUE
1863
+ ossl_ssl_accept(VALUE self)
1864
+ {
1865
+ ossl_ssl_setup(self);
1866
+
1867
+ return ossl_start_ssl(self, SSL_accept, "SSL_accept", Qfalse);
1868
+ }
1869
+
1870
+ /*
1871
+ * call-seq:
1872
+ * ssl.accept_nonblock([options]) => self
1873
+ *
1874
+ * Initiates the SSL/TLS handshake as a server in non-blocking manner.
1875
+ *
1876
+ * # emulates blocking accept
1877
+ * begin
1878
+ * ssl.accept_nonblock
1879
+ * rescue IO::WaitReadable
1880
+ * IO.select([s2])
1881
+ * retry
1882
+ * rescue IO::WaitWritable
1883
+ * IO.select(nil, [s2])
1884
+ * retry
1885
+ * end
1886
+ *
1887
+ * By specifying a keyword argument _exception_ to +false+, you can indicate
1888
+ * that accept_nonblock should not raise an IO::WaitReadable or
1889
+ * IO::WaitWritable exception, but return the symbol +:wait_readable+ or
1890
+ * +:wait_writable+ instead.
1891
+ */
1892
+ static VALUE
1893
+ ossl_ssl_accept_nonblock(int argc, VALUE *argv, VALUE self)
1894
+ {
1895
+ VALUE opts;
1896
+
1897
+ rb_scan_args(argc, argv, "0:", &opts);
1898
+ ossl_ssl_setup(self);
1899
+
1900
+ return ossl_start_ssl(self, SSL_accept, "SSL_accept", opts);
1901
+ }
1902
+
1903
+ static VALUE
1904
+ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1905
+ {
1906
+ SSL *ssl;
1907
+ int ilen;
1908
+ VALUE len, str;
1909
+ rb_io_t *fptr;
1910
+ VALUE io, opts = Qnil;
1911
+
1912
+ if (nonblock) {
1913
+ rb_scan_args(argc, argv, "11:", &len, &str, &opts);
1914
+ } else {
1915
+ rb_scan_args(argc, argv, "11", &len, &str);
1916
+ }
1917
+ GetSSL(self, ssl);
1918
+ if (!ssl_started(ssl))
1919
+ rb_raise(eSSLError, "SSL session is not started yet");
1920
+
1921
+ ilen = NUM2INT(len);
1922
+ if (NIL_P(str))
1923
+ str = rb_str_new(0, ilen);
1924
+ else {
1925
+ StringValue(str);
1926
+ if (RSTRING_LEN(str) >= ilen)
1927
+ rb_str_modify(str);
1928
+ else
1929
+ rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
1930
+ }
1931
+ rb_str_set_len(str, 0);
1932
+ if (ilen == 0)
1933
+ return str;
1934
+
1935
+ io = rb_attr_get(self, id_i_io);
1936
+ GetOpenFile(io, fptr);
1937
+
1938
+ rb_str_locktmp(str);
1939
+ for (;;) {
1940
+ int nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1941
+ switch (ssl_get_error(ssl, nread)) {
1942
+ case SSL_ERROR_NONE:
1943
+ rb_str_unlocktmp(str);
1944
+ rb_str_set_len(str, nread);
1945
+ return str;
1946
+ case SSL_ERROR_ZERO_RETURN:
1947
+ rb_str_unlocktmp(str);
1948
+ if (no_exception_p(opts)) { return Qnil; }
1949
+ rb_eof_error();
1950
+ case SSL_ERROR_WANT_WRITE:
1951
+ if (nonblock) {
1952
+ rb_str_unlocktmp(str);
1953
+ if (no_exception_p(opts)) { return sym_wait_writable; }
1954
+ write_would_block(nonblock);
1955
+ }
1956
+ io_wait_writable(fptr);
1957
+ continue;
1958
+ case SSL_ERROR_WANT_READ:
1959
+ if (nonblock) {
1960
+ rb_str_unlocktmp(str);
1961
+ if (no_exception_p(opts)) { return sym_wait_readable; }
1962
+ read_would_block(nonblock);
1963
+ }
1964
+ io_wait_readable(fptr);
1965
+ continue;
1966
+ case SSL_ERROR_SYSCALL:
1967
+ if (!ERR_peek_error()) {
1968
+ rb_str_unlocktmp(str);
1969
+ if (errno)
1970
+ rb_sys_fail(0);
1971
+ else {
1972
+ /*
1973
+ * The underlying BIO returned 0. This is actually a
1974
+ * protocol error. But unfortunately, not all
1975
+ * implementations cleanly shutdown the TLS connection
1976
+ * but just shutdown/close the TCP connection. So report
1977
+ * EOF for now...
1978
+ */
1979
+ if (no_exception_p(opts)) { return Qnil; }
1980
+ rb_eof_error();
1981
+ }
1982
+ }
1983
+ /* fall through */
1984
+ default:
1985
+ rb_str_unlocktmp(str);
1986
+ ossl_raise(eSSLError, "SSL_read");
1987
+ }
1988
+ }
1989
+ }
1990
+
1991
+ /*
1992
+ * call-seq:
1993
+ * ssl.sysread(length) => string
1994
+ * ssl.sysread(length, buffer) => buffer
1995
+ *
1996
+ * Reads _length_ bytes from the SSL connection. If a pre-allocated _buffer_
1997
+ * is provided the data will be written into it.
1998
+ */
1999
+ static VALUE
2000
+ ossl_ssl_read(int argc, VALUE *argv, VALUE self)
2001
+ {
2002
+ return ossl_ssl_read_internal(argc, argv, self, 0);
2003
+ }
2004
+
2005
+ /*
2006
+ * call-seq:
2007
+ * ssl.sysread_nonblock(length) => string
2008
+ * ssl.sysread_nonblock(length, buffer) => buffer
2009
+ * ssl.sysread_nonblock(length[, buffer [, opts]) => buffer
2010
+ *
2011
+ * A non-blocking version of #sysread. Raises an SSLError if reading would
2012
+ * block. If "exception: false" is passed, this method returns a symbol of
2013
+ * :wait_readable, :wait_writable, or nil, rather than raising an exception.
2014
+ *
2015
+ * Reads _length_ bytes from the SSL connection. If a pre-allocated _buffer_
2016
+ * is provided the data will be written into it.
2017
+ */
2018
+ static VALUE
2019
+ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
2020
+ {
2021
+ return ossl_ssl_read_internal(argc, argv, self, 1);
2022
+ }
2023
+
2024
+ static VALUE
2025
+ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
2026
+ {
2027
+ SSL *ssl;
2028
+ rb_io_t *fptr;
2029
+ int num, nonblock = opts != Qfalse;
2030
+ VALUE tmp, io;
2031
+
2032
+ GetSSL(self, ssl);
2033
+ if (!ssl_started(ssl))
2034
+ rb_raise(eSSLError, "SSL session is not started yet");
2035
+
2036
+ tmp = rb_str_new_frozen(StringValue(str));
2037
+ io = rb_attr_get(self, id_i_io);
2038
+ GetOpenFile(io, fptr);
2039
+
2040
+ /* SSL_write(3ssl) manpage states num == 0 is undefined */
2041
+ num = RSTRING_LENINT(tmp);
2042
+ if (num == 0)
2043
+ return INT2FIX(0);
2044
+
2045
+ for (;;) {
2046
+ int nwritten = SSL_write(ssl, RSTRING_PTR(tmp), num);
2047
+ switch (ssl_get_error(ssl, nwritten)) {
2048
+ case SSL_ERROR_NONE:
2049
+ return INT2NUM(nwritten);
2050
+ case SSL_ERROR_WANT_WRITE:
2051
+ if (no_exception_p(opts)) { return sym_wait_writable; }
2052
+ write_would_block(nonblock);
2053
+ io_wait_writable(fptr);
2054
+ continue;
2055
+ case SSL_ERROR_WANT_READ:
2056
+ if (no_exception_p(opts)) { return sym_wait_readable; }
2057
+ read_would_block(nonblock);
2058
+ io_wait_readable(fptr);
2059
+ continue;
2060
+ case SSL_ERROR_SYSCALL:
2061
+ #ifdef __APPLE__
2062
+ /*
2063
+ * It appears that send syscall can return EPROTOTYPE if the
2064
+ * socket is being torn down. Retry to get a proper errno to
2065
+ * make the error handling in line with the socket library.
2066
+ * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
2067
+ */
2068
+ if (errno == EPROTOTYPE)
2069
+ continue;
2070
+ #endif
2071
+ if (errno) rb_sys_fail(0);
2072
+ /* fallthrough */
2073
+ default:
2074
+ ossl_raise(eSSLError, "SSL_write");
2075
+ }
2076
+ }
2077
+ }
2078
+
2079
+ /*
2080
+ * call-seq:
2081
+ * ssl.syswrite(string) => Integer
2082
+ *
2083
+ * Writes _string_ to the SSL connection.
2084
+ */
2085
+ static VALUE
2086
+ ossl_ssl_write(VALUE self, VALUE str)
2087
+ {
2088
+ return ossl_ssl_write_internal(self, str, Qfalse);
2089
+ }
2090
+
2091
+ /*
2092
+ * call-seq:
2093
+ * ssl.syswrite_nonblock(string) => Integer
2094
+ *
2095
+ * Writes _string_ to the SSL connection in a non-blocking manner. Raises an
2096
+ * SSLError if writing would block.
2097
+ */
2098
+ static VALUE
2099
+ ossl_ssl_write_nonblock(int argc, VALUE *argv, VALUE self)
2100
+ {
2101
+ VALUE str, opts;
2102
+
2103
+ rb_scan_args(argc, argv, "1:", &str, &opts);
2104
+
2105
+ return ossl_ssl_write_internal(self, str, opts);
2106
+ }
2107
+
2108
+ /*
2109
+ * call-seq:
2110
+ * ssl.stop => nil
2111
+ *
2112
+ * Sends "close notify" to the peer and tries to shut down the SSL connection
2113
+ * gracefully.
2114
+ */
2115
+ static VALUE
2116
+ ossl_ssl_stop(VALUE self)
2117
+ {
2118
+ SSL *ssl;
2119
+ int ret;
2120
+
2121
+ GetSSL(self, ssl);
2122
+ if (!ssl_started(ssl))
2123
+ return Qnil;
2124
+ ret = SSL_shutdown(ssl);
2125
+ if (ret == 1) /* Have already received close_notify */
2126
+ return Qnil;
2127
+ if (ret == 0) /* Sent close_notify, but we don't wait for reply */
2128
+ return Qnil;
2129
+
2130
+ /*
2131
+ * XXX: Something happened. Possibly it failed because the underlying socket
2132
+ * is not writable/readable, since it is in non-blocking mode. We should do
2133
+ * some proper error handling using SSL_get_error() and maybe retry, but we
2134
+ * can't block here. Give up for now.
2135
+ */
2136
+ ossl_clear_error();
2137
+ return Qnil;
2138
+ }
2139
+
2140
+ /*
2141
+ * call-seq:
2142
+ * ssl.cert => cert or nil
2143
+ *
2144
+ * The X509 certificate for this socket endpoint.
2145
+ */
2146
+ static VALUE
2147
+ ossl_ssl_get_cert(VALUE self)
2148
+ {
2149
+ SSL *ssl;
2150
+ X509 *cert = NULL;
2151
+
2152
+ GetSSL(self, ssl);
2153
+
2154
+ /*
2155
+ * Is this OpenSSL bug? Should add a ref?
2156
+ * TODO: Ask for.
2157
+ */
2158
+ cert = SSL_get_certificate(ssl); /* NO DUPs => DON'T FREE. */
2159
+
2160
+ if (!cert) {
2161
+ return Qnil;
2162
+ }
2163
+ return ossl_x509_new(cert);
2164
+ }
2165
+
2166
+ /*
2167
+ * call-seq:
2168
+ * ssl.peer_cert => cert or nil
2169
+ *
2170
+ * The X509 certificate for this socket's peer.
2171
+ */
2172
+ static VALUE
2173
+ ossl_ssl_get_peer_cert(VALUE self)
2174
+ {
2175
+ SSL *ssl;
2176
+ X509 *cert = NULL;
2177
+ VALUE obj;
2178
+
2179
+ GetSSL(self, ssl);
2180
+
2181
+ cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */
2182
+
2183
+ if (!cert) {
2184
+ return Qnil;
2185
+ }
2186
+ obj = ossl_x509_new(cert);
2187
+ X509_free(cert);
2188
+
2189
+ return obj;
2190
+ }
2191
+
2192
+ /*
2193
+ * call-seq:
2194
+ * ssl.peer_cert_chain => [cert, ...] or nil
2195
+ *
2196
+ * The X509 certificate chain for this socket's peer.
2197
+ */
2198
+ static VALUE
2199
+ ossl_ssl_get_peer_cert_chain(VALUE self)
2200
+ {
2201
+ SSL *ssl;
2202
+ STACK_OF(X509) *chain;
2203
+ X509 *cert;
2204
+ VALUE ary;
2205
+ int i, num;
2206
+
2207
+ GetSSL(self, ssl);
2208
+
2209
+ chain = SSL_get_peer_cert_chain(ssl);
2210
+ if(!chain) return Qnil;
2211
+ num = sk_X509_num(chain);
2212
+ ary = rb_ary_new2(num);
2213
+ for (i = 0; i < num; i++){
2214
+ cert = sk_X509_value(chain, i);
2215
+ rb_ary_push(ary, ossl_x509_new(cert));
2216
+ }
2217
+
2218
+ return ary;
2219
+ }
2220
+
2221
+ /*
2222
+ * call-seq:
2223
+ * ssl.ssl_version => String
2224
+ *
2225
+ * Returns a String representing the SSL/TLS version that was negotiated
2226
+ * for the connection, for example "TLSv1.2".
2227
+ */
2228
+ static VALUE
2229
+ ossl_ssl_get_version(VALUE self)
2230
+ {
2231
+ SSL *ssl;
2232
+
2233
+ GetSSL(self, ssl);
2234
+
2235
+ return rb_str_new2(SSL_get_version(ssl));
2236
+ }
2237
+
2238
+ /*
2239
+ * call-seq:
2240
+ * ssl.cipher -> nil or [name, version, bits, alg_bits]
2241
+ *
2242
+ * Returns the cipher suite actually used in the current session, or nil if
2243
+ * no session has been established.
2244
+ */
2245
+ static VALUE
2246
+ ossl_ssl_get_cipher(VALUE self)
2247
+ {
2248
+ SSL *ssl;
2249
+ const SSL_CIPHER *cipher;
2250
+
2251
+ GetSSL(self, ssl);
2252
+ cipher = SSL_get_current_cipher(ssl);
2253
+ return cipher ? ossl_ssl_cipher_to_ary(cipher) : Qnil;
2254
+ }
2255
+
2256
+ /*
2257
+ * call-seq:
2258
+ * ssl.state => string
2259
+ *
2260
+ * A description of the current connection state. This is for diagnostic
2261
+ * purposes only.
2262
+ */
2263
+ static VALUE
2264
+ ossl_ssl_get_state(VALUE self)
2265
+ {
2266
+ SSL *ssl;
2267
+ VALUE ret;
2268
+
2269
+ GetSSL(self, ssl);
2270
+
2271
+ ret = rb_str_new2(SSL_state_string(ssl));
2272
+ if (ruby_verbose) {
2273
+ rb_str_cat2(ret, ": ");
2274
+ rb_str_cat2(ret, SSL_state_string_long(ssl));
2275
+ }
2276
+ return ret;
2277
+ }
2278
+
2279
+ /*
2280
+ * call-seq:
2281
+ * ssl.pending => Integer
2282
+ *
2283
+ * The number of bytes that are immediately available for reading.
2284
+ */
2285
+ static VALUE
2286
+ ossl_ssl_pending(VALUE self)
2287
+ {
2288
+ SSL *ssl;
2289
+
2290
+ GetSSL(self, ssl);
2291
+
2292
+ return INT2NUM(SSL_pending(ssl));
2293
+ }
2294
+
2295
+ /*
2296
+ * call-seq:
2297
+ * ssl.session_reused? -> true | false
2298
+ *
2299
+ * Returns +true+ if a reused session was negotiated during the handshake.
2300
+ */
2301
+ static VALUE
2302
+ ossl_ssl_session_reused(VALUE self)
2303
+ {
2304
+ SSL *ssl;
2305
+
2306
+ GetSSL(self, ssl);
2307
+
2308
+ return SSL_session_reused(ssl) ? Qtrue : Qfalse;
2309
+ }
2310
+
2311
+ /*
2312
+ * call-seq:
2313
+ * ssl.session = session -> session
2314
+ *
2315
+ * Sets the Session to be used when the connection is established.
2316
+ */
2317
+ static VALUE
2318
+ ossl_ssl_set_session(VALUE self, VALUE arg1)
2319
+ {
2320
+ SSL *ssl;
2321
+ SSL_SESSION *sess;
2322
+
2323
+ GetSSL(self, ssl);
2324
+ GetSSLSession(arg1, sess);
2325
+
2326
+ if (SSL_set_session(ssl, sess) != 1)
2327
+ ossl_raise(eSSLError, "SSL_set_session");
2328
+
2329
+ return arg1;
2330
+ }
2331
+
2332
+ /*
2333
+ * call-seq:
2334
+ * ssl.hostname = hostname -> hostname
2335
+ *
2336
+ * Sets the server hostname used for SNI. This needs to be set before
2337
+ * SSLSocket#connect.
2338
+ */
2339
+ static VALUE
2340
+ ossl_ssl_set_hostname(VALUE self, VALUE arg)
2341
+ {
2342
+ SSL *ssl;
2343
+ char *hostname = NULL;
2344
+
2345
+ GetSSL(self, ssl);
2346
+
2347
+ if (!NIL_P(arg))
2348
+ hostname = StringValueCStr(arg);
2349
+
2350
+ if (!SSL_set_tlsext_host_name(ssl, hostname))
2351
+ ossl_raise(eSSLError, NULL);
2352
+
2353
+ /* for SSLSocket#hostname */
2354
+ rb_ivar_set(self, id_i_hostname, arg);
2355
+
2356
+ return arg;
2357
+ }
2358
+
2359
+ /*
2360
+ * call-seq:
2361
+ * ssl.verify_result => Integer
2362
+ *
2363
+ * Returns the result of the peer certificates verification. See verify(1)
2364
+ * for error values and descriptions.
2365
+ *
2366
+ * If no peer certificate was presented X509_V_OK is returned.
2367
+ */
2368
+ static VALUE
2369
+ ossl_ssl_get_verify_result(VALUE self)
2370
+ {
2371
+ SSL *ssl;
2372
+
2373
+ GetSSL(self, ssl);
2374
+
2375
+ return LONG2NUM(SSL_get_verify_result(ssl));
2376
+ }
2377
+
2378
+ /*
2379
+ * call-seq:
2380
+ * ssl.finished_message => "finished message"
2381
+ *
2382
+ * Returns the last *Finished* message sent
2383
+ *
2384
+ */
2385
+ static VALUE
2386
+ ossl_ssl_get_finished(VALUE self)
2387
+ {
2388
+ SSL *ssl;
2389
+ char sizer[1], *buf;
2390
+ size_t len;
2391
+
2392
+ GetSSL(self, ssl);
2393
+
2394
+ len = SSL_get_finished(ssl, sizer, 0);
2395
+ if (len == 0)
2396
+ return Qnil;
2397
+
2398
+ buf = ALLOCA_N(char, len);
2399
+ SSL_get_finished(ssl, buf, len);
2400
+ return rb_str_new(buf, len);
2401
+ }
2402
+
2403
+ /*
2404
+ * call-seq:
2405
+ * ssl.peer_finished_message => "peer finished message"
2406
+ *
2407
+ * Returns the last *Finished* message received
2408
+ *
2409
+ */
2410
+ static VALUE
2411
+ ossl_ssl_get_peer_finished(VALUE self)
2412
+ {
2413
+ SSL *ssl;
2414
+ char sizer[1], *buf;
2415
+ size_t len;
2416
+
2417
+ GetSSL(self, ssl);
2418
+
2419
+ len = SSL_get_peer_finished(ssl, sizer, 0);
2420
+ if (len == 0)
2421
+ return Qnil;
2422
+
2423
+ buf = ALLOCA_N(char, len);
2424
+ SSL_get_peer_finished(ssl, buf, len);
2425
+ return rb_str_new(buf, len);
2426
+ }
2427
+
2428
+ /*
2429
+ * call-seq:
2430
+ * ssl.client_ca => [x509name, ...]
2431
+ *
2432
+ * Returns the list of client CAs. Please note that in contrast to
2433
+ * SSLContext#client_ca= no array of X509::Certificate is returned but
2434
+ * X509::Name instances of the CA's subject distinguished name.
2435
+ *
2436
+ * In server mode, returns the list set by SSLContext#client_ca=.
2437
+ * In client mode, returns the list of client CAs sent from the server.
2438
+ */
2439
+ static VALUE
2440
+ ossl_ssl_get_client_ca_list(VALUE self)
2441
+ {
2442
+ SSL *ssl;
2443
+ STACK_OF(X509_NAME) *ca;
2444
+
2445
+ GetSSL(self, ssl);
2446
+
2447
+ ca = SSL_get_client_CA_list(ssl);
2448
+ return ossl_x509name_sk2ary(ca);
2449
+ }
2450
+
2451
+ # ifdef OSSL_USE_NEXTPROTONEG
2452
+ /*
2453
+ * call-seq:
2454
+ * ssl.npn_protocol => String | nil
2455
+ *
2456
+ * Returns the protocol string that was finally selected by the client
2457
+ * during the handshake.
2458
+ */
2459
+ static VALUE
2460
+ ossl_ssl_npn_protocol(VALUE self)
2461
+ {
2462
+ SSL *ssl;
2463
+ const unsigned char *out;
2464
+ unsigned int outlen;
2465
+
2466
+ GetSSL(self, ssl);
2467
+
2468
+ SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
2469
+ if (!outlen)
2470
+ return Qnil;
2471
+ else
2472
+ return rb_str_new((const char *) out, outlen);
2473
+ }
2474
+ # endif
2475
+
2476
+ /*
2477
+ * call-seq:
2478
+ * ssl.alpn_protocol => String | nil
2479
+ *
2480
+ * Returns the ALPN protocol string that was finally selected by the server
2481
+ * during the handshake.
2482
+ */
2483
+ static VALUE
2484
+ ossl_ssl_alpn_protocol(VALUE self)
2485
+ {
2486
+ SSL *ssl;
2487
+ const unsigned char *out;
2488
+ unsigned int outlen;
2489
+
2490
+ GetSSL(self, ssl);
2491
+
2492
+ SSL_get0_alpn_selected(ssl, &out, &outlen);
2493
+ if (!outlen)
2494
+ return Qnil;
2495
+ else
2496
+ return rb_str_new((const char *) out, outlen);
2497
+ }
2498
+
2499
+ /*
2500
+ * call-seq:
2501
+ * session.export_keying_material(label, length) -> String
2502
+ *
2503
+ * Enables use of shared session key material in accordance with RFC 5705.
2504
+ */
2505
+ static VALUE
2506
+ ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self)
2507
+ {
2508
+ SSL *ssl;
2509
+ VALUE str;
2510
+ VALUE label;
2511
+ VALUE length;
2512
+ VALUE context;
2513
+ unsigned char *p;
2514
+ size_t len;
2515
+ int use_ctx = 0;
2516
+ unsigned char *ctx = NULL;
2517
+ size_t ctx_len = 0;
2518
+ int ret;
2519
+
2520
+ rb_scan_args(argc, argv, "21", &label, &length, &context);
2521
+ StringValue(label);
2522
+
2523
+ GetSSL(self, ssl);
2524
+
2525
+ len = (size_t)NUM2LONG(length);
2526
+ str = rb_str_new(0, len);
2527
+ p = (unsigned char *)RSTRING_PTR(str);
2528
+ if (!NIL_P(context)) {
2529
+ use_ctx = 1;
2530
+ StringValue(context);
2531
+ ctx = (unsigned char *)RSTRING_PTR(context);
2532
+ ctx_len = RSTRING_LEN(context);
2533
+ }
2534
+ ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label),
2535
+ RSTRING_LENINT(label), ctx, ctx_len, use_ctx);
2536
+ if (ret == 0 || ret == -1) {
2537
+ ossl_raise(eSSLError, "SSL_export_keying_material");
2538
+ }
2539
+ return str;
2540
+ }
2541
+
2542
+ /*
2543
+ * call-seq:
2544
+ * ssl.tmp_key => PKey or nil
2545
+ *
2546
+ * Returns the ephemeral key used in case of forward secrecy cipher.
2547
+ */
2548
+ static VALUE
2549
+ ossl_ssl_tmp_key(VALUE self)
2550
+ {
2551
+ SSL *ssl;
2552
+ EVP_PKEY *key;
2553
+
2554
+ GetSSL(self, ssl);
2555
+ if (!SSL_get_server_tmp_key(ssl, &key))
2556
+ return Qnil;
2557
+ return ossl_pkey_new(key);
2558
+ }
2559
+ #endif /* !defined(OPENSSL_NO_SOCK) */
2560
+
2561
+ void
2562
+ Init_ossl_ssl(void)
2563
+ {
2564
+ #if 0
2565
+ mOSSL = rb_define_module("OpenSSL");
2566
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
2567
+ rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable");
2568
+ rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable");
2569
+ #endif
2570
+
2571
+ #ifndef OPENSSL_NO_SOCK
2572
+ id_call = rb_intern_const("call");
2573
+ ID_callback_state = rb_intern_const("callback_state");
2574
+
2575
+ ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0);
2576
+ if (ossl_ssl_ex_vcb_idx < 0)
2577
+ ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
2578
+ ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_ptr_idx", 0, 0, 0);
2579
+ if (ossl_ssl_ex_ptr_idx < 0)
2580
+ ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
2581
+ ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
2582
+ if (ossl_sslctx_ex_ptr_idx < 0)
2583
+ ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
2584
+
2585
+ /* Document-module: OpenSSL::SSL
2586
+ *
2587
+ * Use SSLContext to set up the parameters for a TLS (former SSL)
2588
+ * connection. Both client and server TLS connections are supported,
2589
+ * SSLSocket and SSLServer may be used in conjunction with an instance
2590
+ * of SSLContext to set up connections.
2591
+ */
2592
+ mSSL = rb_define_module_under(mOSSL, "SSL");
2593
+
2594
+ /* Document-class: OpenSSL::SSL::SSLError
2595
+ *
2596
+ * Generic error class raised by SSLSocket and SSLContext.
2597
+ */
2598
+ eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError);
2599
+ eSSLErrorWaitReadable = rb_define_class_under(mSSL, "SSLErrorWaitReadable", eSSLError);
2600
+ rb_include_module(eSSLErrorWaitReadable, rb_mWaitReadable);
2601
+ eSSLErrorWaitWritable = rb_define_class_under(mSSL, "SSLErrorWaitWritable", eSSLError);
2602
+ rb_include_module(eSSLErrorWaitWritable, rb_mWaitWritable);
2603
+
2604
+ Init_ossl_ssl_session();
2605
+
2606
+ /* Document-class: OpenSSL::SSL::SSLContext
2607
+ *
2608
+ * An SSLContext is used to set various options regarding certificates,
2609
+ * algorithms, verification, session caching, etc. The SSLContext is
2610
+ * used to create an SSLSocket.
2611
+ *
2612
+ * All attributes must be set before creating an SSLSocket as the
2613
+ * SSLContext will be frozen afterward.
2614
+ */
2615
+ cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject);
2616
+ rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc);
2617
+ rb_undef_method(cSSLContext, "initialize_copy");
2618
+
2619
+ /*
2620
+ * Context certificate
2621
+ *
2622
+ * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2623
+ * It is recommended to use #add_certificate instead.
2624
+ */
2625
+ rb_attr(cSSLContext, rb_intern_const("cert"), 1, 1, Qfalse);
2626
+
2627
+ /*
2628
+ * Context private key
2629
+ *
2630
+ * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2631
+ * It is recommended to use #add_certificate instead.
2632
+ */
2633
+ rb_attr(cSSLContext, rb_intern_const("key"), 1, 1, Qfalse);
2634
+
2635
+ /*
2636
+ * A certificate or Array of certificates that will be sent to the client.
2637
+ */
2638
+ rb_attr(cSSLContext, rb_intern_const("client_ca"), 1, 1, Qfalse);
2639
+
2640
+ /*
2641
+ * The path to a file containing a PEM-format CA certificate
2642
+ */
2643
+ rb_attr(cSSLContext, rb_intern_const("ca_file"), 1, 1, Qfalse);
2644
+
2645
+ /*
2646
+ * The path to a directory containing CA certificates in PEM format.
2647
+ *
2648
+ * Files are looked up by subject's X509 name's hash value.
2649
+ */
2650
+ rb_attr(cSSLContext, rb_intern_const("ca_path"), 1, 1, Qfalse);
2651
+
2652
+ /*
2653
+ * Maximum session lifetime in seconds.
2654
+ */
2655
+ rb_attr(cSSLContext, rb_intern_const("timeout"), 1, 1, Qfalse);
2656
+
2657
+ /*
2658
+ * Session verification mode.
2659
+ *
2660
+ * Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE,
2661
+ * VERIFY_FAIL_IF_NO_PEER_CERT and defined on OpenSSL::SSL
2662
+ *
2663
+ * The default mode is VERIFY_NONE, which does not perform any verification
2664
+ * at all.
2665
+ *
2666
+ * See SSL_CTX_set_verify(3) for details.
2667
+ */
2668
+ rb_attr(cSSLContext, rb_intern_const("verify_mode"), 1, 1, Qfalse);
2669
+
2670
+ /*
2671
+ * Number of CA certificates to walk when verifying a certificate chain.
2672
+ */
2673
+ rb_attr(cSSLContext, rb_intern_const("verify_depth"), 1, 1, Qfalse);
2674
+
2675
+ /*
2676
+ * A callback for additional certificate verification. The callback is
2677
+ * invoked for each certificate in the chain.
2678
+ *
2679
+ * The callback is invoked with two values. _preverify_ok_ indicates
2680
+ * indicates if the verification was passed (+true+) or not (+false+).
2681
+ * _store_context_ is an OpenSSL::X509::StoreContext containing the
2682
+ * context used for certificate verification.
2683
+ *
2684
+ * If the callback returns +false+, the chain verification is immediately
2685
+ * stopped and a bad_certificate alert is then sent.
2686
+ */
2687
+ rb_attr(cSSLContext, rb_intern_const("verify_callback"), 1, 1, Qfalse);
2688
+
2689
+ /*
2690
+ * Whether to check the server certificate is valid for the hostname.
2691
+ *
2692
+ * In order to make this work, verify_mode must be set to VERIFY_PEER and
2693
+ * the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=.
2694
+ */
2695
+ rb_attr(cSSLContext, rb_intern_const("verify_hostname"), 1, 1, Qfalse);
2696
+
2697
+ /*
2698
+ * An OpenSSL::X509::Store used for certificate verification.
2699
+ */
2700
+ rb_attr(cSSLContext, rb_intern_const("cert_store"), 1, 1, Qfalse);
2701
+
2702
+ /*
2703
+ * An Array of extra X509 certificates to be added to the certificate
2704
+ * chain.
2705
+ *
2706
+ * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated.
2707
+ * It is recommended to use #add_certificate instead.
2708
+ */
2709
+ rb_attr(cSSLContext, rb_intern_const("extra_chain_cert"), 1, 1, Qfalse);
2710
+
2711
+ /*
2712
+ * A callback invoked when a client certificate is requested by a server
2713
+ * and no certificate has been set.
2714
+ *
2715
+ * The callback is invoked with a Session and must return an Array
2716
+ * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any
2717
+ * other value is returned the handshake is suspended.
2718
+ */
2719
+ rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse);
2720
+
2721
+ /*
2722
+ * Sets the context in which a session can be reused. This allows
2723
+ * sessions for multiple applications to be distinguished, for example, by
2724
+ * name.
2725
+ */
2726
+ rb_attr(cSSLContext, rb_intern_const("session_id_context"), 1, 1, Qfalse);
2727
+
2728
+ /*
2729
+ * A callback invoked on a server when a session is proposed by the client
2730
+ * but the session could not be found in the server's internal cache.
2731
+ *
2732
+ * The callback is invoked with the SSLSocket and session id. The
2733
+ * callback may return a Session from an external cache.
2734
+ */
2735
+ rb_attr(cSSLContext, rb_intern_const("session_get_cb"), 1, 1, Qfalse);
2736
+
2737
+ /*
2738
+ * A callback invoked when a new session was negotiated.
2739
+ *
2740
+ * The callback is invoked with an SSLSocket. If +false+ is returned the
2741
+ * session will be removed from the internal cache.
2742
+ */
2743
+ rb_attr(cSSLContext, rb_intern_const("session_new_cb"), 1, 1, Qfalse);
2744
+
2745
+ /*
2746
+ * A callback invoked when a session is removed from the internal cache.
2747
+ *
2748
+ * The callback is invoked with an SSLContext and a Session.
2749
+ *
2750
+ * IMPORTANT NOTE: It is currently not possible to use this safely in a
2751
+ * multi-threaded application. The callback is called inside a global lock
2752
+ * and it can randomly cause deadlock on Ruby thread switching.
2753
+ */
2754
+ rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse);
2755
+
2756
+ /*
2757
+ * A callback invoked whenever a new handshake is initiated on an
2758
+ * established connection. May be used to disable renegotiation entirely.
2759
+ *
2760
+ * The callback is invoked with the active SSLSocket. The callback's
2761
+ * return value is ignored. A normal return indicates "approval" of the
2762
+ * renegotiation and will continue the process. To forbid renegotiation
2763
+ * and to cancel the process, raise an exception within the callback.
2764
+ *
2765
+ * === Disable client renegotiation
2766
+ *
2767
+ * When running a server, it is often desirable to disable client
2768
+ * renegotiation entirely. You may use a callback as follows to implement
2769
+ * this feature:
2770
+ *
2771
+ * ctx.renegotiation_cb = lambda do |ssl|
2772
+ * raise RuntimeError, "Client renegotiation disabled"
2773
+ * end
2774
+ */
2775
+ rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse);
2776
+ #ifdef OSSL_USE_NEXTPROTONEG
2777
+ /*
2778
+ * An Enumerable of Strings. Each String represents a protocol to be
2779
+ * advertised as the list of supported protocols for Next Protocol
2780
+ * Negotiation. Supported in OpenSSL 1.0.1 and higher. Has no effect
2781
+ * on the client side. If not set explicitly, the NPN extension will
2782
+ * not be sent by the server in the handshake.
2783
+ *
2784
+ * === Example
2785
+ *
2786
+ * ctx.npn_protocols = ["http/1.1", "spdy/2"]
2787
+ */
2788
+ rb_attr(cSSLContext, rb_intern_const("npn_protocols"), 1, 1, Qfalse);
2789
+ /*
2790
+ * A callback invoked on the client side when the client needs to select
2791
+ * a protocol from the list sent by the server. Supported in OpenSSL 1.0.1
2792
+ * and higher. The client MUST select a protocol of those advertised by
2793
+ * the server. If none is acceptable, raising an error in the callback
2794
+ * will cause the handshake to fail. Not setting this callback explicitly
2795
+ * means not supporting the NPN extension on the client - any protocols
2796
+ * advertised by the server will be ignored.
2797
+ *
2798
+ * === Example
2799
+ *
2800
+ * ctx.npn_select_cb = lambda do |protocols|
2801
+ * # inspect the protocols and select one
2802
+ * protocols.first
2803
+ * end
2804
+ */
2805
+ rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse);
2806
+ #endif
2807
+
2808
+ /*
2809
+ * An Enumerable of Strings. Each String represents a protocol to be
2810
+ * advertised as the list of supported protocols for Application-Layer
2811
+ * Protocol Negotiation. Supported in OpenSSL 1.0.2 and higher. Has no
2812
+ * effect on the server side. If not set explicitly, the ALPN extension will
2813
+ * not be included in the handshake.
2814
+ *
2815
+ * === Example
2816
+ *
2817
+ * ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"]
2818
+ */
2819
+ rb_attr(cSSLContext, rb_intern_const("alpn_protocols"), 1, 1, Qfalse);
2820
+ /*
2821
+ * A callback invoked on the server side when the server needs to select
2822
+ * a protocol from the list sent by the client. Supported in OpenSSL 1.0.2
2823
+ * and higher. The callback must return a protocol of those advertised by
2824
+ * the client. If none is acceptable, raising an error in the callback
2825
+ * will cause the handshake to fail. Not setting this callback explicitly
2826
+ * means not supporting the ALPN extension on the server - any protocols
2827
+ * advertised by the client will be ignored.
2828
+ *
2829
+ * === Example
2830
+ *
2831
+ * ctx.alpn_select_cb = lambda do |protocols|
2832
+ * # inspect the protocols and select one
2833
+ * protocols.first
2834
+ * end
2835
+ */
2836
+ rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse);
2837
+
2838
+ /*
2839
+ * A callback invoked when TLS key material is generated or received, in
2840
+ * order to allow applications to store this keying material for debugging
2841
+ * purposes.
2842
+ *
2843
+ * The callback is invoked with an SSLSocket and a string containing the
2844
+ * key material in the format used by NSS for its SSLKEYLOGFILE debugging
2845
+ * output.
2846
+ *
2847
+ * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements
2848
+ * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see
2849
+ * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6).
2850
+ *
2851
+ * === Example
2852
+ *
2853
+ * context.keylog_cb = proc do |_sock, line|
2854
+ * File.open('ssl_keylog_file', "a") do |f|
2855
+ * f.write("#{line}\n")
2856
+ * end
2857
+ * end
2858
+ */
2859
+ rb_attr(cSSLContext, rb_intern_const("keylog_cb"), 1, 1, Qfalse);
2860
+
2861
+ rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2862
+ rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
2863
+ rb_define_private_method(cSSLContext, "set_minmax_proto_version",
2864
+ ossl_sslctx_set_minmax_proto_version, 2);
2865
+ rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2866
+ rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
2867
+ #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
2868
+ rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1);
2869
+ #endif
2870
+ #ifndef OPENSSL_NO_DH
2871
+ rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
2872
+ #endif
2873
+ rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
2874
+ rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
2875
+ rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
2876
+ #ifdef SSL_MODE_SEND_FALLBACK_SCSV
2877
+ rb_define_method(cSSLContext, "enable_fallback_scsv", ossl_sslctx_enable_fallback_scsv, 0);
2878
+ #endif
2879
+ rb_define_method(cSSLContext, "add_certificate", ossl_sslctx_add_certificate, -1);
2880
+
2881
+ rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
2882
+ rb_define_alias(cSSLContext, "freeze", "setup");
2883
+
2884
+ /*
2885
+ * No session caching for client or server
2886
+ */
2887
+ rb_define_const(cSSLContext, "SESSION_CACHE_OFF", LONG2NUM(SSL_SESS_CACHE_OFF));
2888
+
2889
+ /*
2890
+ * Client sessions are added to the session cache
2891
+ */
2892
+ rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT", LONG2NUM(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */
2893
+
2894
+ /*
2895
+ * Server sessions are added to the session cache
2896
+ */
2897
+ rb_define_const(cSSLContext, "SESSION_CACHE_SERVER", LONG2NUM(SSL_SESS_CACHE_SERVER));
2898
+
2899
+ /*
2900
+ * Both client and server sessions are added to the session cache
2901
+ */
2902
+ rb_define_const(cSSLContext, "SESSION_CACHE_BOTH", LONG2NUM(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */
2903
+
2904
+ /*
2905
+ * Normally the session cache is checked for expired sessions every 255
2906
+ * connections. Since this may lead to a delay that cannot be controlled,
2907
+ * the automatic flushing may be disabled and #flush_sessions can be
2908
+ * called explicitly.
2909
+ */
2910
+ rb_define_const(cSSLContext, "SESSION_CACHE_NO_AUTO_CLEAR", LONG2NUM(SSL_SESS_CACHE_NO_AUTO_CLEAR));
2911
+
2912
+ /*
2913
+ * Always perform external lookups of sessions even if they are in the
2914
+ * internal cache.
2915
+ *
2916
+ * This flag has no effect on clients
2917
+ */
2918
+ rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_LOOKUP", LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP));
2919
+
2920
+ /*
2921
+ * Never automatically store sessions in the internal store.
2922
+ */
2923
+ rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_STORE", LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL_STORE));
2924
+
2925
+ /*
2926
+ * Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and
2927
+ * SESSION_CACHE_NO_INTERNAL_STORE.
2928
+ */
2929
+ rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL", LONG2NUM(SSL_SESS_CACHE_NO_INTERNAL));
2930
+
2931
+ rb_define_method(cSSLContext, "session_add", ossl_sslctx_session_add, 1);
2932
+ rb_define_method(cSSLContext, "session_remove", ossl_sslctx_session_remove, 1);
2933
+ rb_define_method(cSSLContext, "session_cache_mode", ossl_sslctx_get_session_cache_mode, 0);
2934
+ rb_define_method(cSSLContext, "session_cache_mode=", ossl_sslctx_set_session_cache_mode, 1);
2935
+ rb_define_method(cSSLContext, "session_cache_size", ossl_sslctx_get_session_cache_size, 0);
2936
+ rb_define_method(cSSLContext, "session_cache_size=", ossl_sslctx_set_session_cache_size, 1);
2937
+ rb_define_method(cSSLContext, "session_cache_stats", ossl_sslctx_get_session_cache_stats, 0);
2938
+ rb_define_method(cSSLContext, "flush_sessions", ossl_sslctx_flush_sessions, -1);
2939
+ rb_define_method(cSSLContext, "options", ossl_sslctx_get_options, 0);
2940
+ rb_define_method(cSSLContext, "options=", ossl_sslctx_set_options, 1);
2941
+
2942
+ /*
2943
+ * Document-class: OpenSSL::SSL::SSLSocket
2944
+ */
2945
+ cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
2946
+ rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
2947
+ rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
2948
+ rb_undef_method(cSSLSocket, "initialize_copy");
2949
+ rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0);
2950
+ rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, -1);
2951
+ rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0);
2952
+ rb_define_method(cSSLSocket, "accept_nonblock", ossl_ssl_accept_nonblock, -1);
2953
+ rb_define_method(cSSLSocket, "sysread", ossl_ssl_read, -1);
2954
+ rb_define_private_method(cSSLSocket, "sysread_nonblock", ossl_ssl_read_nonblock, -1);
2955
+ rb_define_method(cSSLSocket, "syswrite", ossl_ssl_write, 1);
2956
+ rb_define_private_method(cSSLSocket, "syswrite_nonblock", ossl_ssl_write_nonblock, -1);
2957
+ rb_define_private_method(cSSLSocket, "stop", ossl_ssl_stop, 0);
2958
+ rb_define_method(cSSLSocket, "cert", ossl_ssl_get_cert, 0);
2959
+ rb_define_method(cSSLSocket, "peer_cert", ossl_ssl_get_peer_cert, 0);
2960
+ rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0);
2961
+ rb_define_method(cSSLSocket, "ssl_version", ossl_ssl_get_version, 0);
2962
+ rb_define_method(cSSLSocket, "cipher", ossl_ssl_get_cipher, 0);
2963
+ rb_define_method(cSSLSocket, "state", ossl_ssl_get_state, 0);
2964
+ rb_define_method(cSSLSocket, "pending", ossl_ssl_pending, 0);
2965
+ rb_define_method(cSSLSocket, "session_reused?", ossl_ssl_session_reused, 0);
2966
+ /* implementation of OpenSSL::SSL::SSLSocket#session is in lib/openssl/ssl.rb */
2967
+ rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1);
2968
+ rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
2969
+ rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
2970
+ /* #hostname is defined in lib/openssl/ssl.rb */
2971
+ rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
2972
+ rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0);
2973
+ rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
2974
+ rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
2975
+ rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
2976
+ rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1);
2977
+ # ifdef OSSL_USE_NEXTPROTONEG
2978
+ rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2979
+ # endif
2980
+
2981
+ rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
2982
+ rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
2983
+ rb_define_const(mSSL, "VERIFY_FAIL_IF_NO_PEER_CERT", INT2NUM(SSL_VERIFY_FAIL_IF_NO_PEER_CERT));
2984
+ rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
2985
+
2986
+ rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL));
2987
+ #ifdef SSL_OP_CLEANSE_PLAINTEXT /* OpenSSL 3.0 */
2988
+ rb_define_const(mSSL, "OP_CLEANSE_PLAINTEXT", ULONG2NUM(SSL_OP_CLEANSE_PLAINTEXT));
2989
+ #endif
2990
+ rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
2991
+ #ifdef SSL_OP_ENABLE_KTLS /* OpenSSL 3.0 */
2992
+ rb_define_const(mSSL, "OP_ENABLE_KTLS", ULONG2NUM(SSL_OP_ENABLE_KTLS));
2993
+ #endif
2994
+ rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
2995
+ rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG));
2996
+ #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* OpenSSL 3.0 */
2997
+ rb_define_const(mSSL, "OP_IGNORE_UNEXPECTED_EOF", ULONG2NUM(SSL_OP_IGNORE_UNEXPECTED_EOF));
2998
+ #endif
2999
+ #ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION /* OpenSSL 3.0 */
3000
+ rb_define_const(mSSL, "OP_ALLOW_CLIENT_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_CLIENT_RENEGOTIATION));
3001
+ #endif
3002
+ #ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */
3003
+ rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES));
3004
+ #endif
3005
+ #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
3006
+ rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
3007
+ #endif
3008
+ rb_define_const(mSSL, "OP_DONT_INSERT_EMPTY_FRAGMENTS", ULONG2NUM(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
3009
+ rb_define_const(mSSL, "OP_NO_TICKET", ULONG2NUM(SSL_OP_NO_TICKET));
3010
+ rb_define_const(mSSL, "OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION));
3011
+ rb_define_const(mSSL, "OP_NO_COMPRESSION", ULONG2NUM(SSL_OP_NO_COMPRESSION));
3012
+ rb_define_const(mSSL, "OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
3013
+ #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
3014
+ rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
3015
+ #endif
3016
+ #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */
3017
+ rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT));
3018
+ #endif
3019
+ #ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */
3020
+ rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA));
3021
+ #endif
3022
+ #ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */
3023
+ rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY));
3024
+ #endif
3025
+ rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
3026
+ rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
3027
+ rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
3028
+ rb_define_const(mSSL, "OP_NO_TLSv1_2", ULONG2NUM(SSL_OP_NO_TLSv1_2));
3029
+ #ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
3030
+ rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
3031
+ #endif
3032
+ rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
3033
+ rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
3034
+ #ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
3035
+ rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
3036
+ #endif
3037
+ rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
3038
+
3039
+ /* SSL_OP_* flags for DTLS */
3040
+ #if 0
3041
+ rb_define_const(mSSL, "OP_NO_QUERY_MTU", ULONG2NUM(SSL_OP_NO_QUERY_MTU));
3042
+ rb_define_const(mSSL, "OP_COOKIE_EXCHANGE", ULONG2NUM(SSL_OP_COOKIE_EXCHANGE));
3043
+ rb_define_const(mSSL, "OP_CISCO_ANYCONNECT", ULONG2NUM(SSL_OP_CISCO_ANYCONNECT));
3044
+ #endif
3045
+
3046
+ /* Deprecated in OpenSSL 1.1.0. */
3047
+ rb_define_const(mSSL, "OP_MICROSOFT_SESS_ID_BUG", ULONG2NUM(SSL_OP_MICROSOFT_SESS_ID_BUG));
3048
+ /* Deprecated in OpenSSL 1.1.0. */
3049
+ rb_define_const(mSSL, "OP_NETSCAPE_CHALLENGE_BUG", ULONG2NUM(SSL_OP_NETSCAPE_CHALLENGE_BUG));
3050
+ /* Deprecated in OpenSSL 0.9.8q and 1.0.0c. */
3051
+ rb_define_const(mSSL, "OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", ULONG2NUM(SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG));
3052
+ /* Deprecated in OpenSSL 1.0.1h and 1.0.2. */
3053
+ rb_define_const(mSSL, "OP_SSLREF2_REUSE_CERT_TYPE_BUG", ULONG2NUM(SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG));
3054
+ /* Deprecated in OpenSSL 1.1.0. */
3055
+ rb_define_const(mSSL, "OP_MICROSOFT_BIG_SSLV3_BUFFER", ULONG2NUM(SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER));
3056
+ /* Deprecated in OpenSSL 0.9.7h and 0.9.8b. */
3057
+ rb_define_const(mSSL, "OP_MSIE_SSLV2_RSA_PADDING", ULONG2NUM(SSL_OP_MSIE_SSLV2_RSA_PADDING));
3058
+ /* Deprecated in OpenSSL 1.1.0. */
3059
+ rb_define_const(mSSL, "OP_SSLEAY_080_CLIENT_DH_BUG", ULONG2NUM(SSL_OP_SSLEAY_080_CLIENT_DH_BUG));
3060
+ /* Deprecated in OpenSSL 1.1.0. */
3061
+ rb_define_const(mSSL, "OP_TLS_D5_BUG", ULONG2NUM(SSL_OP_TLS_D5_BUG));
3062
+ /* Deprecated in OpenSSL 1.1.0. */
3063
+ rb_define_const(mSSL, "OP_TLS_BLOCK_PADDING_BUG", ULONG2NUM(SSL_OP_TLS_BLOCK_PADDING_BUG));
3064
+ /* Deprecated in OpenSSL 1.1.0. */
3065
+ rb_define_const(mSSL, "OP_SINGLE_ECDH_USE", ULONG2NUM(SSL_OP_SINGLE_ECDH_USE));
3066
+ /* Deprecated in OpenSSL 1.1.0. */
3067
+ rb_define_const(mSSL, "OP_SINGLE_DH_USE", ULONG2NUM(SSL_OP_SINGLE_DH_USE));
3068
+ /* Deprecated in OpenSSL 1.0.1k and 1.0.2. */
3069
+ rb_define_const(mSSL, "OP_EPHEMERAL_RSA", ULONG2NUM(SSL_OP_EPHEMERAL_RSA));
3070
+ /* Deprecated in OpenSSL 1.1.0. */
3071
+ rb_define_const(mSSL, "OP_NO_SSLv2", ULONG2NUM(SSL_OP_NO_SSLv2));
3072
+ /* Deprecated in OpenSSL 1.0.1. */
3073
+ rb_define_const(mSSL, "OP_PKCS1_CHECK_1", ULONG2NUM(SSL_OP_PKCS1_CHECK_1));
3074
+ /* Deprecated in OpenSSL 1.0.1. */
3075
+ rb_define_const(mSSL, "OP_PKCS1_CHECK_2", ULONG2NUM(SSL_OP_PKCS1_CHECK_2));
3076
+ /* Deprecated in OpenSSL 1.1.0. */
3077
+ rb_define_const(mSSL, "OP_NETSCAPE_CA_DN_BUG", ULONG2NUM(SSL_OP_NETSCAPE_CA_DN_BUG));
3078
+ /* Deprecated in OpenSSL 1.1.0. */
3079
+ rb_define_const(mSSL, "OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", ULONG2NUM(SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG));
3080
+
3081
+
3082
+ /*
3083
+ * SSL/TLS version constants. Used by SSLContext#min_version= and
3084
+ * #max_version=
3085
+ */
3086
+ /* SSL 2.0 */
3087
+ rb_define_const(mSSL, "SSL2_VERSION", INT2NUM(SSL2_VERSION));
3088
+ /* SSL 3.0 */
3089
+ rb_define_const(mSSL, "SSL3_VERSION", INT2NUM(SSL3_VERSION));
3090
+ /* TLS 1.0 */
3091
+ rb_define_const(mSSL, "TLS1_VERSION", INT2NUM(TLS1_VERSION));
3092
+ /* TLS 1.1 */
3093
+ rb_define_const(mSSL, "TLS1_1_VERSION", INT2NUM(TLS1_1_VERSION));
3094
+ /* TLS 1.2 */
3095
+ rb_define_const(mSSL, "TLS1_2_VERSION", INT2NUM(TLS1_2_VERSION));
3096
+ #ifdef TLS1_3_VERSION /* OpenSSL 1.1.1 */
3097
+ /* TLS 1.3 */
3098
+ rb_define_const(mSSL, "TLS1_3_VERSION", INT2NUM(TLS1_3_VERSION));
3099
+ #endif
3100
+
3101
+
3102
+ sym_exception = ID2SYM(rb_intern_const("exception"));
3103
+ sym_wait_readable = ID2SYM(rb_intern_const("wait_readable"));
3104
+ sym_wait_writable = ID2SYM(rb_intern_const("wait_writable"));
3105
+
3106
+ id_tmp_dh_callback = rb_intern_const("tmp_dh_callback");
3107
+ id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded");
3108
+ id_each = rb_intern_const("each");
3109
+
3110
+ #define DefIVarID(name) do \
3111
+ id_i_##name = rb_intern_const("@"#name); while (0)
3112
+
3113
+ DefIVarID(cert_store);
3114
+ DefIVarID(ca_file);
3115
+ DefIVarID(ca_path);
3116
+ DefIVarID(verify_mode);
3117
+ DefIVarID(verify_depth);
3118
+ DefIVarID(verify_callback);
3119
+ DefIVarID(client_ca);
3120
+ DefIVarID(renegotiation_cb);
3121
+ DefIVarID(cert);
3122
+ DefIVarID(key);
3123
+ DefIVarID(extra_chain_cert);
3124
+ DefIVarID(client_cert_cb);
3125
+ DefIVarID(timeout);
3126
+ DefIVarID(session_id_context);
3127
+ DefIVarID(session_get_cb);
3128
+ DefIVarID(session_new_cb);
3129
+ DefIVarID(session_remove_cb);
3130
+ DefIVarID(npn_select_cb);
3131
+ DefIVarID(npn_protocols);
3132
+ DefIVarID(alpn_protocols);
3133
+ DefIVarID(alpn_select_cb);
3134
+ DefIVarID(servername_cb);
3135
+ DefIVarID(verify_hostname);
3136
+ DefIVarID(keylog_cb);
3137
+
3138
+ DefIVarID(io);
3139
+ DefIVarID(context);
3140
+ DefIVarID(hostname);
3141
+ #endif /* !defined(OPENSSL_NO_SOCK) */
3142
+ }