Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

ossl_ssl.c
Go to the documentation of this file.
1 /*
2 * $Id: ossl_ssl.c 40387 2013-04-19 17:16:37Z nagachika $
3 * 'OpenSSL for Ruby' project
4 * Copyright (C) 2000-2002 GOTOU Yuuzou <gotoyuzo@notwork.org>
5 * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
6 * Copyright (C) 2001-2007 Technorama Ltd. <oss-ruby@technorama.net>
7 * All rights reserved.
8 */
9 /*
10 * This program is licenced under the same licence as Ruby.
11 * (See the file 'LICENCE'.)
12 */
13 #include "ossl.h"
14
15 #if defined(HAVE_UNISTD_H)
16 # include <unistd.h> /* for read(), and write() */
17 #endif
18
19 #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
20
21 #ifdef _WIN32
22 # define TO_SOCKET(s) _get_osfhandle(s)
23 #else
24 # define TO_SOCKET(s) (s)
25 #endif
26
27 VALUE mSSL;
28 VALUE eSSLError;
29 VALUE cSSLContext;
30 VALUE cSSLSocket;
31
32 #define ossl_sslctx_set_cert(o,v) rb_iv_set((o),"@cert",(v))
33 #define ossl_sslctx_set_key(o,v) rb_iv_set((o),"@key",(v))
34 #define ossl_sslctx_set_client_ca(o,v) rb_iv_set((o),"@client_ca",(v))
35 #define ossl_sslctx_set_ca_file(o,v) rb_iv_set((o),"@ca_file",(v))
36 #define ossl_sslctx_set_ca_path(o,v) rb_iv_set((o),"@ca_path",(v))
37 #define ossl_sslctx_set_timeout(o,v) rb_iv_set((o),"@timeout",(v))
38 #define ossl_sslctx_set_verify_mode(o,v) rb_iv_set((o),"@verify_mode",(v))
39 #define ossl_sslctx_set_verify_dep(o,v) rb_iv_set((o),"@verify_depth",(v))
40 #define ossl_sslctx_set_verify_cb(o,v) rb_iv_set((o),"@verify_callback",(v))
41 #define ossl_sslctx_set_options(o,v) rb_iv_set((o),"@options",(v))
42 #define ossl_sslctx_set_cert_store(o,v) rb_iv_set((o),"@cert_store",(v))
43 #define ossl_sslctx_set_extra_cert(o,v) rb_iv_set((o),"@extra_chain_cert",(v))
44 #define ossl_sslctx_set_client_cert_cb(o,v) rb_iv_set((o),"@client_cert_cb",(v))
45 #define ossl_sslctx_set_tmp_dh_cb(o,v) rb_iv_set((o),"@tmp_dh_callback",(v))
46 #define ossl_sslctx_set_sess_id_ctx(o, v) rb_iv_set((o),"@session_id_context",(v))
47
48 #define ossl_sslctx_get_cert(o) rb_iv_get((o),"@cert")
49 #define ossl_sslctx_get_key(o) rb_iv_get((o),"@key")
50 #define ossl_sslctx_get_client_ca(o) rb_iv_get((o),"@client_ca")
51 #define ossl_sslctx_get_ca_file(o) rb_iv_get((o),"@ca_file")
52 #define ossl_sslctx_get_ca_path(o) rb_iv_get((o),"@ca_path")
53 #define ossl_sslctx_get_timeout(o) rb_iv_get((o),"@timeout")
54 #define ossl_sslctx_get_verify_mode(o) rb_iv_get((o),"@verify_mode")
55 #define ossl_sslctx_get_verify_dep(o) rb_iv_get((o),"@verify_depth")
56 #define ossl_sslctx_get_verify_cb(o) rb_iv_get((o),"@verify_callback")
57 #define ossl_sslctx_get_options(o) rb_iv_get((o),"@options")
58 #define ossl_sslctx_get_cert_store(o) rb_iv_get((o),"@cert_store")
59 #define ossl_sslctx_get_extra_cert(o) rb_iv_get((o),"@extra_chain_cert")
60 #define ossl_sslctx_get_client_cert_cb(o) rb_iv_get((o),"@client_cert_cb")
61 #define ossl_sslctx_get_tmp_dh_cb(o) rb_iv_get((o),"@tmp_dh_callback")
62 #define ossl_sslctx_get_sess_id_ctx(o) rb_iv_get((o),"@session_id_context")
63
64 static const char *ossl_sslctx_attrs[] = {
65 "cert", "key", "client_ca", "ca_file", "ca_path",
66 "timeout", "verify_mode", "verify_depth", "renegotiation_cb",
67 "verify_callback", "options", "cert_store", "extra_chain_cert",
68 "client_cert_cb", "tmp_dh_callback", "session_id_context",
69 "session_get_cb", "session_new_cb", "session_remove_cb",
70 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
71 "servername_cb",
72 #endif
73 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
74 "npn_protocols",
75 "npn_select_cb",
76 #endif
77 };
78
79 #define ossl_ssl_get_io(o) rb_iv_get((o),"@io")
80 #define ossl_ssl_get_ctx(o) rb_iv_get((o),"@context")
81 #define ossl_ssl_get_sync_close(o) rb_iv_get((o),"@sync_close")
82 #define ossl_ssl_get_x509(o) rb_iv_get((o),"@x509")
83 #define ossl_ssl_get_key(o) rb_iv_get((o),"@key")
84 #define ossl_ssl_get_tmp_dh(o) rb_iv_get((o),"@tmp_dh")
85
86 #define ossl_ssl_set_io(o,v) rb_iv_set((o),"@io",(v))
87 #define ossl_ssl_set_ctx(o,v) rb_iv_set((o),"@context",(v))
88 #define ossl_ssl_set_sync_close(o,v) rb_iv_set((o),"@sync_close",(v))
89 #define ossl_ssl_set_x509(o,v) rb_iv_set((o),"@x509",(v))
90 #define ossl_ssl_set_key(o,v) rb_iv_set((o),"@key",(v))
91 #define ossl_ssl_set_tmp_dh(o,v) rb_iv_set((o),"@tmp_dh",(v))
92
93 static const char *ossl_ssl_attr_readers[] = { "io", "context", };
94 static const char *ossl_ssl_attrs[] = {
95 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
96 "hostname",
97 #endif
98 "sync_close",
99 };
100
101 ID ID_callback_state;
102
103 /*
104 * SSLContext class
105 */
106 struct {
107 const char *name;
108 SSL_METHOD *(*func)(void);
109 } ossl_ssl_method_tab[] = {
110 #define OSSL_SSL_METHOD_ENTRY(name) { #name, (SSL_METHOD *(*)(void))name##_method }
111 OSSL_SSL_METHOD_ENTRY(TLSv1),
112 OSSL_SSL_METHOD_ENTRY(TLSv1_server),
113 OSSL_SSL_METHOD_ENTRY(TLSv1_client),
114 #if defined(HAVE_TLSV1_2_METHOD) && defined(HAVE_TLSV1_2_SERVER_METHOD) && \
115 defined(HAVE_TLSV1_2_CLIENT_METHOD)
116 OSSL_SSL_METHOD_ENTRY(TLSv1_2),
117 OSSL_SSL_METHOD_ENTRY(TLSv1_2_server),
118 OSSL_SSL_METHOD_ENTRY(TLSv1_2_client),
119 #endif
120 #if defined(HAVE_TLSV1_1_METHOD) && defined(HAVE_TLSV1_1_SERVER_METHOD) && \
121 defined(HAVE_TLSV1_1_CLIENT_METHOD)
122 OSSL_SSL_METHOD_ENTRY(TLSv1_1),
123 OSSL_SSL_METHOD_ENTRY(TLSv1_1_server),
124 OSSL_SSL_METHOD_ENTRY(TLSv1_1_client),
125 #endif
126 #if defined(HAVE_SSLV2_METHOD) && defined(HAVE_SSLV2_SERVER_METHOD) && \
127 defined(HAVE_SSLV2_CLIENT_METHOD)
128 OSSL_SSL_METHOD_ENTRY(SSLv2),
129 OSSL_SSL_METHOD_ENTRY(SSLv2_server),
130 OSSL_SSL_METHOD_ENTRY(SSLv2_client),
131 #endif
132 OSSL_SSL_METHOD_ENTRY(SSLv3),
133 OSSL_SSL_METHOD_ENTRY(SSLv3_server),
134 OSSL_SSL_METHOD_ENTRY(SSLv3_client),
135 OSSL_SSL_METHOD_ENTRY(SSLv23),
136 OSSL_SSL_METHOD_ENTRY(SSLv23_server),
137 OSSL_SSL_METHOD_ENTRY(SSLv23_client),
138 #undef OSSL_SSL_METHOD_ENTRY
139 };
140
141 int ossl_ssl_ex_vcb_idx;
142 int ossl_ssl_ex_store_p;
143 int ossl_ssl_ex_ptr_idx;
144 int ossl_ssl_ex_client_cert_cb_idx;
145 int ossl_ssl_ex_tmp_dh_callback_idx;
146
147 static void
148 ossl_sslctx_free(SSL_CTX *ctx)
149 {
150 if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1)
151 ctx->cert_store = NULL;
152 SSL_CTX_free(ctx);
153 }
154
155 static VALUE
156 ossl_sslctx_s_alloc(VALUE klass)
157 {
158 SSL_CTX *ctx;
159 long mode = SSL_MODE_ENABLE_PARTIAL_WRITE;
160
161 #ifdef SSL_MODE_RELEASE_BUFFERS
162 mode |= SSL_MODE_RELEASE_BUFFERS;
163 #endif
164
165 ctx = SSL_CTX_new(SSLv23_method());
166 if (!ctx) {
167 ossl_raise(eSSLError, "SSL_CTX_new");
168 }
169 SSL_CTX_set_mode(ctx, mode);
170 return Data_Wrap_Struct(klass, 0, ossl_sslctx_free, ctx);
171 }
172
173 /*
174 * call-seq:
175 * ctx.ssl_version = :TLSv1
176 * ctx.ssl_version = "SSLv23_client"
177 *
178 * You can get a list of valid versions with OpenSSL::SSL::SSLContext::METHODS
179 */
180 static VALUE
181 ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
182 {
183 SSL_METHOD *method = NULL;
184 const char *s;
185 int i;
186
187 SSL_CTX *ctx;
188 if(TYPE(ssl_method) == T_SYMBOL)
189 s = rb_id2name(SYM2ID(ssl_method));
190 else
191 s = StringValuePtr(ssl_method);
192 for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
193 if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) {
194 method = ossl_ssl_method_tab[i].func();
195 break;
196 }
197 }
198 if (!method) {
199 ossl_raise(rb_eArgError, "unknown SSL method `%s'.", s);
200 }
201 Data_Get_Struct(self, SSL_CTX, ctx);
202 if (SSL_CTX_set_ssl_version(ctx, method) != 1) {
203 ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");
204 }
205
206 return ssl_method;
207 }
208
209 /*
210 * call-seq:
211 * SSLContext.new => ctx
212 * SSLContext.new(:TLSv1) => ctx
213 * SSLContext.new("SSLv23_client") => ctx
214 *
215 * You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS
216 */
217 static VALUE
218 ossl_sslctx_initialize(int argc, VALUE *argv, VALUE self)
219 {
220 VALUE ssl_method;
221 int i;
222
223 for(i = 0; i < numberof(ossl_sslctx_attrs); i++){
224 char buf[32];
225 snprintf(buf, sizeof(buf), "@%s", ossl_sslctx_attrs[i]);
226 rb_iv_set(self, buf, Qnil);
227 }
228 if (rb_scan_args(argc, argv, "01", &ssl_method) == 0){
229 return self;
230 }
231 ossl_sslctx_set_ssl_version(self, ssl_method);
232
233 return self;
234 }
235
236 static VALUE
237 ossl_call_client_cert_cb(VALUE obj)
238 {
239 VALUE cb, ary, cert, key;
240 SSL *ssl;
241
242 Data_Get_Struct(obj, SSL, ssl);
243 cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx);
244 if (NIL_P(cb)) return Qfalse;
245 ary = rb_funcall(cb, rb_intern("call"), 1, obj);
246 Check_Type(ary, T_ARRAY);
247 GetX509CertPtr(cert = rb_ary_entry(ary, 0));
248 GetPKeyPtr(key = rb_ary_entry(ary, 1));
249 ossl_ssl_set_x509(obj, cert);
250 ossl_ssl_set_key(obj, key);
251
252 return Qtrue;
253 }
254
255 static int
256 ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
257 {
258 VALUE obj, success;
259
260 obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
261 success = rb_protect((VALUE(*)_((VALUE)))ossl_call_client_cert_cb,
262 obj, NULL);
263 if (!RTEST(success)) return 0;
264 *x509 = DupX509CertPtr(ossl_ssl_get_x509(obj));
265 *pkey = DupPKeyPtr(ossl_ssl_get_key(obj));
266
267 return 1;
268 }
269
270 #if !defined(OPENSSL_NO_DH)
271 static VALUE
272 ossl_call_tmp_dh_callback(VALUE *args)
273 {
274 SSL *ssl;
275 VALUE cb, dh;
276 EVP_PKEY *pkey;
277
278 Data_Get_Struct(args[0], SSL, ssl);
279 cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx);
280 if (NIL_P(cb)) return Qfalse;
281 dh = rb_funcall(cb, rb_intern("call"), 3, args[0], args[1], args[2]);
282 pkey = GetPKeyPtr(dh);
283 if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) return Qfalse;
284 ossl_ssl_set_tmp_dh(args[0], dh);
285
286 return Qtrue;
287 }
288
289 static DH*
290 ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
291 {
292 VALUE args[3], success;
293
294 args[0] = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
295 args[1] = INT2FIX(is_export);
296 args[2] = INT2FIX(keylength);
297 success = rb_protect((VALUE(*)_((VALUE)))ossl_call_tmp_dh_callback,
298 (VALUE)args, NULL);
299 if (!RTEST(success)) return NULL;
300
301 return GetPKeyPtr(ossl_ssl_get_tmp_dh(args[0]))->pkey.dh;
302 }
303
304 static DH*
305 ossl_default_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
306 {
307 rb_warning("using default DH parameters.");
308
309 switch(keylength){
310 case 512:
311 return OSSL_DEFAULT_DH_512;
312 case 1024:
313 return OSSL_DEFAULT_DH_1024;
314 }
315 return NULL;
316 }
317 #endif /* OPENSSL_NO_DH */
318
319 static int
320 ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
321 {
322 VALUE cb;
323 SSL *ssl;
324
325 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
326 cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx);
327 X509_STORE_CTX_set_ex_data(ctx, ossl_verify_cb_idx, (void*)cb);
328 return ossl_verify_cb(preverify_ok, ctx);
329 }
330
331 static VALUE
332 ossl_call_session_get_cb(VALUE ary)
333 {
334 VALUE ssl_obj, sslctx_obj, cb;
335
336 Check_Type(ary, T_ARRAY);
337 ssl_obj = rb_ary_entry(ary, 0);
338
339 sslctx_obj = rb_iv_get(ssl_obj, "@context");
340 if (NIL_P(sslctx_obj)) return Qnil;
341 cb = rb_iv_get(sslctx_obj, "@session_get_cb");
342 if (NIL_P(cb)) return Qnil;
343
344 return rb_funcall(cb, rb_intern("call"), 1, ary);
345 }
346
347 /* this method is currently only called for servers (in OpenSSL <= 0.9.8e) */
348 static SSL_SESSION *
349 ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
350 {
351 VALUE ary, ssl_obj, ret_obj;
352 SSL_SESSION *sess;
353 void *ptr;
354 int state = 0;
355
356 OSSL_Debug("SSL SESSION get callback entered");
357 if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
358 return NULL;
359 ssl_obj = (VALUE)ptr;
360 ary = rb_ary_new2(2);
361 rb_ary_push(ary, ssl_obj);
362 rb_ary_push(ary, rb_str_new((const char *)buf, len));
363
364 ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_get_cb, ary, &state);
365 if (state) {
366 rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
367 return NULL;
368 }
369 if (!rb_obj_is_instance_of(ret_obj, cSSLSession))
370 return NULL;
371
372 SafeGetSSLSession(ret_obj, sess);
373 *copy = 1;
374
375 return sess;
376 }
377
378 static VALUE
379 ossl_call_session_new_cb(VALUE ary)
380 {
381 VALUE ssl_obj, sslctx_obj, cb;
382
383 Check_Type(ary, T_ARRAY);
384 ssl_obj = rb_ary_entry(ary, 0);
385
386 sslctx_obj = rb_iv_get(ssl_obj, "@context");
387 if (NIL_P(sslctx_obj)) return Qnil;
388 cb = rb_iv_get(sslctx_obj, "@session_new_cb");
389 if (NIL_P(cb)) return Qnil;
390
391 return rb_funcall(cb, rb_intern("call"), 1, ary);
392 }
393
394 /* return 1 normal. return 0 removes the session */
395 static int
396 ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
397 {
398 VALUE ary, ssl_obj, sess_obj;
399 void *ptr;
400 int state = 0;
401
402 OSSL_Debug("SSL SESSION new callback entered");
403
404 if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
405 return 1;
406 ssl_obj = (VALUE)ptr;
407 sess_obj = rb_obj_alloc(cSSLSession);
408 CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION);
409 DATA_PTR(sess_obj) = sess;
410
411 ary = rb_ary_new2(2);
412 rb_ary_push(ary, ssl_obj);
413 rb_ary_push(ary, sess_obj);
414
415 rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state);
416 if (state) {
417 rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
418 }
419
420 /*
421 * return 0 which means to OpenSSL that the the session is still
422 * valid (since we created Ruby Session object) and was not freed by us
423 * with SSL_SESSION_free(). Call SSLContext#remove_session(sess) in
424 * session_get_cb block if you don't want OpenSSL to cache the session
425 * internally.
426 */
427 return 0;
428 }
429
430 static VALUE
431 ossl_call_session_remove_cb(VALUE ary)
432 {
433 VALUE sslctx_obj, cb;
434
435 Check_Type(ary, T_ARRAY);
436 sslctx_obj = rb_ary_entry(ary, 0);
437
438 cb = rb_iv_get(sslctx_obj, "@session_remove_cb");
439 if (NIL_P(cb)) return Qnil;
440
441 return rb_funcall(cb, rb_intern("call"), 1, ary);
442 }
443
444 static void
445 ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
446 {
447 VALUE ary, sslctx_obj, sess_obj;
448 void *ptr;
449 int state = 0;
450
451 OSSL_Debug("SSL SESSION remove callback entered");
452
453 if ((ptr = SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx)) == NULL)
454 return;
455 sslctx_obj = (VALUE)ptr;
456 sess_obj = rb_obj_alloc(cSSLSession);
457 CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION);
458 DATA_PTR(sess_obj) = sess;
459
460 ary = rb_ary_new2(2);
461 rb_ary_push(ary, sslctx_obj);
462 rb_ary_push(ary, sess_obj);
463
464 rb_protect((VALUE(*)_((VALUE)))ossl_call_session_remove_cb, ary, &state);
465 if (state) {
466 /*
467 the SSL_CTX is frozen, nowhere to save state.
468 there is no common accessor method to check it either.
469 rb_ivar_set(sslctx_obj, ID_callback_state, INT2NUM(state));
470 */
471 }
472 }
473
474 static VALUE
475 ossl_sslctx_add_extra_chain_cert_i(VALUE i, VALUE arg)
476 {
477 X509 *x509;
478 SSL_CTX *ctx;
479
480 Data_Get_Struct(arg, SSL_CTX, ctx);
481 x509 = DupX509CertPtr(i);
482 if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){
483 ossl_raise(eSSLError, NULL);
484 }
485
486 return i;
487 }
488
489 static VALUE ossl_sslctx_setup(VALUE self);
490
491 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
492 static VALUE
493 ossl_call_servername_cb(VALUE ary)
494 {
495 VALUE ssl_obj, sslctx_obj, cb, ret_obj;
496
497 Check_Type(ary, T_ARRAY);
498 ssl_obj = rb_ary_entry(ary, 0);
499
500 sslctx_obj = rb_iv_get(ssl_obj, "@context");
501 if (NIL_P(sslctx_obj)) return Qnil;
502 cb = rb_iv_get(sslctx_obj, "@servername_cb");
503 if (NIL_P(cb)) return Qnil;
504
505 ret_obj = rb_funcall(cb, rb_intern("call"), 1, ary);
506 if (rb_obj_is_kind_of(ret_obj, cSSLContext)) {
507 SSL *ssl;
508 SSL_CTX *ctx2;
509
510 ossl_sslctx_setup(ret_obj);
511 Data_Get_Struct(ssl_obj, SSL, ssl);
512 Data_Get_Struct(ret_obj, SSL_CTX, ctx2);
513 SSL_set_SSL_CTX(ssl, ctx2);
514 } else if (!NIL_P(ret_obj)) {
515 ossl_raise(rb_eArgError, "servername_cb must return an OpenSSL::SSL::SSLContext object or nil");
516 }
517
518 return ret_obj;
519 }
520
521 static int
522 ssl_servername_cb(SSL *ssl, int *ad, void *arg)
523 {
524 VALUE ary, ssl_obj;
525 void *ptr;
526 int state = 0;
527 const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
528
529 if (!servername)
530 return SSL_TLSEXT_ERR_OK;
531
532 if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
533 return SSL_TLSEXT_ERR_ALERT_FATAL;
534 ssl_obj = (VALUE)ptr;
535 ary = rb_ary_new2(2);
536 rb_ary_push(ary, ssl_obj);
537 rb_ary_push(ary, rb_str_new2(servername));
538
539 rb_protect((VALUE(*)_((VALUE)))ossl_call_servername_cb, ary, &state);
540 if (state) {
541 rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
542 return SSL_TLSEXT_ERR_ALERT_FATAL;
543 }
544
545 return SSL_TLSEXT_ERR_OK;
546 }
547 #endif
548
549 static void
550 ssl_renegotiation_cb(const SSL *ssl)
551 {
552 VALUE ssl_obj, sslctx_obj, cb;
553 void *ptr;
554
555 if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
556 ossl_raise(eSSLError, "SSL object could not be retrieved");
557 ssl_obj = (VALUE)ptr;
558
559 sslctx_obj = rb_iv_get(ssl_obj, "@context");
560 if (NIL_P(sslctx_obj)) return;
561 cb = rb_iv_get(sslctx_obj, "@renegotiation_cb");
562 if (NIL_P(cb)) return;
563
564 (void) rb_funcall(cb, rb_intern("call"), 1, ssl_obj);
565 }
566
567 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
568 static VALUE
569 ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
570 {
571 int len = RSTRING_LENINT(cur);
572 char len_byte;
573 if (len < 1 || len > 255)
574 ossl_raise(eSSLError, "Advertised protocol must have length 1..255");
575 /* Encode the length byte */
576 len_byte = len;
577 rb_str_buf_cat(encoded, &len_byte, 1);
578 rb_str_buf_cat(encoded, RSTRING_PTR(cur), len);
579 return Qnil;
580 }
581
582 static void
583 ssl_npn_encode_protocols(VALUE sslctx, VALUE protocols)
584 {
585 VALUE encoded = rb_str_new2("");
586 rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded);
587 StringValueCStr(encoded);
588 rb_iv_set(sslctx, "@_protocols", encoded);
589 }
590
591 static int
592 ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg)
593 {
594 VALUE sslctx_obj = (VALUE) arg;
595 VALUE protocols = rb_iv_get(sslctx_obj, "@_protocols");
596
597 *out = (const unsigned char *) RSTRING_PTR(protocols);
598 *outlen = RSTRING_LENINT(protocols);
599
600 return SSL_TLSEXT_ERR_OK;
601 }
602
603 static int
604 ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
605 {
606 int i = 0;
607 VALUE sslctx_obj, cb, protocols, selected;
608
609 sslctx_obj = (VALUE) arg;
610 cb = rb_iv_get(sslctx_obj, "@npn_select_cb");
611 protocols = rb_ary_new();
612
613 /* The format is len_1|proto_1|...|len_n|proto_n\0 */
614 while (in[i]) {
615 VALUE protocol = rb_str_new((const char *) &in[i + 1], in[i]);
616 rb_ary_push(protocols, protocol);
617 i += in[i] + 1;
618 }
619
620 selected = rb_funcall(cb, rb_intern("call"), 1, protocols);
621 StringValue(selected);
622 *out = (unsigned char *) StringValuePtr(selected);
623 *outlen = RSTRING_LENINT(selected);
624
625 return SSL_TLSEXT_ERR_OK;
626 }
627 #endif
628
629 /* This function may serve as the entry point to support further
630 * callbacks. */
631 static void
632 ssl_info_cb(const SSL *ssl, int where, int val)
633 {
634 int state = SSL_state(ssl);
635
636 if ((where & SSL_CB_HANDSHAKE_START) &&
637 (state & SSL_ST_ACCEPT)) {
638 ssl_renegotiation_cb(ssl);
639 }
640 }
641
642 /*
643 * call-seq:
644 * ctx.setup => Qtrue # first time
645 * ctx.setup => nil # thereafter
646 *
647 * This method is called automatically when a new SSLSocket is created.
648 * Normally you do not need to call this method (unless you are writing an
649 * extension in C).
650 */
651 static VALUE
652 ossl_sslctx_setup(VALUE self)
653 {
654 SSL_CTX *ctx;
655 X509 *cert = NULL, *client_ca = NULL;
656 X509_STORE *store;
657 EVP_PKEY *key = NULL;
658 char *ca_path = NULL, *ca_file = NULL;
659 int i, verify_mode;
660 VALUE val;
661
662 if(OBJ_FROZEN(self)) return Qnil;
663 Data_Get_Struct(self, SSL_CTX, ctx);
664
665 #if !defined(OPENSSL_NO_DH)
666 if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){
667 SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
668 }
669 else{
670 SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback);
671 }
672 #endif
673 SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self);
674
675 val = ossl_sslctx_get_cert_store(self);
676 if(!NIL_P(val)){
677 /*
678 * WORKAROUND:
679 * X509_STORE can count references, but
680 * X509_STORE_free() doesn't care it.
681 * So we won't increment it but mark it by ex_data.
682 */
683 store = GetX509StorePtr(val); /* NO NEED TO DUP */
684 SSL_CTX_set_cert_store(ctx, store);
685 SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1);
686 }
687
688 val = ossl_sslctx_get_extra_cert(self);
689 if(!NIL_P(val)){
690 rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
691 }
692
693 /* private key may be bundled in certificate file. */
694 val = ossl_sslctx_get_cert(self);
695 cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
696 val = ossl_sslctx_get_key(self);
697 key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */
698 if (cert && key) {
699 if (!SSL_CTX_use_certificate(ctx, cert)) {
700 /* Adds a ref => Safe to FREE */
701 ossl_raise(eSSLError, "SSL_CTX_use_certificate");
702 }
703 if (!SSL_CTX_use_PrivateKey(ctx, key)) {
704 /* Adds a ref => Safe to FREE */
705 ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
706 }
707 if (!SSL_CTX_check_private_key(ctx)) {
708 ossl_raise(eSSLError, "SSL_CTX_check_private_key");
709 }
710 }
711
712 val = ossl_sslctx_get_client_ca(self);
713 if(!NIL_P(val)){
714 if(TYPE(val) == T_ARRAY){
715 for(i = 0; i < RARRAY_LEN(val); i++){
716 client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]);
717 if (!SSL_CTX_add_client_CA(ctx, client_ca)){
718 /* Copies X509_NAME => FREE it. */
719 ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
720 }
721 }
722 }
723 else{
724 client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
725 if (!SSL_CTX_add_client_CA(ctx, client_ca)){
726 /* Copies X509_NAME => FREE it. */
727 ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
728 }
729 }
730 }
731
732 val = ossl_sslctx_get_ca_file(self);
733 ca_file = NIL_P(val) ? NULL : StringValuePtr(val);
734 val = ossl_sslctx_get_ca_path(self);
735 ca_path = NIL_P(val) ? NULL : StringValuePtr(val);
736 if(ca_file || ca_path){
737 if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
738 rb_warning("can't set verify locations");
739 }
740
741 val = ossl_sslctx_get_verify_mode(self);
742 verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
743 SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
744 if (RTEST(ossl_sslctx_get_client_cert_cb(self)))
745 SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
746
747 val = ossl_sslctx_get_timeout(self);
748 if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));
749
750 val = ossl_sslctx_get_verify_dep(self);
751 if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
752
753 val = ossl_sslctx_get_options(self);
754 if(!NIL_P(val)) {
755 SSL_CTX_set_options(ctx, NUM2LONG(val));
756 } else {
757 SSL_CTX_set_options(ctx, SSL_OP_ALL);
758 }
759
760 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
761 val = rb_iv_get(self, "@npn_protocols");
762 if (!NIL_P(val)) {
763 ssl_npn_encode_protocols(self, val);
764 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *) self);
765 OSSL_Debug("SSL NPN advertise callback added");
766 }
767 if (RTEST(rb_iv_get(self, "@npn_select_cb"))) {
768 SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
769 OSSL_Debug("SSL NPN select callback added");
770 }
771 #endif
772
773 rb_obj_freeze(self);
774
775 val = ossl_sslctx_get_sess_id_ctx(self);
776 if (!NIL_P(val)){
777 StringValue(val);
778 if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
779 RSTRING_LENINT(val))){
780 ossl_raise(eSSLError, "SSL_CTX_set_session_id_context");
781 }
782 }
783
784 if (RTEST(rb_iv_get(self, "@session_get_cb"))) {
785 SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
786 OSSL_Debug("SSL SESSION get callback added");
787 }
788 if (RTEST(rb_iv_get(self, "@session_new_cb"))) {
789 SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
790 OSSL_Debug("SSL SESSION new callback added");
791 }
792 if (RTEST(rb_iv_get(self, "@session_remove_cb"))) {
793 SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
794 OSSL_Debug("SSL SESSION remove callback added");
795 }
796
797 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
798 val = rb_iv_get(self, "@servername_cb");
799 if (!NIL_P(val)) {
800 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
801 OSSL_Debug("SSL TLSEXT servername callback added");
802 }
803 #endif
804
805 return Qtrue;
806 }
807
808 static VALUE
809 ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher)
810 {
811 VALUE ary;
812 int bits, alg_bits;
813
814 ary = rb_ary_new2(4);
815 rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_name(cipher)));
816 rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_version(cipher)));
817 bits = SSL_CIPHER_get_bits(cipher, &alg_bits);
818 rb_ary_push(ary, INT2FIX(bits));
819 rb_ary_push(ary, INT2FIX(alg_bits));
820
821 return ary;
822 }
823
824 /*
825 * call-seq:
826 * ctx.ciphers => [[name, version, bits, alg_bits], ...]
827 *
828 * The list of ciphers configured for this context.
829 */
830 static VALUE
831 ossl_sslctx_get_ciphers(VALUE self)
832 {
833 SSL_CTX *ctx;
834 STACK_OF(SSL_CIPHER) *ciphers;
835 SSL_CIPHER *cipher;
836 VALUE ary;
837 int i, num;
838
839 Data_Get_Struct(self, SSL_CTX, ctx);
840 if(!ctx){
841 rb_warning("SSL_CTX is not initialized.");
842 return Qnil;
843 }
844 ciphers = ctx->cipher_list;
845
846 if (!ciphers)
847 return rb_ary_new();
848
849 num = sk_SSL_CIPHER_num(ciphers);
850 ary = rb_ary_new2(num);
851 for(i = 0; i < num; i++){
852 cipher = sk_SSL_CIPHER_value(ciphers, i);
853 rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher));
854 }
855 return ary;
856 }
857
858 /*
859 * call-seq:
860 * ctx.ciphers = "cipher1:cipher2:..."
861 * ctx.ciphers = [name, ...]
862 * ctx.ciphers = [[name, version, bits, alg_bits], ...]
863 *
864 * Sets the list of available ciphers for this context. Note in a server
865 * context some ciphers require the appropriate certificates. For example, an
866 * RSA cipher can only be chosen when an RSA certificate is available.
867 *
868 * See also OpenSSL::Cipher and OpenSSL::Cipher::ciphers
869 */
870 static VALUE
871 ossl_sslctx_set_ciphers(VALUE self, VALUE v)
872 {
873 SSL_CTX *ctx;
874 VALUE str, elem;
875 int i;
876
877 rb_check_frozen(self);
878 if (NIL_P(v))
879 return v;
880 else if (TYPE(v) == T_ARRAY) {
881 str = rb_str_new(0, 0);
882 for (i = 0; i < RARRAY_LEN(v); i++) {
883 elem = rb_ary_entry(v, i);
884 if (TYPE(elem) == T_ARRAY) elem = rb_ary_entry(elem, 0);
885 elem = rb_String(elem);
886 rb_str_append(str, elem);
887 if (i < RARRAY_LEN(v)-1) rb_str_cat2(str, ":");
888 }
889 } else {
890 str = v;
891 StringValue(str);
892 }
893
894 Data_Get_Struct(self, SSL_CTX, ctx);
895 if(!ctx){
896 ossl_raise(eSSLError, "SSL_CTX is not initialized.");
897 return Qnil;
898 }
899 if (!SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(str))) {
900 ossl_raise(eSSLError, "SSL_CTX_set_cipher_list");
901 }
902
903 return v;
904 }
905
906 /*
907 * call-seq:
908 * ctx.session_add(session) -> true | false
909 *
910 * Adds +session+ to the session cache
911 */
912 static VALUE
913 ossl_sslctx_session_add(VALUE self, VALUE arg)
914 {
915 SSL_CTX *ctx;
916 SSL_SESSION *sess;
917
918 Data_Get_Struct(self, SSL_CTX, ctx);
919 SafeGetSSLSession(arg, sess);
920
921 return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse;
922 }
923
924 /*
925 * call-seq:
926 * ctx.session_remove(session) -> true | false
927 *
928 * Removes +session+ from the session cache
929 */
930 static VALUE
931 ossl_sslctx_session_remove(VALUE self, VALUE arg)
932 {
933 SSL_CTX *ctx;
934 SSL_SESSION *sess;
935
936 Data_Get_Struct(self, SSL_CTX, ctx);
937 SafeGetSSLSession(arg, sess);
938
939 return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse;
940 }
941
942 /*
943 * call-seq:
944 * ctx.session_cache_mode -> Integer
945 *
946 * The current session cache mode.
947 */
948 static VALUE
949 ossl_sslctx_get_session_cache_mode(VALUE self)
950 {
951 SSL_CTX *ctx;
952
953 Data_Get_Struct(self, SSL_CTX, ctx);
954
955 return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx));
956 }
957
958 /*
959 * call-seq:
960 * ctx.session_cache_mode=(integer) -> Integer
961 *
962 * Sets the SSL session cache mode. Bitwise-or together the desired
963 * SESSION_CACHE_* constants to set. See SSL_CTX_set_session_cache_mode(3) for
964 * details.
965 */
966 static VALUE
967 ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg)
968 {
969 SSL_CTX *ctx;
970
971 Data_Get_Struct(self, SSL_CTX, ctx);
972
973 SSL_CTX_set_session_cache_mode(ctx, NUM2LONG(arg));
974
975 return arg;
976 }
977
978 /*
979 * call-seq:
980 * ctx.session_cache_size -> Integer
981 *
982 * Returns the current session cache size. Zero is used to represent an
983 * unlimited cache size.
984 */
985 static VALUE
986 ossl_sslctx_get_session_cache_size(VALUE self)
987 {
988 SSL_CTX *ctx;
989
990 Data_Get_Struct(self, SSL_CTX, ctx);
991
992 return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx));
993 }
994
995 /*
996 * call-seq:
997 * ctx.session_cache_size=(integer) -> Integer
998 *
999 * Sets the session cache size. Returns the previously valid session cache
1000 * size. Zero is used to represent an unlimited session cache size.
1001 */
1002 static VALUE
1003 ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg)
1004 {
1005 SSL_CTX *ctx;
1006
1007 Data_Get_Struct(self, SSL_CTX, ctx);
1008
1009 SSL_CTX_sess_set_cache_size(ctx, NUM2LONG(arg));
1010
1011 return arg;
1012 }
1013
1014 /*
1015 * call-seq:
1016 * ctx.session_cache_stats -> Hash
1017 *
1018 * Returns a Hash containing the following keys:
1019 *
1020 * :accept:: Number of started SSL/TLS handshakes in server mode
1021 * :accept_good:: Number of established SSL/TLS sessions in server mode
1022 * :accept_renegotiate:: Number of start renegotiations in server mode
1023 * :cache_full:: Number of sessions that were removed due to cache overflow
1024 * :cache_hits:: Number of successfully reused connections
1025 * :cache_misses:: Number of sessions proposed by clients that were not found
1026 * in the cache
1027 * :cache_num:: Number of sessions in the internal session cache
1028 * :cb_hits:: Number of sessions retrieved from the external cache in server
1029 * mode
1030 * :connect:: Number of started SSL/TLS handshakes in client mode
1031 * :connect_good:: Number of established SSL/TLS sessions in client mode
1032 * :connect_renegotiate:: Number of start renegotiations in client mode
1033 * :timeouts:: Number of sessions proposed by clients that were found in the
1034 * cache but had expired due to timeouts
1035 */
1036 static VALUE
1037 ossl_sslctx_get_session_cache_stats(VALUE self)
1038 {
1039 SSL_CTX *ctx;
1040 VALUE hash;
1041
1042 Data_Get_Struct(self, SSL_CTX, ctx);
1043
1044 hash = rb_hash_new();
1045 rb_hash_aset(hash, ID2SYM(rb_intern("cache_num")), LONG2NUM(SSL_CTX_sess_number(ctx)));
1046 rb_hash_aset(hash, ID2SYM(rb_intern("connect")), LONG2NUM(SSL_CTX_sess_connect(ctx)));
1047 rb_hash_aset(hash, ID2SYM(rb_intern("connect_good")), LONG2NUM(SSL_CTX_sess_connect_good(ctx)));
1048 rb_hash_aset(hash, ID2SYM(rb_intern("connect_renegotiate")), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx)));
1049 rb_hash_aset(hash, ID2SYM(rb_intern("accept")), LONG2NUM(SSL_CTX_sess_accept(ctx)));
1050 rb_hash_aset(hash, ID2SYM(rb_intern("accept_good")), LONG2NUM(SSL_CTX_sess_accept_good(ctx)));
1051 rb_hash_aset(hash, ID2SYM(rb_intern("accept_renegotiate")), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx)));
1052 rb_hash_aset(hash, ID2SYM(rb_intern("cache_hits")), LONG2NUM(SSL_CTX_sess_hits(ctx)));
1053 rb_hash_aset(hash, ID2SYM(rb_intern("cb_hits")), LONG2NUM(SSL_CTX_sess_cb_hits(ctx)));
1054 rb_hash_aset(hash, ID2SYM(rb_intern("cache_misses")), LONG2NUM(SSL_CTX_sess_misses(ctx)));
1055 rb_hash_aset(hash, ID2SYM(rb_intern("cache_full")), LONG2NUM(SSL_CTX_sess_cache_full(ctx)));
1056 rb_hash_aset(hash, ID2SYM(rb_intern("timeouts")), LONG2NUM(SSL_CTX_sess_timeouts(ctx)));
1057
1058 return hash;
1059 }
1060
1061
1062 /*
1063 * call-seq:
1064 * ctx.flush_sessions(time | nil) -> self
1065 *
1066 * Removes sessions in the internal cache that have expired at +time+.
1067 */
1068 static VALUE
1069 ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
1070 {
1071 VALUE arg1;
1072 SSL_CTX *ctx;
1073 time_t tm = 0;
1074
1075 rb_scan_args(argc, argv, "01", &arg1);
1076
1077 Data_Get_Struct(self, SSL_CTX, ctx);
1078
1079 if (NIL_P(arg1)) {
1080 tm = time(0);
1081 } else if (rb_obj_is_instance_of(arg1, rb_cTime)) {
1082 tm = NUM2LONG(rb_funcall(arg1, rb_intern("to_i"), 0));
1083 } else {
1084 ossl_raise(rb_eArgError, "arg must be Time or nil");
1085 }
1086
1087 SSL_CTX_flush_sessions(ctx, (long)tm);
1088
1089 return self;
1090 }
1091
1092 /*
1093 * SSLSocket class
1094 */
1095 static void
1096 ossl_ssl_shutdown(SSL *ssl)
1097 {
1098 int i, rc;
1099
1100 if (ssl) {
1101 /* 4 is from SSL_smart_shutdown() of mod_ssl.c (v2.2.19) */
1102 /* It says max 2x pending + 2x data = 4 */
1103 for (i = 0; i < 4; ++i) {
1104 /*
1105 * Ignore the case SSL_shutdown returns -1. Empty handshake_func
1106 * must not happen.
1107 */
1108 if (rc = SSL_shutdown(ssl))
1109 break;
1110 }
1111 SSL_clear(ssl);
1112 ERR_clear_error();
1113 }
1114 }
1115
1116 static void
1117 ossl_ssl_free(SSL *ssl)
1118 {
1119 SSL_free(ssl);
1120 }
1121
1122 static VALUE
1123 ossl_ssl_s_alloc(VALUE klass)
1124 {
1125 return Data_Wrap_Struct(klass, 0, ossl_ssl_free, NULL);
1126 }
1127
1128 /*
1129 * call-seq:
1130 * SSLSocket.new(io) => aSSLSocket
1131 * SSLSocket.new(io, ctx) => aSSLSocket
1132 *
1133 * Creates a new SSL socket from +io+ which must be a real ruby object (not an
1134 * IO-like object that responds to read/write.
1135 *
1136 * If +ctx+ is provided the SSL Sockets initial params will be taken from
1137 * the context.
1138 *
1139 * The OpenSSL::Buffering module provides additional IO methods.
1140 *
1141 * This method will freeze the SSLContext if one is provided;
1142 * however, session management is still allowed in the frozen SSLContext.
1143 */
1144 static VALUE
1145 ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1146 {
1147 VALUE io, ctx;
1148
1149 if (rb_scan_args(argc, argv, "11", &io, &ctx) == 1) {
1150 ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
1151 }
1152 OSSL_Check_Kind(ctx, cSSLContext);
1153 Check_Type(io, T_FILE);
1154 ossl_ssl_set_io(self, io);
1155 ossl_ssl_set_ctx(self, ctx);
1156 ossl_ssl_set_sync_close(self, Qfalse);
1157 ossl_sslctx_setup(ctx);
1158
1159 rb_iv_set(self, "@hostname", Qnil);
1160
1161 rb_call_super(0, 0);
1162
1163 return self;
1164 }
1165
1166 static VALUE
1167 ossl_ssl_setup(VALUE self)
1168 {
1169 VALUE io, v_ctx, cb;
1170 SSL_CTX *ctx;
1171 SSL *ssl;
1172 rb_io_t *fptr;
1173
1174 Data_Get_Struct(self, SSL, ssl);
1175 if(!ssl){
1176 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
1177 VALUE hostname = rb_iv_get(self, "@hostname");
1178 #endif
1179
1180 v_ctx = ossl_ssl_get_ctx(self);
1181 Data_Get_Struct(v_ctx, SSL_CTX, ctx);
1182
1183 ssl = SSL_new(ctx);
1184 if (!ssl) {
1185 ossl_raise(eSSLError, "SSL_new");
1186 }
1187 DATA_PTR(self) = ssl;
1188
1189 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
1190 if (!NIL_P(hostname)) {
1191 if (SSL_set_tlsext_host_name(ssl, StringValuePtr(hostname)) != 1)
1192 ossl_raise(eSSLError, "SSL_set_tlsext_host_name");
1193 }
1194 #endif
1195 io = ossl_ssl_get_io(self);
1196 GetOpenFile(io, fptr);
1197 rb_io_check_readable(fptr);
1198 rb_io_check_writable(fptr);
1199 SSL_set_fd(ssl, TO_SOCKET(FPTR_TO_FD(fptr)));
1200 SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void*)self);
1201 cb = ossl_sslctx_get_verify_cb(v_ctx);
1202 SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void*)cb);
1203 cb = ossl_sslctx_get_client_cert_cb(v_ctx);
1204 SSL_set_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx, (void*)cb);
1205 cb = ossl_sslctx_get_tmp_dh_cb(v_ctx);
1206 SSL_set_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx, (void*)cb);
1207 SSL_set_info_callback(ssl, ssl_info_cb);
1208 }
1209
1210 return Qtrue;
1211 }
1212
1213 #ifdef _WIN32
1214 #define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
1215 #else
1216 #define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret))
1217 #endif
1218
1219 #define ossl_ssl_data_get_struct(v, ssl) \
1220 do { \
1221 Data_Get_Struct((v), SSL, (ssl)); \
1222 if (!(ssl)) { \
1223 rb_warning("SSL session is not started yet."); \
1224 return Qnil; \
1225 } \
1226 } while (0)
1227
1228 static void
1229 write_would_block(int nonblock)
1230 {
1231 if (nonblock) {
1232 VALUE exc = ossl_exc_new(eSSLError, "write would block");
1233 rb_extend_object(exc, rb_mWaitWritable);
1234 rb_exc_raise(exc);
1235 }
1236 }
1237
1238 static void
1239 read_would_block(int nonblock)
1240 {
1241 if (nonblock) {
1242 VALUE exc = ossl_exc_new(eSSLError, "read would block");
1243 rb_extend_object(exc, rb_mWaitReadable);
1244 rb_exc_raise(exc);
1245 }
1246 }
1247
1248 static VALUE
1249 ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, int nonblock)
1250 {
1251 SSL *ssl;
1252 rb_io_t *fptr;
1253 int ret, ret2;
1254 VALUE cb_state;
1255
1256 rb_ivar_set(self, ID_callback_state, Qnil);
1257
1258 ossl_ssl_data_get_struct(self, ssl);
1259
1260 GetOpenFile(ossl_ssl_get_io(self), fptr);
1261 for(;;){
1262 ret = func(ssl);
1263
1264 cb_state = rb_ivar_get(self, ID_callback_state);
1265 if (!NIL_P(cb_state))
1266 rb_jump_tag(NUM2INT(cb_state));
1267
1268 if (ret > 0)
1269 break;
1270
1271 switch((ret2 = ssl_get_error(ssl, ret))){
1272 case SSL_ERROR_WANT_WRITE:
1273 write_would_block(nonblock);
1274 rb_io_wait_writable(FPTR_TO_FD(fptr));
1275 continue;
1276 case SSL_ERROR_WANT_READ:
1277 read_would_block(nonblock);
1278 rb_io_wait_readable(FPTR_TO_FD(fptr));
1279 continue;
1280 case SSL_ERROR_SYSCALL:
1281 if (errno) rb_sys_fail(funcname);
1282 ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1283 default:
1284 ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1285 }
1286 }
1287
1288 return self;
1289 }
1290
1291 /*
1292 * call-seq:
1293 * ssl.connect => self
1294 *
1295 * Initiates an SSL/TLS handshake with a server. The handshake may be started
1296 * after unencrypted data has been sent over the socket.
1297 */
1298 static VALUE
1299 ossl_ssl_connect(VALUE self)
1300 {
1301 ossl_ssl_setup(self);
1302 return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0);
1303 }
1304
1305 /*
1306 * call-seq:
1307 * ssl.connect_nonblock => self
1308 *
1309 * Initiates the SSL/TLS handshake as a client in non-blocking manner.
1310 *
1311 * # emulates blocking connect
1312 * begin
1313 * ssl.connect_nonblock
1314 * rescue IO::WaitReadable
1315 * IO.select([s2])
1316 * retry
1317 * rescue IO::WaitWritable
1318 * IO.select(nil, [s2])
1319 * retry
1320 * end
1321 *
1322 */
1323 static VALUE
1324 ossl_ssl_connect_nonblock(VALUE self)
1325 {
1326 ossl_ssl_setup(self);
1327 return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1);
1328 }
1329
1330 /*
1331 * call-seq:
1332 * ssl.accept => self
1333 *
1334 * Waits for a SSL/TLS client to initiate a handshake. The handshake may be
1335 * started after unencrypted data has been sent over the socket.
1336 */
1337 static VALUE
1338 ossl_ssl_accept(VALUE self)
1339 {
1340 ossl_ssl_setup(self);
1341 return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0);
1342 }
1343
1344 /*
1345 * call-seq:
1346 * ssl.accept_nonblock => self
1347 *
1348 * Initiates the SSL/TLS handshake as a server in non-blocking manner.
1349 *
1350 * # emulates blocking accept
1351 * begin
1352 * ssl.accept_nonblock
1353 * rescue IO::WaitReadable
1354 * IO.select([s2])
1355 * retry
1356 * rescue IO::WaitWritable
1357 * IO.select(nil, [s2])
1358 * retry
1359 * end
1360 *
1361 */
1362 static VALUE
1363 ossl_ssl_accept_nonblock(VALUE self)
1364 {
1365 ossl_ssl_setup(self);
1366 return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1);
1367 }
1368
1369 static VALUE
1370 ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1371 {
1372 SSL *ssl;
1373 int ilen, nread = 0;
1374 VALUE len, str;
1375 rb_io_t *fptr;
1376
1377 rb_scan_args(argc, argv, "11", &len, &str);
1378 ilen = NUM2INT(len);
1379 if(NIL_P(str)) str = rb_str_new(0, ilen);
1380 else{
1381 StringValue(str);
1382 rb_str_modify(str);
1383 rb_str_resize(str, ilen);
1384 }
1385 if(ilen == 0) return str;
1386
1387 Data_Get_Struct(self, SSL, ssl);
1388 GetOpenFile(ossl_ssl_get_io(self), fptr);
1389 if (ssl) {
1390 if(!nonblock && SSL_pending(ssl) <= 0)
1391 rb_thread_wait_fd(FPTR_TO_FD(fptr));
1392 for (;;){
1393 nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
1394 switch(ssl_get_error(ssl, nread)){
1395 case SSL_ERROR_NONE:
1396 goto end;
1397 case SSL_ERROR_ZERO_RETURN:
1398 rb_eof_error();
1399 case SSL_ERROR_WANT_WRITE:
1400 write_would_block(nonblock);
1401 rb_io_wait_writable(FPTR_TO_FD(fptr));
1402 continue;
1403 case SSL_ERROR_WANT_READ:
1404 read_would_block(nonblock);
1405 rb_io_wait_readable(FPTR_TO_FD(fptr));
1406 continue;
1407 case SSL_ERROR_SYSCALL:
1408 if(ERR_peek_error() == 0 && nread == 0) rb_eof_error();
1409 rb_sys_fail(0);
1410 default:
1411 ossl_raise(eSSLError, "SSL_read");
1412 }
1413 }
1414 }
1415 else {
1416 ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
1417 rb_warning("SSL session is not started yet.");
1418 return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str);
1419 }
1420
1421 end:
1422 rb_str_set_len(str, nread);
1423 OBJ_TAINT(str);
1424
1425 return str;
1426 }
1427
1428 /*
1429 * call-seq:
1430 * ssl.sysread(length) => string
1431 * ssl.sysread(length, buffer) => buffer
1432 *
1433 * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+
1434 * is provided the data will be written into it.
1435 */
1436 static VALUE
1437 ossl_ssl_read(int argc, VALUE *argv, VALUE self)
1438 {
1439 return ossl_ssl_read_internal(argc, argv, self, 0);
1440 }
1441
1442 /*
1443 * call-seq:
1444 * ssl.sysread_nonblock(length) => string
1445 * ssl.sysread_nonblock(length, buffer) => buffer
1446 *
1447 * A non-blocking version of #sysread. Raises an SSLError if reading would
1448 * block.
1449 *
1450 * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+
1451 * is provided the data will be written into it.
1452 */
1453 static VALUE
1454 ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
1455 {
1456 return ossl_ssl_read_internal(argc, argv, self, 1);
1457 }
1458
1459 static VALUE
1460 ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock)
1461 {
1462 SSL *ssl;
1463 int nwrite = 0;
1464 rb_io_t *fptr;
1465
1466 StringValue(str);
1467 Data_Get_Struct(self, SSL, ssl);
1468 GetOpenFile(ossl_ssl_get_io(self), fptr);
1469
1470 if (ssl) {
1471 for (;;){
1472 nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
1473 switch(ssl_get_error(ssl, nwrite)){
1474 case SSL_ERROR_NONE:
1475 goto end;
1476 case SSL_ERROR_WANT_WRITE:
1477 write_would_block(nonblock);
1478 rb_io_wait_writable(FPTR_TO_FD(fptr));
1479 continue;
1480 case SSL_ERROR_WANT_READ:
1481 read_would_block(nonblock);
1482 rb_io_wait_readable(FPTR_TO_FD(fptr));
1483 continue;
1484 case SSL_ERROR_SYSCALL:
1485 if (errno) rb_sys_fail(0);
1486 default:
1487 ossl_raise(eSSLError, "SSL_write");
1488 }
1489 }
1490 }
1491 else {
1492 ID id_syswrite = rb_intern("syswrite");
1493 rb_warning("SSL session is not started yet.");
1494 return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str);
1495 }
1496
1497 end:
1498 return INT2NUM(nwrite);
1499 }
1500
1501 /*
1502 * call-seq:
1503 * ssl.syswrite(string) => Integer
1504 *
1505 * Writes +string+ to the SSL connection.
1506 */
1507 static VALUE
1508 ossl_ssl_write(VALUE self, VALUE str)
1509 {
1510 return ossl_ssl_write_internal(self, str, 0);
1511 }
1512
1513 /*
1514 * call-seq:
1515 * ssl.syswrite_nonblock(string) => Integer
1516 *
1517 * Writes +string+ to the SSL connection in a non-blocking manner. Raises an
1518 * SSLError if writing would block.
1519 */
1520 static VALUE
1521 ossl_ssl_write_nonblock(VALUE self, VALUE str)
1522 {
1523 return ossl_ssl_write_internal(self, str, 1);
1524 }
1525
1526 /*
1527 * call-seq:
1528 * ssl.sysclose => nil
1529 *
1530 * Shuts down the SSL connection and prepares it for another connection.
1531 */
1532 static VALUE
1533 ossl_ssl_close(VALUE self)
1534 {
1535 SSL *ssl;
1536
1537 ossl_ssl_data_get_struct(self, ssl);
1538
1539 if (ssl) {
1540 VALUE io = ossl_ssl_get_io(self);
1541 if (!RTEST(rb_funcall(io, rb_intern("closed?"), 0))) {
1542 ossl_ssl_shutdown(ssl);
1543 SSL_free(ssl);
1544 DATA_PTR(self) = NULL;
1545 if (RTEST(ossl_ssl_get_sync_close(self)))
1546 rb_funcall(io, rb_intern("close"), 0);
1547 }
1548 }
1549
1550 return Qnil;
1551 }
1552
1553 /*
1554 * call-seq:
1555 * ssl.cert => cert or nil
1556 *
1557 * The X509 certificate for this socket endpoint.
1558 */
1559 static VALUE
1560 ossl_ssl_get_cert(VALUE self)
1561 {
1562 SSL *ssl;
1563 X509 *cert = NULL;
1564
1565 ossl_ssl_data_get_struct(self, ssl);
1566
1567 /*
1568 * Is this OpenSSL bug? Should add a ref?
1569 * TODO: Ask for.
1570 */
1571 cert = SSL_get_certificate(ssl); /* NO DUPs => DON'T FREE. */
1572
1573 if (!cert) {
1574 return Qnil;
1575 }
1576 return ossl_x509_new(cert);
1577 }
1578
1579 /*
1580 * call-seq:
1581 * ssl.peer_cert => cert or nil
1582 *
1583 * The X509 certificate for this socket's peer.
1584 */
1585 static VALUE
1586 ossl_ssl_get_peer_cert(VALUE self)
1587 {
1588 SSL *ssl;
1589 X509 *cert = NULL;
1590 VALUE obj;
1591
1592 ossl_ssl_data_get_struct(self, ssl);
1593
1594 cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */
1595
1596 if (!cert) {
1597 return Qnil;
1598 }
1599 obj = ossl_x509_new(cert);
1600 X509_free(cert);
1601
1602 return obj;
1603 }
1604
1605 /*
1606 * call-seq:
1607 * ssl.peer_cert_chain => [cert, ...] or nil
1608 *
1609 * The X509 certificate chain for this socket's peer.
1610 */
1611 static VALUE
1612 ossl_ssl_get_peer_cert_chain(VALUE self)
1613 {
1614 SSL *ssl;
1615 STACK_OF(X509) *chain;
1616 X509 *cert;
1617 VALUE ary;
1618 int i, num;
1619
1620 ossl_ssl_data_get_struct(self, ssl);
1621
1622 chain = SSL_get_peer_cert_chain(ssl);
1623 if(!chain) return Qnil;
1624 num = sk_X509_num(chain);
1625 ary = rb_ary_new2(num);
1626 for (i = 0; i < num; i++){
1627 cert = sk_X509_value(chain, i);
1628 rb_ary_push(ary, ossl_x509_new(cert));
1629 }
1630
1631 return ary;
1632 }
1633
1634 /*
1635 * call-seq:
1636 * ssl.version => String
1637 *
1638 * Returns a String representing the SSL/TLS version that was negotiated
1639 * for the connection, for example "TLSv1.2".
1640 */
1641 static VALUE
1642 ossl_ssl_get_version(VALUE self)
1643 {
1644 SSL *ssl;
1645
1646 ossl_ssl_data_get_struct(self, ssl);
1647
1648 return rb_str_new2(SSL_get_version(ssl));
1649 }
1650
1651 /*
1652 * call-seq:
1653 * ssl.cipher => [name, version, bits, alg_bits]
1654 *
1655 * The cipher being used for the current connection
1656 */
1657 static VALUE
1658 ossl_ssl_get_cipher(VALUE self)
1659 {
1660 SSL *ssl;
1661 SSL_CIPHER *cipher;
1662
1663 ossl_ssl_data_get_struct(self, ssl);
1664
1665 cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl);
1666
1667 return ossl_ssl_cipher_to_ary(cipher);
1668 }
1669
1670 /*
1671 * call-seq:
1672 * ssl.state => string
1673 *
1674 * A description of the current connection state.
1675 */
1676 static VALUE
1677 ossl_ssl_get_state(VALUE self)
1678 {
1679 SSL *ssl;
1680 VALUE ret;
1681
1682 ossl_ssl_data_get_struct(self, ssl);
1683
1684 ret = rb_str_new2(SSL_state_string(ssl));
1685 if (ruby_verbose) {
1686 rb_str_cat2(ret, ": ");
1687 rb_str_cat2(ret, SSL_state_string_long(ssl));
1688 }
1689 return ret;
1690 }
1691
1692 /*
1693 * call-seq:
1694 * ssl.pending => Integer
1695 *
1696 * The number of bytes that are immediately available for reading
1697 */
1698 static VALUE
1699 ossl_ssl_pending(VALUE self)
1700 {
1701 SSL *ssl;
1702
1703 ossl_ssl_data_get_struct(self, ssl);
1704
1705 return INT2NUM(SSL_pending(ssl));
1706 }
1707
1708 /*
1709 * call-seq:
1710 * ssl.session_reused? -> true | false
1711 *
1712 * Returns true if a reused session was negotiated during the handshake.
1713 */
1714 static VALUE
1715 ossl_ssl_session_reused(VALUE self)
1716 {
1717 SSL *ssl;
1718
1719 ossl_ssl_data_get_struct(self, ssl);
1720
1721 switch(SSL_session_reused(ssl)) {
1722 case 1: return Qtrue;
1723 case 0: return Qfalse;
1724 default: ossl_raise(eSSLError, "SSL_session_reused");
1725 }
1726
1727 UNREACHABLE;
1728 }
1729
1730 /*
1731 * call-seq:
1732 * ssl.session = session -> session
1733 *
1734 * Sets the Session to be used when the connection is established.
1735 */
1736 static VALUE
1737 ossl_ssl_set_session(VALUE self, VALUE arg1)
1738 {
1739 SSL *ssl;
1740 SSL_SESSION *sess;
1741
1742 /* why is ossl_ssl_setup delayed? */
1743 ossl_ssl_setup(self);
1744
1745 ossl_ssl_data_get_struct(self, ssl);
1746
1747 SafeGetSSLSession(arg1, sess);
1748
1749 if (SSL_set_session(ssl, sess) != 1)
1750 ossl_raise(eSSLError, "SSL_set_session");
1751
1752 return arg1;
1753 }
1754
1755 /*
1756 * call-seq:
1757 * ssl.verify_result => Integer
1758 *
1759 * Returns the result of the peer certificates verification. See verify(1)
1760 * for error values and descriptions.
1761 *
1762 * If no peer certificate was presented X509_V_OK is returned.
1763 */
1764 static VALUE
1765 ossl_ssl_get_verify_result(VALUE self)
1766 {
1767 SSL *ssl;
1768
1769 ossl_ssl_data_get_struct(self, ssl);
1770
1771 return INT2FIX(SSL_get_verify_result(ssl));
1772 }
1773
1774 /*
1775 * call-seq:
1776 * ssl.client_ca => [x509name, ...]
1777 *
1778 * Returns the list of client CAs. Please note that in contrast to
1779 * SSLContext#client_ca= no array of X509::Certificate is returned but
1780 * X509::Name instances of the CA's subject distinguished name.
1781 *
1782 * In server mode, returns the list set by SSLContext#client_ca=.
1783 * In client mode, returns the list of client CAs sent from the server.
1784 */
1785 static VALUE
1786 ossl_ssl_get_client_ca_list(VALUE self)
1787 {
1788 SSL *ssl;
1789 STACK_OF(X509_NAME) *ca;
1790
1791 ossl_ssl_data_get_struct(self, ssl);
1792
1793 ca = SSL_get_client_CA_list(ssl);
1794 return ossl_x509name_sk2ary(ca);
1795 }
1796
1797 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
1798 /*
1799 * call-seq:
1800 * ssl.npn_protocol => String
1801 *
1802 * Returns the protocol string that was finally selected by the client
1803 * during the handshake.
1804 */
1805 static VALUE
1806 ossl_ssl_npn_protocol(VALUE self)
1807 {
1808 SSL *ssl;
1809 const unsigned char *out;
1810 unsigned int outlen;
1811
1812 ossl_ssl_data_get_struct(self, ssl);
1813
1814 SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
1815 if (!outlen)
1816 return Qnil;
1817 else
1818 return rb_str_new((const char *) out, outlen);
1819 }
1820 #endif
1821
1822 void
1823 Init_ossl_ssl()
1824 {
1825 int i;
1826 VALUE ary;
1827
1828 #if 0
1829 mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
1830 #endif
1831
1832 ID_callback_state = rb_intern("@callback_state");
1833
1834 ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0);
1835 ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0);
1836 ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_ptr_idx",0,0,0);
1837 ossl_ssl_ex_client_cert_cb_idx =
1838 SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_client_cert_cb_idx",0,0,0);
1839 ossl_ssl_ex_tmp_dh_callback_idx =
1840 SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_tmp_dh_callback_idx",0,0,0);
1841
1842 /* Document-module: OpenSSL::SSL
1843 *
1844 * Use SSLContext to set up the parameters for a TLS (former SSL)
1845 * connection. Both client and server TLS connections are supported,
1846 * SSLSocket and SSLServer may be used in conjunction with an instance
1847 * of SSLContext to set up connections.
1848 */
1849 mSSL = rb_define_module_under(mOSSL, "SSL");
1850 /* Document-class: OpenSSL::SSL::SSLError
1851 *
1852 * Generic error class raised by SSLSocket and SSLContext.
1853 */
1854 eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError);
1855
1856 Init_ossl_ssl_session();
1857
1858 /* Document-class: OpenSSL::SSL::SSLContext
1859 *
1860 * An SSLContext is used to set various options regarding certificates,
1861 * algorithms, verification, session caching, etc. The SSLContext is
1862 * used to create an SSLSocket.
1863 *
1864 * All attributes must be set before creating an SSLSocket as the
1865 * SSLContext will be frozen afterward.
1866 *
1867 * The following attributes are available but don't show up in rdoc:
1868 * * ssl_version, cert, key, client_ca, ca_file, ca_path, timeout,
1869 * * verify_mode, verify_depth client_cert_cb, tmp_dh_callback,
1870 * * session_id_context, session_add_cb, session_new_cb, session_remove_cb
1871 */
1872 cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject);
1873 rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc);
1874
1875 /*
1876 * Context certificate
1877 */
1878 rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse);
1879
1880 /*
1881 * Context private key
1882 */
1883 rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse);
1884
1885 /*
1886 * A certificate or Array of certificates that will be sent to the client.
1887 */
1888 rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse);
1889
1890 /*
1891 * The path to a file containing a PEM-format CA certificate
1892 */
1893 rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse);
1894
1895 /*
1896 * The path to a directory containing CA certificates in PEM format.
1897 *
1898 * Files are looked up by subject's X509 name's hash value.
1899 */
1900 rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse);
1901
1902 /*
1903 * Maximum session lifetime.
1904 */
1905 rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse);
1906
1907 /*
1908 * Session verification mode.
1909 *
1910 * Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE,
1911 * VERIFY_FAIL_IF_NO_PEER_CERT and defined on OpenSSL::SSL
1912 */
1913 rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse);
1914
1915 /*
1916 * Number of CA certificates to walk when verifying a certificate chain.
1917 */
1918 rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse);
1919
1920 /*
1921 * A callback for additional certificate verification. The callback is
1922 * invoked for each certificate in the chain.
1923 *
1924 * The callback is invoked with two values. +preverify_ok+ indicates
1925 * indicates if the verification was passed (true) or not (false).
1926 * +store_context+ is an OpenSSL::X509::StoreContext containing the
1927 * context used for certificate verification.
1928 *
1929 * If the callback returns false verification is stopped.
1930 */
1931 rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
1932
1933 /*
1934 * Sets various OpenSSL options.
1935 */
1936 rb_attr(cSSLContext, rb_intern("options"), 1, 1, Qfalse);
1937
1938 /*
1939 * An OpenSSL::X509::Store used for certificate verification
1940 */
1941 rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse);
1942
1943 /*
1944 * An Array of extra X509 certificates to be added to the certificate
1945 * chain.
1946 */
1947 rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse);
1948
1949 /*
1950 * A callback invoked when a client certificate is requested by a server
1951 * and no certificate has been set.
1952 *
1953 * The callback is invoked with a Session and must return an Array
1954 * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any
1955 * other value is returned the handshake is suspended.
1956 */
1957 rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
1958
1959 /*
1960 * A callback invoked when DH parameters are required.
1961 *
1962 * The callback is invoked with the Session for the key exchange, an
1963 * flag indicating the use of an export cipher and the keylength
1964 * required.
1965 *
1966 * The callback must return an OpenSSL::PKey::DH instance of the correct
1967 * key length.
1968 */
1969 rb_attr(cSSLContext, rb_intern("tmp_dh_callback"), 1, 1, Qfalse);
1970
1971 /*
1972 * Sets the context in which a session can be reused. This allows
1973 * sessions for multiple applications to be distinguished, for exapmle, by
1974 * name.
1975 */
1976 rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse);
1977
1978 /*
1979 * A callback invoked on a server when a session is proposed by the client
1980 * but the session could not be found in the server's internal cache.
1981 *
1982 * The callback is invoked with the SSLSocket and session id. The
1983 * callback may return a Session from an external cache.
1984 */
1985 rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse);
1986
1987 /*
1988 * A callback invoked when a new session was negotiatied.
1989 *
1990 * The callback is invoked with an SSLSocket. If false is returned the
1991 * session will be removed from the internal cache.
1992 */
1993 rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse);
1994
1995 /*
1996 * A callback invoked when a session is removed from the internal cache.
1997 *
1998 * The callback is invoked with an SSLContext and a Session.
1999 */
2000 rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
2001
2002 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
2003 /*
2004 * A callback invoked at connect time to distinguish between multiple
2005 * server names.
2006 *
2007 * The callback is invoked with an SSLSocket and a server name. The
2008 * callback must return an SSLContext for the server name or nil.
2009 */
2010 rb_attr(cSSLContext, rb_intern("servername_cb"), 1, 1, Qfalse);
2011 #endif
2012 /*
2013 * A callback invoked whenever a new handshake is initiated. May be used
2014 * to disable renegotiation entirely.
2015 *
2016 * The callback is invoked with the active SSLSocket. The callback's
2017 * return value is irrelevant, normal return indicates "approval" of the
2018 * renegotiation and will continue the process. To forbid renegotiation
2019 * and to cancel the process, an Error may be raised within the callback.
2020 *
2021 * === Disable client renegotiation
2022 *
2023 * When running a server, it is often desirable to disable client
2024 * renegotiation entirely. You may use a callback as follows to implement
2025 * this feature:
2026 *
2027 * num_handshakes = 0
2028 * ctx.renegotiation_cb = lambda do |ssl|
2029 * num_handshakes += 1
2030 * raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
2031 * end
2032 */
2033 rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse);
2034 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
2035 /*
2036 * An Enumerable of Strings. Each String represents a protocol to be
2037 * advertised as the list of supported protocols for Next Protocol
2038 * Negotiation. Supported in OpenSSL 1.0.1 and higher. Has no effect
2039 * on the client side. If not set explicitly, the NPN extension will
2040 * not be sent by the server in the handshake.
2041 *
2042 * === Example
2043 *
2044 * ctx.npn_protocols = ["http/1.1", "spdy/2"]
2045 */
2046 rb_attr(cSSLContext, rb_intern("npn_protocols"), 1, 1, Qfalse);
2047 /*
2048 * A callback invoked on the client side when the client needs to select
2049 * a protocol from the list sent by the server. Supported in OpenSSL 1.0.1
2050 * and higher. The client MUST select a protocol of those advertised by
2051 * the server. If none is acceptable, raising an error in the callback
2052 * will cause the handshake to fail. Not setting this callback explicitly
2053 * means not supporting the NPN extension on the client - any protocols
2054 * advertised by the server will be ignored.
2055 *
2056 * === Example
2057 *
2058 * ctx.npn_select_cb = lambda do |protocols|
2059 * #inspect the protocols and select one
2060 * protocols.first
2061 * end
2062 */
2063 rb_attr(cSSLContext, rb_intern("npn_select_cb"), 1, 1, Qfalse);
2064 #endif
2065
2066 rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
2067 rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
2068 rb_define_method(cSSLContext, "initialize", ossl_sslctx_initialize, -1);
2069 rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1);
2070 rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
2071 rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
2072
2073 rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
2074
2075 /*
2076 * No session caching for client or server
2077 */
2078 rb_define_const(cSSLContext, "SESSION_CACHE_OFF", LONG2FIX(SSL_SESS_CACHE_OFF));
2079
2080 /*
2081 * Client sessions are added to the session cache
2082 */
2083 rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT", LONG2FIX(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */
2084
2085 /*
2086 * Server sessions are added to the session cache
2087 */
2088 rb_define_const(cSSLContext, "SESSION_CACHE_SERVER", LONG2FIX(SSL_SESS_CACHE_SERVER));
2089
2090 /*
2091 * Both client and server sessions are added to the session cache
2092 */
2093 rb_define_const(cSSLContext, "SESSION_CACHE_BOTH", LONG2FIX(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */
2094
2095 /*
2096 * Normally the session cache is checked for expired sessions every 255
2097 * connections. Since this may lead to a delay that cannot be controlled,
2098 * the automatic flushing may be disabled and #flush_sessions can be
2099 * called explicitly.
2100 */
2101 rb_define_const(cSSLContext, "SESSION_CACHE_NO_AUTO_CLEAR", LONG2FIX(SSL_SESS_CACHE_NO_AUTO_CLEAR));
2102
2103 /*
2104 * Always perform external lookups of sessions even if they are in the
2105 * internal cache.
2106 *
2107 * This flag has no effect on clients
2108 */
2109 rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_LOOKUP", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP));
2110
2111 /*
2112 * Never automatically store sessions in the internal store.
2113 */
2114 rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_STORE", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_STORE));
2115
2116 /*
2117 * Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and
2118 * SESSION_CACHE_NO_INTERNAL_STORE.
2119 */
2120 rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL));
2121
2122 rb_define_method(cSSLContext, "session_add", ossl_sslctx_session_add, 1);
2123 rb_define_method(cSSLContext, "session_remove", ossl_sslctx_session_remove, 1);
2124 rb_define_method(cSSLContext, "session_cache_mode", ossl_sslctx_get_session_cache_mode, 0);
2125 rb_define_method(cSSLContext, "session_cache_mode=", ossl_sslctx_set_session_cache_mode, 1);
2126 rb_define_method(cSSLContext, "session_cache_size", ossl_sslctx_get_session_cache_size, 0);
2127 rb_define_method(cSSLContext, "session_cache_size=", ossl_sslctx_set_session_cache_size, 1);
2128 rb_define_method(cSSLContext, "session_cache_stats", ossl_sslctx_get_session_cache_stats, 0);
2129 rb_define_method(cSSLContext, "flush_sessions", ossl_sslctx_flush_sessions, -1);
2130
2131 ary = rb_ary_new2(numberof(ossl_ssl_method_tab));
2132 for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
2133 rb_ary_push(ary, ID2SYM(rb_intern(ossl_ssl_method_tab[i].name)));
2134 }
2135 rb_obj_freeze(ary);
2136 /* The list of available SSL/TLS methods */
2137 rb_define_const(cSSLContext, "METHODS", ary);
2138
2139 /*
2140 * Document-class: OpenSSL::SSL::SSLSocket
2141 *
2142 * The following attributes are available but don't show up in rdoc.
2143 * * io, context, sync_close
2144 *
2145 */
2146 cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
2147 rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
2148 for(i = 0; i < numberof(ossl_ssl_attr_readers); i++)
2149 rb_attr(cSSLSocket, rb_intern(ossl_ssl_attr_readers[i]), 1, 0, Qfalse);
2150 for(i = 0; i < numberof(ossl_ssl_attrs); i++)
2151 rb_attr(cSSLSocket, rb_intern(ossl_ssl_attrs[i]), 1, 1, Qfalse);
2152 rb_define_alias(cSSLSocket, "to_io", "io");
2153 rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
2154 rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0);
2155 rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, 0);
2156 rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0);
2157 rb_define_method(cSSLSocket, "accept_nonblock", ossl_ssl_accept_nonblock, 0);
2158 rb_define_method(cSSLSocket, "sysread", ossl_ssl_read, -1);
2159 rb_define_private_method(cSSLSocket, "sysread_nonblock", ossl_ssl_read_nonblock, -1);
2160 rb_define_method(cSSLSocket, "syswrite", ossl_ssl_write, 1);
2161 rb_define_private_method(cSSLSocket, "syswrite_nonblock", ossl_ssl_write_nonblock, 1);
2162 rb_define_method(cSSLSocket, "sysclose", ossl_ssl_close, 0);
2163 rb_define_method(cSSLSocket, "cert", ossl_ssl_get_cert, 0);
2164 rb_define_method(cSSLSocket, "peer_cert", ossl_ssl_get_peer_cert, 0);
2165 rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0);
2166 rb_define_method(cSSLSocket, "ssl_version", ossl_ssl_get_version, 0);
2167 rb_define_method(cSSLSocket, "cipher", ossl_ssl_get_cipher, 0);
2168 rb_define_method(cSSLSocket, "state", ossl_ssl_get_state, 0);
2169 rb_define_method(cSSLSocket, "pending", ossl_ssl_pending, 0);
2170 rb_define_method(cSSLSocket, "session_reused?", ossl_ssl_session_reused, 0);
2171 /* implementation of OpenSSL::SSL::SSLSocket#session is in lib/openssl/ssl.rb */
2172 rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1);
2173 rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
2174 rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
2175 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
2176 rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2177 #endif
2178
2179 #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2NUM(SSL_##x))
2180
2181 ossl_ssl_def_const(VERIFY_NONE);
2182 ossl_ssl_def_const(VERIFY_PEER);
2183 ossl_ssl_def_const(VERIFY_FAIL_IF_NO_PEER_CERT);
2184 ossl_ssl_def_const(VERIFY_CLIENT_ONCE);
2185 /* Introduce constants included in OP_ALL. These constants are mostly for
2186 * unset some bits in OP_ALL such as;
2187 * ctx.options = OP_ALL & ~OP_DONT_INSERT_EMPTY_FRAGMENTS
2188 */
2189 ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG);
2190 ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG);
2191 ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
2192 ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG);
2193 ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER);
2194 ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING);
2195 ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG);
2196 ossl_ssl_def_const(OP_TLS_D5_BUG);
2197 ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG);
2198 ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS);
2199 ossl_ssl_def_const(OP_ALL);
2200 #if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
2201 ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
2202 #endif
2203 #if defined(SSL_OP_SINGLE_ECDH_USE)
2204 ossl_ssl_def_const(OP_SINGLE_ECDH_USE);
2205 #endif
2206 ossl_ssl_def_const(OP_SINGLE_DH_USE);
2207 ossl_ssl_def_const(OP_EPHEMERAL_RSA);
2208 #if defined(SSL_OP_CIPHER_SERVER_PREFERENCE)
2209 ossl_ssl_def_const(OP_CIPHER_SERVER_PREFERENCE);
2210 #endif
2211 ossl_ssl_def_const(OP_TLS_ROLLBACK_BUG);
2212 ossl_ssl_def_const(OP_NO_SSLv2);
2213 ossl_ssl_def_const(OP_NO_SSLv3);
2214 ossl_ssl_def_const(OP_NO_TLSv1);
2215 #if defined(SSL_OP_NO_TLSv1_1)
2216 ossl_ssl_def_const(OP_NO_TLSv1_1);
2217 #endif
2218 #if defined(SSL_OP_NO_TLSv1_2)
2219 ossl_ssl_def_const(OP_NO_TLSv1_2);
2220 #endif
2221 #if defined(SSL_OP_NO_TICKET)
2222 ossl_ssl_def_const(OP_NO_TICKET);
2223 #endif
2224 #if defined(SSL_OP_NO_COMPRESSION)
2225 ossl_ssl_def_const(OP_NO_COMPRESSION);
2226 #endif
2227 ossl_ssl_def_const(OP_PKCS1_CHECK_1);
2228 ossl_ssl_def_const(OP_PKCS1_CHECK_2);
2229 ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG);
2230 ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
2231 }
ossl_ssl_get_cipher
static VALUE ossl_ssl_get_cipher(VALUE self)
Definition: ossl_ssl.c:1658
ID_callback_state
ID ID_callback_state
Definition: ossl_ssl.c:101
RARRAY_PTR
RARRAY_PTR(q->result)[0]
ossl_sslctx_session_add
static VALUE ossl_sslctx_session_add(VALUE self, VALUE arg)
Definition: ossl_ssl.c:913
ossl_sslctx_get_session_cache_stats
static VALUE ossl_sslctx_get_session_cache_stats(VALUE self)
Definition: ossl_ssl.c:1037
mOSSL
VALUE mOSSL
Definition: ossl.c:259
ary
volatile VALUE ary
Definition: tcltklib.c:9713
ossl_tmp_dh_callback
static DH * ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
Definition: ossl_ssl.c:290
rb_ary_entry
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1101
ssl_get_error
#define ssl_get_error(ssl, ret)
Definition: ossl_ssl.c:1216
rb_io_check_readable
void rb_io_check_readable(rb_io_t *)
Definition: io.c:781
ossl_sslctx_get_key
#define ossl_sslctx_get_key(o)
Definition: ossl_ssl.c:49
ossl_ssl_ex_store_p
int ossl_ssl_ex_store_p
Definition: ossl_ssl.c:142
rb_thread_wait_fd
void rb_thread_wait_fd(int)
Definition: thread.c:3431
rb_iv_set
VALUE rb_iv_set(VALUE, const char *, VALUE)
Definition: variable.c:2591
ossl_sslctx_initialize
static VALUE ossl_sslctx_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_ssl.c:218
ossl_ssl_get_tmp_dh
#define ossl_ssl_get_tmp_dh(o)
Definition: ossl_ssl.c:84
ossl_ssl_s_alloc
static VALUE ossl_ssl_s_alloc(VALUE klass)
Definition: ossl_ssl.c:1123
ossl_ssl_read
static VALUE ossl_ssl_read(int argc, VALUE *argv, VALUE self)
Definition: ossl_ssl.c:1437
out
C_block * out
Definition: crypt.c:308
func
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:108
rb_mWaitReadable
RUBY_EXTERN VALUE rb_mWaitReadable
Definition: ripper.y:1422
ossl_sslctx_free
static void ossl_sslctx_free(SSL_CTX *ctx)
Definition: ossl_ssl.c:148
i
ssize_t i
Definition: bigdecimal.c:5655
rb_io_t
Definition: io.h:63
rb_check_frozen
#define rb_check_frozen(obj)
rb_cTime
RUBY_EXTERN VALUE rb_cTime
Definition: ripper.y:1460
ret
int ret
Definition: tcltklib.c:280
ossl_ssl_set_key
#define ossl_ssl_set_key(o, v)
Definition: ossl_ssl.c:90
rb_iv_get
VALUE rb_iv_get(VALUE, const char *)
Definition: variable.c:2583
rb_define_private_method
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1356
ossl_ssl_ex_tmp_dh_callback_idx
int ossl_ssl_ex_tmp_dh_callback_idx
Definition: ossl_ssl.c:145
ossl_ssl_ex_vcb_idx
int ossl_ssl_ex_vcb_idx
Definition: ossl_ssl.c:141
rb_obj_freeze
VALUE rb_obj_freeze(VALUE)
Definition: object.c:989
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
UNREACHABLE
#define UNREACHABLE
Definition: ruby.h:40
ossl_call_tmp_dh_callback
static VALUE ossl_call_tmp_dh_callback(VALUE *args)
Definition: ossl_ssl.c:272
exc
VALUE exc
Definition: tcltklib.c:3096
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
ossl_sslctx_get_client_cert_cb
#define ossl_sslctx_get_client_cert_cb(o)
Definition: ossl_ssl.c:60
ossl_ssl_get_cert
static VALUE ossl_ssl_get_cert(VALUE self)
Definition: ossl_ssl.c:1560
ossl_ssl_ex_ptr_idx
int ossl_ssl_ex_ptr_idx
Definition: ossl_ssl.c:143
TYPE
#define TYPE(x)
ossl_x509name_sk2ary
VALUE ossl_x509name_sk2ary(STACK_OF(X509_NAME)*names)
RSTRING_PTR
#define RSTRING_PTR(str)
NIL_P
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
T_ARRAY
#define T_ARRAY
in
int const char * in
Definition: crypt.c:639
FPTR_TO_FD
#define FPTR_TO_FD(fptr)
Definition: ruby_missing.h:19
rb_protect
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:771
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:545
Qtrue
return Qtrue
Definition: tcltklib.c:9610
T_FILE
#define T_FILE
ossl_ssl_set_tmp_dh
#define ossl_ssl_set_tmp_dh(o, v)
Definition: ossl_ssl.c:91
ossl_sslctx_get_client_ca
#define ossl_sslctx_get_client_ca(o)
Definition: ossl_ssl.c:50
rb_str_new2
#define rb_str_new2
ossl_ssl_connect_nonblock
static VALUE ossl_ssl_connect_nonblock(VALUE self)
Definition: ossl_ssl.c:1324
ossl_sslctx_add_extra_chain_cert_i
static VALUE ossl_sslctx_add_extra_chain_cert_i(VALUE i, VALUE arg)
Definition: ossl_ssl.c:475
state
int state
Definition: tcltklib.c:1462
ossl_ssl_read_nonblock
static VALUE ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
Definition: ossl_ssl.c:1454
ossl_ssl_close
static VALUE ossl_ssl_close(VALUE self)
Definition: ossl_ssl.c:1533
ossl_verify_cb_idx
int ossl_verify_cb_idx
Definition: ossl.c:201
ID2SYM
#define ID2SYM(x)
ossl_ssl_get_io
#define ossl_ssl_get_io(o)
Definition: ossl_ssl.c:79
rb_iterate
VALUE rb_iterate(VALUE(*)(VALUE), VALUE, VALUE(*)(ANYARGS), VALUE)
Definition: vm_eval.c:1032
args
VALUE VALUE args
Definition: tcltklib.c:2561
GetOpenFile
#define GetOpenFile(obj, fp)
Definition: io.h:120
LONG2NUM
#define LONG2NUM(x)
rb_str_append
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2121
ossl_ssl_write_nonblock
static VALUE ossl_ssl_write_nonblock(VALUE self, VALUE str)
Definition: ossl_ssl.c:1521
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1116
ossl_ssl_shutdown
static void ossl_ssl_shutdown(SSL *ssl)
Definition: ossl_ssl.c:1096
rb_mWaitWritable
RUBY_EXTERN VALUE rb_mWaitWritable
Definition: ripper.y:1423
ossl_ssl_write
static VALUE ossl_ssl_write(VALUE self, VALUE str)
Definition: ossl_ssl.c:1508
ossl_call_client_cert_cb
static VALUE ossl_call_client_cert_cb(VALUE obj)
Definition: ossl_ssl.c:237
ossl_exc_new
VALUE ossl_exc_new(VALUE exc, const char *fmt,...)
Definition: ossl.c:339
rb_exc_raise
void rb_exc_raise(VALUE mesg)
Definition: eval.c:527
Init_ossl_ssl_session
void Init_ossl_ssl_session(void)
Definition: ossl_ssl_session.c:296
STACK_OF
STACK_OF(X509)*ossl_x509_ary2sk0(VALUE)
hash
VALUE hash
Definition: tkutil.c:267
OSSL_DEFAULT_DH_512
DH * OSSL_DEFAULT_DH_512
Definition: ossl_pkey_dh.c:539
mSSL
VALUE mSSL
Definition: ossl_ssl.c:27
GetX509CertPtr
X509 * GetX509CertPtr(VALUE)
Definition: ossl_x509cert.c:92
rb_obj_is_instance_of
VALUE rb_obj_is_instance_of(VALUE, VALUE)
Definition: object.c:545
ossl_ssl_accept
static VALUE ossl_ssl_accept(VALUE self)
Definition: ossl_ssl.c:1338
Data_Wrap_Struct
return Data_Wrap_Struct(CLASS_OF(interp), 0, ip_free, slave)
ossl_sslctx_get_ciphers
static VALUE ossl_sslctx_get_ciphers(VALUE self)
Definition: ossl_ssl.c:831
Qfalse
return Qfalse
Definition: tcltklib.c:6779
numberof
#define numberof(ary)
Definition: ossl_ssl.c:19
RARRAY_LEN
#define RARRAY_LEN(a)
Init_ossl_ssl
void Init_ossl_ssl()
Definition: ossl_ssl.c:1823
Qnil
#define Qnil
Definition: tcltklib.c:1896
StringValuePtr
#define StringValuePtr(v)
elem
volatile VALUE elem
Definition: tcltklib.c:9713
val
#define val
Definition: tcltklib.c:1949
ossl_ssl_write_internal
static VALUE ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock)
Definition: ossl_ssl.c:1460
ossl_sslctx_get_cert
#define ossl_sslctx_get_cert(o)
Definition: ossl_ssl.c:48
ossl_ssl_session_reused
static VALUE ossl_ssl_session_reused(VALUE self)
Definition: ossl_ssl.c:1715
ossl_ssl_get_ctx
#define ossl_ssl_get_ctx(o)
Definition: ossl_ssl.c:80
ossl_call_session_remove_cb
static VALUE ossl_call_session_remove_cb(VALUE ary)
Definition: ossl_ssl.c:431
ossl_ssl_attrs
static const char * ossl_ssl_attrs[]
Definition: ossl_ssl.c:94
str
static VALUE char * str
Definition: tcltklib.c:3547
ossl_sslctx_get_extra_cert
#define ossl_sslctx_get_extra_cert(o)
Definition: ossl_ssl.c:59
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:424
Check_Type
#define Check_Type(v, t)
StringValueCStr
#define StringValueCStr(v)
ID
unsigned long ID
Definition: ripper.y:105
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2202
rb_str_cat2
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1982
ossl_ssl_accept_nonblock
static VALUE ossl_ssl_accept_nonblock(VALUE self)
Definition: ossl_ssl.c:1363
obj
static VALUE VALUE obj
Definition: tcltklib.c:3158
INT2FIX
#define INT2FIX(i)
ossl_sslctx_get_sess_id_ctx
#define ossl_sslctx_get_sess_id_ctx(o)
Definition: ossl_ssl.c:62
ossl_sslctx_attrs
static const char * ossl_sslctx_attrs[]
Definition: ossl_ssl.c:64
ossl_sslctx_get_ca_file
#define ossl_sslctx_get_ca_file(o)
Definition: ossl_ssl.c:51
rb_io_wait_writable
int rb_io_wait_writable(int)
Definition: io.c:1090
unistd.h
ossl_sslctx_get_verify_dep
#define ossl_sslctx_get_verify_dep(o)
Definition: ossl_ssl.c:55
eOSSLError
VALUE eOSSLError
Definition: ossl.c:264
ossl_ssl_pending
static VALUE ossl_ssl_pending(VALUE self)
Definition: ossl_ssl.c:1699
ossl_sslctx_setup
static VALUE ossl_sslctx_setup(VALUE self)
Definition: ossl_ssl.c:652
method
volatile ID method
Definition: tcltklib.c:3599
rb_call_super
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:273
ossl_x509_new
VALUE ossl_x509_new(X509 *)
Definition: ossl_x509cert.c:40
ossl_ssl_read_internal
static VALUE ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
Definition: ossl_ssl.c:1370
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
ossl_ssl_set_sync_close
#define ossl_ssl_set_sync_close(o, v)
Definition: ossl_ssl.c:88
ossl_ssl_set_session
static VALUE ossl_ssl_set_session(VALUE self, VALUE arg1)
Definition: ossl_ssl.c:1737
ossl_sslctx_get_verify_cb
#define ossl_sslctx_get_verify_cb(o)
Definition: ossl_ssl.c:56
key
static int VALUE key
Definition: tkutil.c:265
ossl_ssl_get_verify_result
static VALUE ossl_ssl_get_verify_result(VALUE self)
Definition: ossl_ssl.c:1765
ossl_ssl_get_state
static VALUE ossl_ssl_get_state(VALUE self)
Definition: ossl_ssl.c:1677
ossl_sslctx_get_session_cache_mode
static VALUE ossl_sslctx_get_session_cache_mode(VALUE self)
Definition: ossl_ssl.c:949
ossl_sslctx_session_get_cb
static SSL_SESSION * ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
Definition: ossl_ssl.c:349
rb_str_buf_cat
VALUE rb_str_buf_cat(VALUE, const char *, long)
Definition: string.c:1947
ossl_sslctx_get_verify_mode
#define ossl_sslctx_get_verify_mode(o)
Definition: ossl_ssl.c:54
TO_SOCKET
#define TO_SOCKET(s)
Definition: ossl_ssl.c:24
argv
VALUE * argv
Definition: tcltklib.c:1971
rb_hash_aset
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1539
rb_str_resize
VALUE rb_str_resize(VALUE, long)
Definition: string.c:1853
ossl_ssl_get_client_ca_list
static VALUE ossl_ssl_get_client_ca_list(VALUE self)
Definition: ossl_ssl.c:1786
RTEST
#define RTEST(v)
write_would_block
static void write_would_block(int nonblock)
Definition: ossl_ssl.c:1229
ossl_ssl_setup
static VALUE ossl_ssl_setup(VALUE self)
Definition: ossl_ssl.c:1167
errno
int errno
StringValue
#define StringValue(v)
cSSLContext
VALUE cSSLContext
Definition: ossl_ssl.c:29
OSSL_SSL_METHOD_ENTRY
#define OSSL_SSL_METHOD_ENTRY(name)
ossl_ssl_initialize
static VALUE ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_ssl.c:1145
ossl_sslctx_get_cert_store
#define ossl_sslctx_get_cert_store(o)
Definition: ossl_ssl.c:58
s
register char * s
Definition: os2.c:56
cSSLSocket
VALUE cSSLSocket
Definition: ossl_ssl.c:30
rb_String
VALUE rb_String(VALUE)
Definition: object.c:2738
void
VP_EXPORT void
Definition: bigdecimal.c:5083
mode
VALUE mode
Definition: tcltklib.c:1664
ossl_ssl_set_x509
#define ossl_ssl_set_x509(o, v)
Definition: ossl_ssl.c:89
ossl_sslctx_get_timeout
#define ossl_sslctx_get_timeout(o)
Definition: ossl_ssl.c:53
ossl_sslctx_session_remove
static VALUE ossl_sslctx_session_remove(VALUE self, VALUE arg)
Definition: ossl_ssl.c:931
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
rb_block_call
VALUE rb_block_call(VALUE, ID, int, VALUE *, VALUE(*)(ANYARGS), VALUE)
Definition: vm_eval.c:1131
rb_attr
void rb_attr(VALUE, ID, int, int, int)
Definition: vm_method.c:796
ossl_ssl_data_get_struct
#define ossl_ssl_data_get_struct(v, ssl)
Definition: ossl_ssl.c:1219
OBJ_FROZEN
#define OBJ_FROZEN(x)
ossl_ssl_get_x509
#define ossl_ssl_get_x509(o)
Definition: ossl_ssl.c:82
ossl_sslctx_get_options
#define ossl_sslctx_get_options(o)
Definition: ossl_ssl.c:57
argc
int argc
Definition: tcltklib.c:1970
ossl_call_session_new_cb
static VALUE ossl_call_session_new_cb(VALUE ary)
Definition: ossl_ssl.c:379
ossl_sslctx_set_ciphers
static VALUE ossl_sslctx_set_ciphers(VALUE self, VALUE v)
Definition: ossl_ssl.c:871
ossl_client_cert_cb
static int ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
Definition: ossl_ssl.c:256
rb_extend_object
void rb_extend_object(VALUE obj, VALUE module)
Definition: eval.c:1234
ossl_sslctx_set_session_cache_mode
static VALUE ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg)
Definition: ossl_ssl.c:967
ossl_ssl_get_key
#define ossl_ssl_get_key(o)
Definition: ossl_ssl.c:83
ssl_renegotiation_cb
static void ssl_renegotiation_cb(const SSL *ssl)
Definition: ossl_ssl.c:550
rb_sys_fail
void rb_sys_fail(const char *mesg)
Definition: error.c:1899
OSSL_Debug
#define OSSL_Debug
Definition: ossl.h:211
ruby_verbose
ruby_verbose
Definition: tcltklib.c:5818
rb_jump_tag
void rb_jump_tag(int tag)
Definition: eval.c:666
ptr
return ptr
Definition: tcltklib.c:784
rb_each
VALUE rb_each(VALUE)
Definition: vm_eval.c:1166
_
#define _(args)
Definition: dln.h:28
GetX509StorePtr
X509_STORE * GetX509StorePtr(VALUE)
Definition: ossl_x509store.c:68
rb_define_module_under
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:637
ossl_sslctx_get_tmp_dh_cb
#define ossl_sslctx_get_tmp_dh_cb(o)
Definition: ossl_ssl.c:61
end
gz end
Definition: zlib.c:2272
ossl_sslctx_get_ca_path
#define ossl_sslctx_get_ca_path(o)
Definition: ossl_ssl.c:52
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1128
arg
arg
Definition: ripper.y:1315
ossl_ssl_get_peer_cert
static VALUE ossl_ssl_get_peer_cert(VALUE self)
Definition: ossl_ssl.c:1586
rb_str_modify
void rb_str_modify(VALUE)
Definition: string.c:1369
T_SYMBOL
#define T_SYMBOL
ossl_call_session_get_cb
static VALUE ossl_call_session_get_cb(VALUE ary)
Definition: ossl_ssl.c:332
NUM2LONG
#define NUM2LONG(x)
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:582
DATA_PTR
DATA_PTR(self)
ossl_ssl_free
static void ossl_ssl_free(SSL *ssl)
Definition: ossl_ssl.c:1117
OSSL_Check_Kind
#define OSSL_Check_Kind(obj, klass)
Definition: ossl.h:96
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
LONG2FIX
#define LONG2FIX(i)
ssl_info_cb
static void ssl_info_cb(const SSL *ssl, int where, int val)
Definition: ossl_ssl.c:632
klass
klass
Definition: tcltklib.c:3504
ossl_ssl_set_io
#define ossl_ssl_set_io(o, v)
Definition: ossl_ssl.c:86
INT2NUM
#define INT2NUM(x)
Data_Get_Struct
#define Data_Get_Struct(obj, type, sval)
ossl_ssl_method_tab
struct @11 ossl_ssl_method_tab[]
ossl_ssl_def_const
#define ossl_ssl_def_const(x)
cSSLSession
VALUE cSSLSession
Definition: ossl_ssl_session.c:20
ossl_raise
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:328
ossl_ssl_verify_callback
static int ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
Definition: ossl_ssl.c:320
io
gz io
Definition: zlib.c:2263
GetPKeyPtr
EVP_PKEY * GetPKeyPtr(VALUE obj)
Definition: ossl_pkey.c:174
ossl_ssl_get_version
static VALUE ossl_ssl_get_version(VALUE self)
Definition: ossl_ssl.c:1642
ossl_sslctx_set_session_cache_size
static VALUE ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg)
Definition: ossl_ssl.c:1003
RSTRING_LENINT
#define RSTRING_LENINT(str)
DupPKeyPtr
EVP_PKEY * DupPKeyPtr(VALUE obj)
Definition: ossl_pkey.c:197
DupX509CertPtr
X509 * DupX509CertPtr(VALUE)
Definition: ossl_x509cert.c:102
rb_ary_new2
VALUE rb_ary_new2(long capa)
Definition: array.c:417
rb_str_new
VALUE rb_str_new(const char *, long)
Definition: string.c:425
rb_io_check_writable
void rb_io_check_writable(rb_io_t *)
Definition: io.c:805
eSSLError
VALUE eSSLError
Definition: ossl_ssl.c:28
NUM2INT
#define NUM2INT(x)
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:234
rb_obj_alloc
VALUE rb_obj_alloc(VALUE)
Definition: object.c:1721
ossl_ssl_get_peer_cert_chain
static VALUE ossl_ssl_get_peer_cert_chain(VALUE self)
Definition: ossl_ssl.c:1612
rb_id2name
const char * rb_id2name(ID id)
Definition: ripper.c:17005
ossl.h
ossl_ssl_attr_readers
static const char * ossl_ssl_attr_readers[]
Definition: ossl_ssl.c:93
ossl_sslctx_flush_sessions
static VALUE ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
Definition: ossl_ssl.c:1069
VALUE
unsigned long VALUE
Definition: ripper.y:104
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:229
SafeGetSSLSession
#define SafeGetSSLSession(obj, sess)
Definition: ossl_ssl.h:21
ossl_sslctx_session_remove_cb
static void ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
Definition: ossl_ssl.c:445
ossl_sslctx_set_ssl_version
static VALUE ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
Definition: ossl_ssl.c:181
snprintf
#define snprintf
OBJ_TAINT
#define OBJ_TAINT(x)
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:617
ossl_sslctx_session_new_cb
static int ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
Definition: ossl_ssl.c:396
read_would_block
static void read_would_block(int nonblock)
Definition: ossl_ssl.c:1239
rb_intern
#define rb_intern(str)
v
BDIGIT v
Definition: bigdecimal.c:5656
ossl_ssl_connect
static VALUE ossl_ssl_connect(VALUE self)
Definition: ossl_ssl.c:1299
NULL
#define NULL
Definition: _sdbm.c:103
time
VALUE time
Definition: tcltklib.c:1866
name
const char * name
Definition: nkf.c:208
rb_io_wait_readable
int rb_io_wait_readable(int)
Definition: io.c:1064
ossl_sslctx_s_alloc
static VALUE ossl_sslctx_s_alloc(VALUE klass)
Definition: ossl_ssl.c:156
OSSL_DEFAULT_DH_1024
DH * OSSL_DEFAULT_DH_1024
Definition: ossl_pkey_dh.c:567
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
ossl_ssl_cipher_to_ary
static VALUE ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher)
Definition: ossl_ssl.c:809
SYM2ID
#define SYM2ID(x)
ossl_start_ssl
static VALUE ossl_start_ssl(VALUE self, int(*func)(), const char *funcname, int nonblock)
Definition: ossl_ssl.c:1249
rb_eArgError
VALUE rb_eArgError
Definition: error.c:512
ossl_verify_cb
int ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
Definition: ossl.c:211
ossl_ssl_set_ctx
#define ossl_ssl_set_ctx(o, v)
Definition: ossl_ssl.c:87
ossl_default_tmp_dh_callback
static DH * ossl_default_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
Definition: ossl_ssl.c:305
ossl_sslctx_get_session_cache_size
static VALUE ossl_sslctx_get_session_cache_size(VALUE self)
Definition: ossl_ssl.c:986
ossl_ssl_ex_client_cert_cb_idx
int ossl_ssl_ex_client_cert_cb_idx
Definition: ossl_ssl.c:144
ossl_ssl_get_sync_close
#define ossl_ssl_get_sync_close(o)
Definition: ossl_ssl.c:81
len
size_t len
Definition: tcltklib.c:3568
rb_eof_error
void rb_eof_error(void)
Definition: io.c:581
rb_str_set_len
void rb_str_set_len(VALUE, long)
Definition: string.c:1837