openssl-custom 2.2.2

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