Ruby
2.0.0p247(2013-06-27revision41674)
|
00001 /* 00002 * $Id: ossl_ssl.c 40387 2013-04-19 17:16:37Z nagachika $ 00003 * 'OpenSSL for Ruby' project 00004 * Copyright (C) 2000-2002 GOTOU Yuuzou <gotoyuzo@notwork.org> 00005 * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> 00006 * Copyright (C) 2001-2007 Technorama Ltd. <oss-ruby@technorama.net> 00007 * All rights reserved. 00008 */ 00009 /* 00010 * This program is licenced under the same licence as Ruby. 00011 * (See the file 'LICENCE'.) 00012 */ 00013 #include "ossl.h" 00014 00015 #if defined(HAVE_UNISTD_H) 00016 # include <unistd.h> /* for read(), and write() */ 00017 #endif 00018 00019 #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0])) 00020 00021 #ifdef _WIN32 00022 # define TO_SOCKET(s) _get_osfhandle(s) 00023 #else 00024 # define TO_SOCKET(s) (s) 00025 #endif 00026 00027 VALUE mSSL; 00028 VALUE eSSLError; 00029 VALUE cSSLContext; 00030 VALUE cSSLSocket; 00031 00032 #define ossl_sslctx_set_cert(o,v) rb_iv_set((o),"@cert",(v)) 00033 #define ossl_sslctx_set_key(o,v) rb_iv_set((o),"@key",(v)) 00034 #define ossl_sslctx_set_client_ca(o,v) rb_iv_set((o),"@client_ca",(v)) 00035 #define ossl_sslctx_set_ca_file(o,v) rb_iv_set((o),"@ca_file",(v)) 00036 #define ossl_sslctx_set_ca_path(o,v) rb_iv_set((o),"@ca_path",(v)) 00037 #define ossl_sslctx_set_timeout(o,v) rb_iv_set((o),"@timeout",(v)) 00038 #define ossl_sslctx_set_verify_mode(o,v) rb_iv_set((o),"@verify_mode",(v)) 00039 #define ossl_sslctx_set_verify_dep(o,v) rb_iv_set((o),"@verify_depth",(v)) 00040 #define ossl_sslctx_set_verify_cb(o,v) rb_iv_set((o),"@verify_callback",(v)) 00041 #define ossl_sslctx_set_options(o,v) rb_iv_set((o),"@options",(v)) 00042 #define ossl_sslctx_set_cert_store(o,v) rb_iv_set((o),"@cert_store",(v)) 00043 #define ossl_sslctx_set_extra_cert(o,v) rb_iv_set((o),"@extra_chain_cert",(v)) 00044 #define ossl_sslctx_set_client_cert_cb(o,v) rb_iv_set((o),"@client_cert_cb",(v)) 00045 #define ossl_sslctx_set_tmp_dh_cb(o,v) rb_iv_set((o),"@tmp_dh_callback",(v)) 00046 #define ossl_sslctx_set_sess_id_ctx(o, v) rb_iv_set((o),"@session_id_context",(v)) 00047 00048 #define ossl_sslctx_get_cert(o) rb_iv_get((o),"@cert") 00049 #define ossl_sslctx_get_key(o) rb_iv_get((o),"@key") 00050 #define ossl_sslctx_get_client_ca(o) rb_iv_get((o),"@client_ca") 00051 #define ossl_sslctx_get_ca_file(o) rb_iv_get((o),"@ca_file") 00052 #define ossl_sslctx_get_ca_path(o) rb_iv_get((o),"@ca_path") 00053 #define ossl_sslctx_get_timeout(o) rb_iv_get((o),"@timeout") 00054 #define ossl_sslctx_get_verify_mode(o) rb_iv_get((o),"@verify_mode") 00055 #define ossl_sslctx_get_verify_dep(o) rb_iv_get((o),"@verify_depth") 00056 #define ossl_sslctx_get_verify_cb(o) rb_iv_get((o),"@verify_callback") 00057 #define ossl_sslctx_get_options(o) rb_iv_get((o),"@options") 00058 #define ossl_sslctx_get_cert_store(o) rb_iv_get((o),"@cert_store") 00059 #define ossl_sslctx_get_extra_cert(o) rb_iv_get((o),"@extra_chain_cert") 00060 #define ossl_sslctx_get_client_cert_cb(o) rb_iv_get((o),"@client_cert_cb") 00061 #define ossl_sslctx_get_tmp_dh_cb(o) rb_iv_get((o),"@tmp_dh_callback") 00062 #define ossl_sslctx_get_sess_id_ctx(o) rb_iv_get((o),"@session_id_context") 00063 00064 static const char *ossl_sslctx_attrs[] = { 00065 "cert", "key", "client_ca", "ca_file", "ca_path", 00066 "timeout", "verify_mode", "verify_depth", "renegotiation_cb", 00067 "verify_callback", "options", "cert_store", "extra_chain_cert", 00068 "client_cert_cb", "tmp_dh_callback", "session_id_context", 00069 "session_get_cb", "session_new_cb", "session_remove_cb", 00070 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME 00071 "servername_cb", 00072 #endif 00073 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED 00074 "npn_protocols", 00075 "npn_select_cb", 00076 #endif 00077 }; 00078 00079 #define ossl_ssl_get_io(o) rb_iv_get((o),"@io") 00080 #define ossl_ssl_get_ctx(o) rb_iv_get((o),"@context") 00081 #define ossl_ssl_get_sync_close(o) rb_iv_get((o),"@sync_close") 00082 #define ossl_ssl_get_x509(o) rb_iv_get((o),"@x509") 00083 #define ossl_ssl_get_key(o) rb_iv_get((o),"@key") 00084 #define ossl_ssl_get_tmp_dh(o) rb_iv_get((o),"@tmp_dh") 00085 00086 #define ossl_ssl_set_io(o,v) rb_iv_set((o),"@io",(v)) 00087 #define ossl_ssl_set_ctx(o,v) rb_iv_set((o),"@context",(v)) 00088 #define ossl_ssl_set_sync_close(o,v) rb_iv_set((o),"@sync_close",(v)) 00089 #define ossl_ssl_set_x509(o,v) rb_iv_set((o),"@x509",(v)) 00090 #define ossl_ssl_set_key(o,v) rb_iv_set((o),"@key",(v)) 00091 #define ossl_ssl_set_tmp_dh(o,v) rb_iv_set((o),"@tmp_dh",(v)) 00092 00093 static const char *ossl_ssl_attr_readers[] = { "io", "context", }; 00094 static const char *ossl_ssl_attrs[] = { 00095 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME 00096 "hostname", 00097 #endif 00098 "sync_close", 00099 }; 00100 00101 ID ID_callback_state; 00102 00103 /* 00104 * SSLContext class 00105 */ 00106 struct { 00107 const char *name; 00108 SSL_METHOD *(*func)(void); 00109 } ossl_ssl_method_tab[] = { 00110 #define OSSL_SSL_METHOD_ENTRY(name) { #name, (SSL_METHOD *(*)(void))name##_method } 00111 OSSL_SSL_METHOD_ENTRY(TLSv1), 00112 OSSL_SSL_METHOD_ENTRY(TLSv1_server), 00113 OSSL_SSL_METHOD_ENTRY(TLSv1_client), 00114 #if defined(HAVE_TLSV1_2_METHOD) && defined(HAVE_TLSV1_2_SERVER_METHOD) && \ 00115 defined(HAVE_TLSV1_2_CLIENT_METHOD) 00116 OSSL_SSL_METHOD_ENTRY(TLSv1_2), 00117 OSSL_SSL_METHOD_ENTRY(TLSv1_2_server), 00118 OSSL_SSL_METHOD_ENTRY(TLSv1_2_client), 00119 #endif 00120 #if defined(HAVE_TLSV1_1_METHOD) && defined(HAVE_TLSV1_1_SERVER_METHOD) && \ 00121 defined(HAVE_TLSV1_1_CLIENT_METHOD) 00122 OSSL_SSL_METHOD_ENTRY(TLSv1_1), 00123 OSSL_SSL_METHOD_ENTRY(TLSv1_1_server), 00124 OSSL_SSL_METHOD_ENTRY(TLSv1_1_client), 00125 #endif 00126 #if defined(HAVE_SSLV2_METHOD) && defined(HAVE_SSLV2_SERVER_METHOD) && \ 00127 defined(HAVE_SSLV2_CLIENT_METHOD) 00128 OSSL_SSL_METHOD_ENTRY(SSLv2), 00129 OSSL_SSL_METHOD_ENTRY(SSLv2_server), 00130 OSSL_SSL_METHOD_ENTRY(SSLv2_client), 00131 #endif 00132 OSSL_SSL_METHOD_ENTRY(SSLv3), 00133 OSSL_SSL_METHOD_ENTRY(SSLv3_server), 00134 OSSL_SSL_METHOD_ENTRY(SSLv3_client), 00135 OSSL_SSL_METHOD_ENTRY(SSLv23), 00136 OSSL_SSL_METHOD_ENTRY(SSLv23_server), 00137 OSSL_SSL_METHOD_ENTRY(SSLv23_client), 00138 #undef OSSL_SSL_METHOD_ENTRY 00139 }; 00140 00141 int ossl_ssl_ex_vcb_idx; 00142 int ossl_ssl_ex_store_p; 00143 int ossl_ssl_ex_ptr_idx; 00144 int ossl_ssl_ex_client_cert_cb_idx; 00145 int ossl_ssl_ex_tmp_dh_callback_idx; 00146 00147 static void 00148 ossl_sslctx_free(SSL_CTX *ctx) 00149 { 00150 if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1) 00151 ctx->cert_store = NULL; 00152 SSL_CTX_free(ctx); 00153 } 00154 00155 static VALUE 00156 ossl_sslctx_s_alloc(VALUE klass) 00157 { 00158 SSL_CTX *ctx; 00159 long mode = SSL_MODE_ENABLE_PARTIAL_WRITE; 00160 00161 #ifdef SSL_MODE_RELEASE_BUFFERS 00162 mode |= SSL_MODE_RELEASE_BUFFERS; 00163 #endif 00164 00165 ctx = SSL_CTX_new(SSLv23_method()); 00166 if (!ctx) { 00167 ossl_raise(eSSLError, "SSL_CTX_new"); 00168 } 00169 SSL_CTX_set_mode(ctx, mode); 00170 return Data_Wrap_Struct(klass, 0, ossl_sslctx_free, ctx); 00171 } 00172 00173 /* 00174 * call-seq: 00175 * ctx.ssl_version = :TLSv1 00176 * ctx.ssl_version = "SSLv23_client" 00177 * 00178 * You can get a list of valid versions with OpenSSL::SSL::SSLContext::METHODS 00179 */ 00180 static VALUE 00181 ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method) 00182 { 00183 SSL_METHOD *method = NULL; 00184 const char *s; 00185 int i; 00186 00187 SSL_CTX *ctx; 00188 if(TYPE(ssl_method) == T_SYMBOL) 00189 s = rb_id2name(SYM2ID(ssl_method)); 00190 else 00191 s = StringValuePtr(ssl_method); 00192 for (i = 0; i < numberof(ossl_ssl_method_tab); i++) { 00193 if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) { 00194 method = ossl_ssl_method_tab[i].func(); 00195 break; 00196 } 00197 } 00198 if (!method) { 00199 ossl_raise(rb_eArgError, "unknown SSL method `%s'.", s); 00200 } 00201 Data_Get_Struct(self, SSL_CTX, ctx); 00202 if (SSL_CTX_set_ssl_version(ctx, method) != 1) { 00203 ossl_raise(eSSLError, "SSL_CTX_set_ssl_version"); 00204 } 00205 00206 return ssl_method; 00207 } 00208 00209 /* 00210 * call-seq: 00211 * SSLContext.new => ctx 00212 * SSLContext.new(:TLSv1) => ctx 00213 * SSLContext.new("SSLv23_client") => ctx 00214 * 00215 * You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS 00216 */ 00217 static VALUE 00218 ossl_sslctx_initialize(int argc, VALUE *argv, VALUE self) 00219 { 00220 VALUE ssl_method; 00221 int i; 00222 00223 for(i = 0; i < numberof(ossl_sslctx_attrs); i++){ 00224 char buf[32]; 00225 snprintf(buf, sizeof(buf), "@%s", ossl_sslctx_attrs[i]); 00226 rb_iv_set(self, buf, Qnil); 00227 } 00228 if (rb_scan_args(argc, argv, "01", &ssl_method) == 0){ 00229 return self; 00230 } 00231 ossl_sslctx_set_ssl_version(self, ssl_method); 00232 00233 return self; 00234 } 00235 00236 static VALUE 00237 ossl_call_client_cert_cb(VALUE obj) 00238 { 00239 VALUE cb, ary, cert, key; 00240 SSL *ssl; 00241 00242 Data_Get_Struct(obj, SSL, ssl); 00243 cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx); 00244 if (NIL_P(cb)) return Qfalse; 00245 ary = rb_funcall(cb, rb_intern("call"), 1, obj); 00246 Check_Type(ary, T_ARRAY); 00247 GetX509CertPtr(cert = rb_ary_entry(ary, 0)); 00248 GetPKeyPtr(key = rb_ary_entry(ary, 1)); 00249 ossl_ssl_set_x509(obj, cert); 00250 ossl_ssl_set_key(obj, key); 00251 00252 return Qtrue; 00253 } 00254 00255 static int 00256 ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey) 00257 { 00258 VALUE obj, success; 00259 00260 obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); 00261 success = rb_protect((VALUE(*)_((VALUE)))ossl_call_client_cert_cb, 00262 obj, NULL); 00263 if (!RTEST(success)) return 0; 00264 *x509 = DupX509CertPtr(ossl_ssl_get_x509(obj)); 00265 *pkey = DupPKeyPtr(ossl_ssl_get_key(obj)); 00266 00267 return 1; 00268 } 00269 00270 #if !defined(OPENSSL_NO_DH) 00271 static VALUE 00272 ossl_call_tmp_dh_callback(VALUE *args) 00273 { 00274 SSL *ssl; 00275 VALUE cb, dh; 00276 EVP_PKEY *pkey; 00277 00278 Data_Get_Struct(args[0], SSL, ssl); 00279 cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx); 00280 if (NIL_P(cb)) return Qfalse; 00281 dh = rb_funcall(cb, rb_intern("call"), 3, args[0], args[1], args[2]); 00282 pkey = GetPKeyPtr(dh); 00283 if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) return Qfalse; 00284 ossl_ssl_set_tmp_dh(args[0], dh); 00285 00286 return Qtrue; 00287 } 00288 00289 static DH* 00290 ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength) 00291 { 00292 VALUE args[3], success; 00293 00294 args[0] = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); 00295 args[1] = INT2FIX(is_export); 00296 args[2] = INT2FIX(keylength); 00297 success = rb_protect((VALUE(*)_((VALUE)))ossl_call_tmp_dh_callback, 00298 (VALUE)args, NULL); 00299 if (!RTEST(success)) return NULL; 00300 00301 return GetPKeyPtr(ossl_ssl_get_tmp_dh(args[0]))->pkey.dh; 00302 } 00303 00304 static DH* 00305 ossl_default_tmp_dh_callback(SSL *ssl, int is_export, int keylength) 00306 { 00307 rb_warning("using default DH parameters."); 00308 00309 switch(keylength){ 00310 case 512: 00311 return OSSL_DEFAULT_DH_512; 00312 case 1024: 00313 return OSSL_DEFAULT_DH_1024; 00314 } 00315 return NULL; 00316 } 00317 #endif /* OPENSSL_NO_DH */ 00318 00319 static int 00320 ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) 00321 { 00322 VALUE cb; 00323 SSL *ssl; 00324 00325 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); 00326 cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx); 00327 X509_STORE_CTX_set_ex_data(ctx, ossl_verify_cb_idx, (void*)cb); 00328 return ossl_verify_cb(preverify_ok, ctx); 00329 } 00330 00331 static VALUE 00332 ossl_call_session_get_cb(VALUE ary) 00333 { 00334 VALUE ssl_obj, sslctx_obj, cb; 00335 00336 Check_Type(ary, T_ARRAY); 00337 ssl_obj = rb_ary_entry(ary, 0); 00338 00339 sslctx_obj = rb_iv_get(ssl_obj, "@context"); 00340 if (NIL_P(sslctx_obj)) return Qnil; 00341 cb = rb_iv_get(sslctx_obj, "@session_get_cb"); 00342 if (NIL_P(cb)) return Qnil; 00343 00344 return rb_funcall(cb, rb_intern("call"), 1, ary); 00345 } 00346 00347 /* this method is currently only called for servers (in OpenSSL <= 0.9.8e) */ 00348 static SSL_SESSION * 00349 ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy) 00350 { 00351 VALUE ary, ssl_obj, ret_obj; 00352 SSL_SESSION *sess; 00353 void *ptr; 00354 int state = 0; 00355 00356 OSSL_Debug("SSL SESSION get callback entered"); 00357 if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL) 00358 return NULL; 00359 ssl_obj = (VALUE)ptr; 00360 ary = rb_ary_new2(2); 00361 rb_ary_push(ary, ssl_obj); 00362 rb_ary_push(ary, rb_str_new((const char *)buf, len)); 00363 00364 ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_get_cb, ary, &state); 00365 if (state) { 00366 rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); 00367 return NULL; 00368 } 00369 if (!rb_obj_is_instance_of(ret_obj, cSSLSession)) 00370 return NULL; 00371 00372 SafeGetSSLSession(ret_obj, sess); 00373 *copy = 1; 00374 00375 return sess; 00376 } 00377 00378 static VALUE 00379 ossl_call_session_new_cb(VALUE ary) 00380 { 00381 VALUE ssl_obj, sslctx_obj, cb; 00382 00383 Check_Type(ary, T_ARRAY); 00384 ssl_obj = rb_ary_entry(ary, 0); 00385 00386 sslctx_obj = rb_iv_get(ssl_obj, "@context"); 00387 if (NIL_P(sslctx_obj)) return Qnil; 00388 cb = rb_iv_get(sslctx_obj, "@session_new_cb"); 00389 if (NIL_P(cb)) return Qnil; 00390 00391 return rb_funcall(cb, rb_intern("call"), 1, ary); 00392 } 00393 00394 /* return 1 normal. return 0 removes the session */ 00395 static int 00396 ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess) 00397 { 00398 VALUE ary, ssl_obj, sess_obj; 00399 void *ptr; 00400 int state = 0; 00401 00402 OSSL_Debug("SSL SESSION new callback entered"); 00403 00404 if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL) 00405 return 1; 00406 ssl_obj = (VALUE)ptr; 00407 sess_obj = rb_obj_alloc(cSSLSession); 00408 CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION); 00409 DATA_PTR(sess_obj) = sess; 00410 00411 ary = rb_ary_new2(2); 00412 rb_ary_push(ary, ssl_obj); 00413 rb_ary_push(ary, sess_obj); 00414 00415 rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state); 00416 if (state) { 00417 rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); 00418 } 00419 00420 /* 00421 * return 0 which means to OpenSSL that the the session is still 00422 * valid (since we created Ruby Session object) and was not freed by us 00423 * with SSL_SESSION_free(). Call SSLContext#remove_session(sess) in 00424 * session_get_cb block if you don't want OpenSSL to cache the session 00425 * internally. 00426 */ 00427 return 0; 00428 } 00429 00430 static VALUE 00431 ossl_call_session_remove_cb(VALUE ary) 00432 { 00433 VALUE sslctx_obj, cb; 00434 00435 Check_Type(ary, T_ARRAY); 00436 sslctx_obj = rb_ary_entry(ary, 0); 00437 00438 cb = rb_iv_get(sslctx_obj, "@session_remove_cb"); 00439 if (NIL_P(cb)) return Qnil; 00440 00441 return rb_funcall(cb, rb_intern("call"), 1, ary); 00442 } 00443 00444 static void 00445 ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess) 00446 { 00447 VALUE ary, sslctx_obj, sess_obj; 00448 void *ptr; 00449 int state = 0; 00450 00451 OSSL_Debug("SSL SESSION remove callback entered"); 00452 00453 if ((ptr = SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx)) == NULL) 00454 return; 00455 sslctx_obj = (VALUE)ptr; 00456 sess_obj = rb_obj_alloc(cSSLSession); 00457 CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION); 00458 DATA_PTR(sess_obj) = sess; 00459 00460 ary = rb_ary_new2(2); 00461 rb_ary_push(ary, sslctx_obj); 00462 rb_ary_push(ary, sess_obj); 00463 00464 rb_protect((VALUE(*)_((VALUE)))ossl_call_session_remove_cb, ary, &state); 00465 if (state) { 00466 /* 00467 the SSL_CTX is frozen, nowhere to save state. 00468 there is no common accessor method to check it either. 00469 rb_ivar_set(sslctx_obj, ID_callback_state, INT2NUM(state)); 00470 */ 00471 } 00472 } 00473 00474 static VALUE 00475 ossl_sslctx_add_extra_chain_cert_i(VALUE i, VALUE arg) 00476 { 00477 X509 *x509; 00478 SSL_CTX *ctx; 00479 00480 Data_Get_Struct(arg, SSL_CTX, ctx); 00481 x509 = DupX509CertPtr(i); 00482 if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){ 00483 ossl_raise(eSSLError, NULL); 00484 } 00485 00486 return i; 00487 } 00488 00489 static VALUE ossl_sslctx_setup(VALUE self); 00490 00491 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME 00492 static VALUE 00493 ossl_call_servername_cb(VALUE ary) 00494 { 00495 VALUE ssl_obj, sslctx_obj, cb, ret_obj; 00496 00497 Check_Type(ary, T_ARRAY); 00498 ssl_obj = rb_ary_entry(ary, 0); 00499 00500 sslctx_obj = rb_iv_get(ssl_obj, "@context"); 00501 if (NIL_P(sslctx_obj)) return Qnil; 00502 cb = rb_iv_get(sslctx_obj, "@servername_cb"); 00503 if (NIL_P(cb)) return Qnil; 00504 00505 ret_obj = rb_funcall(cb, rb_intern("call"), 1, ary); 00506 if (rb_obj_is_kind_of(ret_obj, cSSLContext)) { 00507 SSL *ssl; 00508 SSL_CTX *ctx2; 00509 00510 ossl_sslctx_setup(ret_obj); 00511 Data_Get_Struct(ssl_obj, SSL, ssl); 00512 Data_Get_Struct(ret_obj, SSL_CTX, ctx2); 00513 SSL_set_SSL_CTX(ssl, ctx2); 00514 } else if (!NIL_P(ret_obj)) { 00515 ossl_raise(rb_eArgError, "servername_cb must return an OpenSSL::SSL::SSLContext object or nil"); 00516 } 00517 00518 return ret_obj; 00519 } 00520 00521 static int 00522 ssl_servername_cb(SSL *ssl, int *ad, void *arg) 00523 { 00524 VALUE ary, ssl_obj; 00525 void *ptr; 00526 int state = 0; 00527 const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); 00528 00529 if (!servername) 00530 return SSL_TLSEXT_ERR_OK; 00531 00532 if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL) 00533 return SSL_TLSEXT_ERR_ALERT_FATAL; 00534 ssl_obj = (VALUE)ptr; 00535 ary = rb_ary_new2(2); 00536 rb_ary_push(ary, ssl_obj); 00537 rb_ary_push(ary, rb_str_new2(servername)); 00538 00539 rb_protect((VALUE(*)_((VALUE)))ossl_call_servername_cb, ary, &state); 00540 if (state) { 00541 rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); 00542 return SSL_TLSEXT_ERR_ALERT_FATAL; 00543 } 00544 00545 return SSL_TLSEXT_ERR_OK; 00546 } 00547 #endif 00548 00549 static void 00550 ssl_renegotiation_cb(const SSL *ssl) 00551 { 00552 VALUE ssl_obj, sslctx_obj, cb; 00553 void *ptr; 00554 00555 if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL) 00556 ossl_raise(eSSLError, "SSL object could not be retrieved"); 00557 ssl_obj = (VALUE)ptr; 00558 00559 sslctx_obj = rb_iv_get(ssl_obj, "@context"); 00560 if (NIL_P(sslctx_obj)) return; 00561 cb = rb_iv_get(sslctx_obj, "@renegotiation_cb"); 00562 if (NIL_P(cb)) return; 00563 00564 (void) rb_funcall(cb, rb_intern("call"), 1, ssl_obj); 00565 } 00566 00567 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED 00568 static VALUE 00569 ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded) 00570 { 00571 int len = RSTRING_LENINT(cur); 00572 char len_byte; 00573 if (len < 1 || len > 255) 00574 ossl_raise(eSSLError, "Advertised protocol must have length 1..255"); 00575 /* Encode the length byte */ 00576 len_byte = len; 00577 rb_str_buf_cat(encoded, &len_byte, 1); 00578 rb_str_buf_cat(encoded, RSTRING_PTR(cur), len); 00579 return Qnil; 00580 } 00581 00582 static void 00583 ssl_npn_encode_protocols(VALUE sslctx, VALUE protocols) 00584 { 00585 VALUE encoded = rb_str_new2(""); 00586 rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded); 00587 StringValueCStr(encoded); 00588 rb_iv_set(sslctx, "@_protocols", encoded); 00589 } 00590 00591 static int 00592 ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg) 00593 { 00594 VALUE sslctx_obj = (VALUE) arg; 00595 VALUE protocols = rb_iv_get(sslctx_obj, "@_protocols"); 00596 00597 *out = (const unsigned char *) RSTRING_PTR(protocols); 00598 *outlen = RSTRING_LENINT(protocols); 00599 00600 return SSL_TLSEXT_ERR_OK; 00601 } 00602 00603 static int 00604 ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) 00605 { 00606 int i = 0; 00607 VALUE sslctx_obj, cb, protocols, selected; 00608 00609 sslctx_obj = (VALUE) arg; 00610 cb = rb_iv_get(sslctx_obj, "@npn_select_cb"); 00611 protocols = rb_ary_new(); 00612 00613 /* The format is len_1|proto_1|...|len_n|proto_n\0 */ 00614 while (in[i]) { 00615 VALUE protocol = rb_str_new((const char *) &in[i + 1], in[i]); 00616 rb_ary_push(protocols, protocol); 00617 i += in[i] + 1; 00618 } 00619 00620 selected = rb_funcall(cb, rb_intern("call"), 1, protocols); 00621 StringValue(selected); 00622 *out = (unsigned char *) StringValuePtr(selected); 00623 *outlen = RSTRING_LENINT(selected); 00624 00625 return SSL_TLSEXT_ERR_OK; 00626 } 00627 #endif 00628 00629 /* This function may serve as the entry point to support further 00630 * callbacks. */ 00631 static void 00632 ssl_info_cb(const SSL *ssl, int where, int val) 00633 { 00634 int state = SSL_state(ssl); 00635 00636 if ((where & SSL_CB_HANDSHAKE_START) && 00637 (state & SSL_ST_ACCEPT)) { 00638 ssl_renegotiation_cb(ssl); 00639 } 00640 } 00641 00642 /* 00643 * call-seq: 00644 * ctx.setup => Qtrue # first time 00645 * ctx.setup => nil # thereafter 00646 * 00647 * This method is called automatically when a new SSLSocket is created. 00648 * Normally you do not need to call this method (unless you are writing an 00649 * extension in C). 00650 */ 00651 static VALUE 00652 ossl_sslctx_setup(VALUE self) 00653 { 00654 SSL_CTX *ctx; 00655 X509 *cert = NULL, *client_ca = NULL; 00656 X509_STORE *store; 00657 EVP_PKEY *key = NULL; 00658 char *ca_path = NULL, *ca_file = NULL; 00659 int i, verify_mode; 00660 VALUE val; 00661 00662 if(OBJ_FROZEN(self)) return Qnil; 00663 Data_Get_Struct(self, SSL_CTX, ctx); 00664 00665 #if !defined(OPENSSL_NO_DH) 00666 if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){ 00667 SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); 00668 } 00669 else{ 00670 SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback); 00671 } 00672 #endif 00673 SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self); 00674 00675 val = ossl_sslctx_get_cert_store(self); 00676 if(!NIL_P(val)){ 00677 /* 00678 * WORKAROUND: 00679 * X509_STORE can count references, but 00680 * X509_STORE_free() doesn't care it. 00681 * So we won't increment it but mark it by ex_data. 00682 */ 00683 store = GetX509StorePtr(val); /* NO NEED TO DUP */ 00684 SSL_CTX_set_cert_store(ctx, store); 00685 SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1); 00686 } 00687 00688 val = ossl_sslctx_get_extra_cert(self); 00689 if(!NIL_P(val)){ 00690 rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self); 00691 } 00692 00693 /* private key may be bundled in certificate file. */ 00694 val = ossl_sslctx_get_cert(self); 00695 cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */ 00696 val = ossl_sslctx_get_key(self); 00697 key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */ 00698 if (cert && key) { 00699 if (!SSL_CTX_use_certificate(ctx, cert)) { 00700 /* Adds a ref => Safe to FREE */ 00701 ossl_raise(eSSLError, "SSL_CTX_use_certificate"); 00702 } 00703 if (!SSL_CTX_use_PrivateKey(ctx, key)) { 00704 /* Adds a ref => Safe to FREE */ 00705 ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey"); 00706 } 00707 if (!SSL_CTX_check_private_key(ctx)) { 00708 ossl_raise(eSSLError, "SSL_CTX_check_private_key"); 00709 } 00710 } 00711 00712 val = ossl_sslctx_get_client_ca(self); 00713 if(!NIL_P(val)){ 00714 if(TYPE(val) == T_ARRAY){ 00715 for(i = 0; i < RARRAY_LEN(val); i++){ 00716 client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]); 00717 if (!SSL_CTX_add_client_CA(ctx, client_ca)){ 00718 /* Copies X509_NAME => FREE it. */ 00719 ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); 00720 } 00721 } 00722 } 00723 else{ 00724 client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */ 00725 if (!SSL_CTX_add_client_CA(ctx, client_ca)){ 00726 /* Copies X509_NAME => FREE it. */ 00727 ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); 00728 } 00729 } 00730 } 00731 00732 val = ossl_sslctx_get_ca_file(self); 00733 ca_file = NIL_P(val) ? NULL : StringValuePtr(val); 00734 val = ossl_sslctx_get_ca_path(self); 00735 ca_path = NIL_P(val) ? NULL : StringValuePtr(val); 00736 if(ca_file || ca_path){ 00737 if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) 00738 rb_warning("can't set verify locations"); 00739 } 00740 00741 val = ossl_sslctx_get_verify_mode(self); 00742 verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val); 00743 SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback); 00744 if (RTEST(ossl_sslctx_get_client_cert_cb(self))) 00745 SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb); 00746 00747 val = ossl_sslctx_get_timeout(self); 00748 if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val)); 00749 00750 val = ossl_sslctx_get_verify_dep(self); 00751 if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val)); 00752 00753 val = ossl_sslctx_get_options(self); 00754 if(!NIL_P(val)) { 00755 SSL_CTX_set_options(ctx, NUM2LONG(val)); 00756 } else { 00757 SSL_CTX_set_options(ctx, SSL_OP_ALL); 00758 } 00759 00760 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED 00761 val = rb_iv_get(self, "@npn_protocols"); 00762 if (!NIL_P(val)) { 00763 ssl_npn_encode_protocols(self, val); 00764 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *) self); 00765 OSSL_Debug("SSL NPN advertise callback added"); 00766 } 00767 if (RTEST(rb_iv_get(self, "@npn_select_cb"))) { 00768 SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self); 00769 OSSL_Debug("SSL NPN select callback added"); 00770 } 00771 #endif 00772 00773 rb_obj_freeze(self); 00774 00775 val = ossl_sslctx_get_sess_id_ctx(self); 00776 if (!NIL_P(val)){ 00777 StringValue(val); 00778 if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val), 00779 RSTRING_LENINT(val))){ 00780 ossl_raise(eSSLError, "SSL_CTX_set_session_id_context"); 00781 } 00782 } 00783 00784 if (RTEST(rb_iv_get(self, "@session_get_cb"))) { 00785 SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb); 00786 OSSL_Debug("SSL SESSION get callback added"); 00787 } 00788 if (RTEST(rb_iv_get(self, "@session_new_cb"))) { 00789 SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb); 00790 OSSL_Debug("SSL SESSION new callback added"); 00791 } 00792 if (RTEST(rb_iv_get(self, "@session_remove_cb"))) { 00793 SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb); 00794 OSSL_Debug("SSL SESSION remove callback added"); 00795 } 00796 00797 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME 00798 val = rb_iv_get(self, "@servername_cb"); 00799 if (!NIL_P(val)) { 00800 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); 00801 OSSL_Debug("SSL TLSEXT servername callback added"); 00802 } 00803 #endif 00804 00805 return Qtrue; 00806 } 00807 00808 static VALUE 00809 ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher) 00810 { 00811 VALUE ary; 00812 int bits, alg_bits; 00813 00814 ary = rb_ary_new2(4); 00815 rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_name(cipher))); 00816 rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_version(cipher))); 00817 bits = SSL_CIPHER_get_bits(cipher, &alg_bits); 00818 rb_ary_push(ary, INT2FIX(bits)); 00819 rb_ary_push(ary, INT2FIX(alg_bits)); 00820 00821 return ary; 00822 } 00823 00824 /* 00825 * call-seq: 00826 * ctx.ciphers => [[name, version, bits, alg_bits], ...] 00827 * 00828 * The list of ciphers configured for this context. 00829 */ 00830 static VALUE 00831 ossl_sslctx_get_ciphers(VALUE self) 00832 { 00833 SSL_CTX *ctx; 00834 STACK_OF(SSL_CIPHER) *ciphers; 00835 SSL_CIPHER *cipher; 00836 VALUE ary; 00837 int i, num; 00838 00839 Data_Get_Struct(self, SSL_CTX, ctx); 00840 if(!ctx){ 00841 rb_warning("SSL_CTX is not initialized."); 00842 return Qnil; 00843 } 00844 ciphers = ctx->cipher_list; 00845 00846 if (!ciphers) 00847 return rb_ary_new(); 00848 00849 num = sk_SSL_CIPHER_num(ciphers); 00850 ary = rb_ary_new2(num); 00851 for(i = 0; i < num; i++){ 00852 cipher = sk_SSL_CIPHER_value(ciphers, i); 00853 rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher)); 00854 } 00855 return ary; 00856 } 00857 00858 /* 00859 * call-seq: 00860 * ctx.ciphers = "cipher1:cipher2:..." 00861 * ctx.ciphers = [name, ...] 00862 * ctx.ciphers = [[name, version, bits, alg_bits], ...] 00863 * 00864 * Sets the list of available ciphers for this context. Note in a server 00865 * context some ciphers require the appropriate certificates. For example, an 00866 * RSA cipher can only be chosen when an RSA certificate is available. 00867 * 00868 * See also OpenSSL::Cipher and OpenSSL::Cipher::ciphers 00869 */ 00870 static VALUE 00871 ossl_sslctx_set_ciphers(VALUE self, VALUE v) 00872 { 00873 SSL_CTX *ctx; 00874 VALUE str, elem; 00875 int i; 00876 00877 rb_check_frozen(self); 00878 if (NIL_P(v)) 00879 return v; 00880 else if (TYPE(v) == T_ARRAY) { 00881 str = rb_str_new(0, 0); 00882 for (i = 0; i < RARRAY_LEN(v); i++) { 00883 elem = rb_ary_entry(v, i); 00884 if (TYPE(elem) == T_ARRAY) elem = rb_ary_entry(elem, 0); 00885 elem = rb_String(elem); 00886 rb_str_append(str, elem); 00887 if (i < RARRAY_LEN(v)-1) rb_str_cat2(str, ":"); 00888 } 00889 } else { 00890 str = v; 00891 StringValue(str); 00892 } 00893 00894 Data_Get_Struct(self, SSL_CTX, ctx); 00895 if(!ctx){ 00896 ossl_raise(eSSLError, "SSL_CTX is not initialized."); 00897 return Qnil; 00898 } 00899 if (!SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(str))) { 00900 ossl_raise(eSSLError, "SSL_CTX_set_cipher_list"); 00901 } 00902 00903 return v; 00904 } 00905 00906 /* 00907 * call-seq: 00908 * ctx.session_add(session) -> true | false 00909 * 00910 * Adds +session+ to the session cache 00911 */ 00912 static VALUE 00913 ossl_sslctx_session_add(VALUE self, VALUE arg) 00914 { 00915 SSL_CTX *ctx; 00916 SSL_SESSION *sess; 00917 00918 Data_Get_Struct(self, SSL_CTX, ctx); 00919 SafeGetSSLSession(arg, sess); 00920 00921 return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse; 00922 } 00923 00924 /* 00925 * call-seq: 00926 * ctx.session_remove(session) -> true | false 00927 * 00928 * Removes +session+ from the session cache 00929 */ 00930 static VALUE 00931 ossl_sslctx_session_remove(VALUE self, VALUE arg) 00932 { 00933 SSL_CTX *ctx; 00934 SSL_SESSION *sess; 00935 00936 Data_Get_Struct(self, SSL_CTX, ctx); 00937 SafeGetSSLSession(arg, sess); 00938 00939 return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse; 00940 } 00941 00942 /* 00943 * call-seq: 00944 * ctx.session_cache_mode -> Integer 00945 * 00946 * The current session cache mode. 00947 */ 00948 static VALUE 00949 ossl_sslctx_get_session_cache_mode(VALUE self) 00950 { 00951 SSL_CTX *ctx; 00952 00953 Data_Get_Struct(self, SSL_CTX, ctx); 00954 00955 return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx)); 00956 } 00957 00958 /* 00959 * call-seq: 00960 * ctx.session_cache_mode=(integer) -> Integer 00961 * 00962 * Sets the SSL session cache mode. Bitwise-or together the desired 00963 * SESSION_CACHE_* constants to set. See SSL_CTX_set_session_cache_mode(3) for 00964 * details. 00965 */ 00966 static VALUE 00967 ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg) 00968 { 00969 SSL_CTX *ctx; 00970 00971 Data_Get_Struct(self, SSL_CTX, ctx); 00972 00973 SSL_CTX_set_session_cache_mode(ctx, NUM2LONG(arg)); 00974 00975 return arg; 00976 } 00977 00978 /* 00979 * call-seq: 00980 * ctx.session_cache_size -> Integer 00981 * 00982 * Returns the current session cache size. Zero is used to represent an 00983 * unlimited cache size. 00984 */ 00985 static VALUE 00986 ossl_sslctx_get_session_cache_size(VALUE self) 00987 { 00988 SSL_CTX *ctx; 00989 00990 Data_Get_Struct(self, SSL_CTX, ctx); 00991 00992 return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx)); 00993 } 00994 00995 /* 00996 * call-seq: 00997 * ctx.session_cache_size=(integer) -> Integer 00998 * 00999 * Sets the session cache size. Returns the previously valid session cache 01000 * size. Zero is used to represent an unlimited session cache size. 01001 */ 01002 static VALUE 01003 ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg) 01004 { 01005 SSL_CTX *ctx; 01006 01007 Data_Get_Struct(self, SSL_CTX, ctx); 01008 01009 SSL_CTX_sess_set_cache_size(ctx, NUM2LONG(arg)); 01010 01011 return arg; 01012 } 01013 01014 /* 01015 * call-seq: 01016 * ctx.session_cache_stats -> Hash 01017 * 01018 * Returns a Hash containing the following keys: 01019 * 01020 * :accept:: Number of started SSL/TLS handshakes in server mode 01021 * :accept_good:: Number of established SSL/TLS sessions in server mode 01022 * :accept_renegotiate:: Number of start renegotiations in server mode 01023 * :cache_full:: Number of sessions that were removed due to cache overflow 01024 * :cache_hits:: Number of successfully reused connections 01025 * :cache_misses:: Number of sessions proposed by clients that were not found 01026 * in the cache 01027 * :cache_num:: Number of sessions in the internal session cache 01028 * :cb_hits:: Number of sessions retrieved from the external cache in server 01029 * mode 01030 * :connect:: Number of started SSL/TLS handshakes in client mode 01031 * :connect_good:: Number of established SSL/TLS sessions in client mode 01032 * :connect_renegotiate:: Number of start renegotiations in client mode 01033 * :timeouts:: Number of sessions proposed by clients that were found in the 01034 * cache but had expired due to timeouts 01035 */ 01036 static VALUE 01037 ossl_sslctx_get_session_cache_stats(VALUE self) 01038 { 01039 SSL_CTX *ctx; 01040 VALUE hash; 01041 01042 Data_Get_Struct(self, SSL_CTX, ctx); 01043 01044 hash = rb_hash_new(); 01045 rb_hash_aset(hash, ID2SYM(rb_intern("cache_num")), LONG2NUM(SSL_CTX_sess_number(ctx))); 01046 rb_hash_aset(hash, ID2SYM(rb_intern("connect")), LONG2NUM(SSL_CTX_sess_connect(ctx))); 01047 rb_hash_aset(hash, ID2SYM(rb_intern("connect_good")), LONG2NUM(SSL_CTX_sess_connect_good(ctx))); 01048 rb_hash_aset(hash, ID2SYM(rb_intern("connect_renegotiate")), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx))); 01049 rb_hash_aset(hash, ID2SYM(rb_intern("accept")), LONG2NUM(SSL_CTX_sess_accept(ctx))); 01050 rb_hash_aset(hash, ID2SYM(rb_intern("accept_good")), LONG2NUM(SSL_CTX_sess_accept_good(ctx))); 01051 rb_hash_aset(hash, ID2SYM(rb_intern("accept_renegotiate")), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx))); 01052 rb_hash_aset(hash, ID2SYM(rb_intern("cache_hits")), LONG2NUM(SSL_CTX_sess_hits(ctx))); 01053 rb_hash_aset(hash, ID2SYM(rb_intern("cb_hits")), LONG2NUM(SSL_CTX_sess_cb_hits(ctx))); 01054 rb_hash_aset(hash, ID2SYM(rb_intern("cache_misses")), LONG2NUM(SSL_CTX_sess_misses(ctx))); 01055 rb_hash_aset(hash, ID2SYM(rb_intern("cache_full")), LONG2NUM(SSL_CTX_sess_cache_full(ctx))); 01056 rb_hash_aset(hash, ID2SYM(rb_intern("timeouts")), LONG2NUM(SSL_CTX_sess_timeouts(ctx))); 01057 01058 return hash; 01059 } 01060 01061 01062 /* 01063 * call-seq: 01064 * ctx.flush_sessions(time | nil) -> self 01065 * 01066 * Removes sessions in the internal cache that have expired at +time+. 01067 */ 01068 static VALUE 01069 ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self) 01070 { 01071 VALUE arg1; 01072 SSL_CTX *ctx; 01073 time_t tm = 0; 01074 01075 rb_scan_args(argc, argv, "01", &arg1); 01076 01077 Data_Get_Struct(self, SSL_CTX, ctx); 01078 01079 if (NIL_P(arg1)) { 01080 tm = time(0); 01081 } else if (rb_obj_is_instance_of(arg1, rb_cTime)) { 01082 tm = NUM2LONG(rb_funcall(arg1, rb_intern("to_i"), 0)); 01083 } else { 01084 ossl_raise(rb_eArgError, "arg must be Time or nil"); 01085 } 01086 01087 SSL_CTX_flush_sessions(ctx, (long)tm); 01088 01089 return self; 01090 } 01091 01092 /* 01093 * SSLSocket class 01094 */ 01095 static void 01096 ossl_ssl_shutdown(SSL *ssl) 01097 { 01098 int i, rc; 01099 01100 if (ssl) { 01101 /* 4 is from SSL_smart_shutdown() of mod_ssl.c (v2.2.19) */ 01102 /* It says max 2x pending + 2x data = 4 */ 01103 for (i = 0; i < 4; ++i) { 01104 /* 01105 * Ignore the case SSL_shutdown returns -1. Empty handshake_func 01106 * must not happen. 01107 */ 01108 if (rc = SSL_shutdown(ssl)) 01109 break; 01110 } 01111 SSL_clear(ssl); 01112 ERR_clear_error(); 01113 } 01114 } 01115 01116 static void 01117 ossl_ssl_free(SSL *ssl) 01118 { 01119 SSL_free(ssl); 01120 } 01121 01122 static VALUE 01123 ossl_ssl_s_alloc(VALUE klass) 01124 { 01125 return Data_Wrap_Struct(klass, 0, ossl_ssl_free, NULL); 01126 } 01127 01128 /* 01129 * call-seq: 01130 * SSLSocket.new(io) => aSSLSocket 01131 * SSLSocket.new(io, ctx) => aSSLSocket 01132 * 01133 * Creates a new SSL socket from +io+ which must be a real ruby object (not an 01134 * IO-like object that responds to read/write. 01135 * 01136 * If +ctx+ is provided the SSL Sockets initial params will be taken from 01137 * the context. 01138 * 01139 * The OpenSSL::Buffering module provides additional IO methods. 01140 * 01141 * This method will freeze the SSLContext if one is provided; 01142 * however, session management is still allowed in the frozen SSLContext. 01143 */ 01144 static VALUE 01145 ossl_ssl_initialize(int argc, VALUE *argv, VALUE self) 01146 { 01147 VALUE io, ctx; 01148 01149 if (rb_scan_args(argc, argv, "11", &io, &ctx) == 1) { 01150 ctx = rb_funcall(cSSLContext, rb_intern("new"), 0); 01151 } 01152 OSSL_Check_Kind(ctx, cSSLContext); 01153 Check_Type(io, T_FILE); 01154 ossl_ssl_set_io(self, io); 01155 ossl_ssl_set_ctx(self, ctx); 01156 ossl_ssl_set_sync_close(self, Qfalse); 01157 ossl_sslctx_setup(ctx); 01158 01159 rb_iv_set(self, "@hostname", Qnil); 01160 01161 rb_call_super(0, 0); 01162 01163 return self; 01164 } 01165 01166 static VALUE 01167 ossl_ssl_setup(VALUE self) 01168 { 01169 VALUE io, v_ctx, cb; 01170 SSL_CTX *ctx; 01171 SSL *ssl; 01172 rb_io_t *fptr; 01173 01174 Data_Get_Struct(self, SSL, ssl); 01175 if(!ssl){ 01176 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME 01177 VALUE hostname = rb_iv_get(self, "@hostname"); 01178 #endif 01179 01180 v_ctx = ossl_ssl_get_ctx(self); 01181 Data_Get_Struct(v_ctx, SSL_CTX, ctx); 01182 01183 ssl = SSL_new(ctx); 01184 if (!ssl) { 01185 ossl_raise(eSSLError, "SSL_new"); 01186 } 01187 DATA_PTR(self) = ssl; 01188 01189 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME 01190 if (!NIL_P(hostname)) { 01191 if (SSL_set_tlsext_host_name(ssl, StringValuePtr(hostname)) != 1) 01192 ossl_raise(eSSLError, "SSL_set_tlsext_host_name"); 01193 } 01194 #endif 01195 io = ossl_ssl_get_io(self); 01196 GetOpenFile(io, fptr); 01197 rb_io_check_readable(fptr); 01198 rb_io_check_writable(fptr); 01199 SSL_set_fd(ssl, TO_SOCKET(FPTR_TO_FD(fptr))); 01200 SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void*)self); 01201 cb = ossl_sslctx_get_verify_cb(v_ctx); 01202 SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void*)cb); 01203 cb = ossl_sslctx_get_client_cert_cb(v_ctx); 01204 SSL_set_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx, (void*)cb); 01205 cb = ossl_sslctx_get_tmp_dh_cb(v_ctx); 01206 SSL_set_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx, (void*)cb); 01207 SSL_set_info_callback(ssl, ssl_info_cb); 01208 } 01209 01210 return Qtrue; 01211 } 01212 01213 #ifdef _WIN32 01214 #define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret))) 01215 #else 01216 #define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret)) 01217 #endif 01218 01219 #define ossl_ssl_data_get_struct(v, ssl) \ 01220 do { \ 01221 Data_Get_Struct((v), SSL, (ssl)); \ 01222 if (!(ssl)) { \ 01223 rb_warning("SSL session is not started yet."); \ 01224 return Qnil; \ 01225 } \ 01226 } while (0) 01227 01228 static void 01229 write_would_block(int nonblock) 01230 { 01231 if (nonblock) { 01232 VALUE exc = ossl_exc_new(eSSLError, "write would block"); 01233 rb_extend_object(exc, rb_mWaitWritable); 01234 rb_exc_raise(exc); 01235 } 01236 } 01237 01238 static void 01239 read_would_block(int nonblock) 01240 { 01241 if (nonblock) { 01242 VALUE exc = ossl_exc_new(eSSLError, "read would block"); 01243 rb_extend_object(exc, rb_mWaitReadable); 01244 rb_exc_raise(exc); 01245 } 01246 } 01247 01248 static VALUE 01249 ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, int nonblock) 01250 { 01251 SSL *ssl; 01252 rb_io_t *fptr; 01253 int ret, ret2; 01254 VALUE cb_state; 01255 01256 rb_ivar_set(self, ID_callback_state, Qnil); 01257 01258 ossl_ssl_data_get_struct(self, ssl); 01259 01260 GetOpenFile(ossl_ssl_get_io(self), fptr); 01261 for(;;){ 01262 ret = func(ssl); 01263 01264 cb_state = rb_ivar_get(self, ID_callback_state); 01265 if (!NIL_P(cb_state)) 01266 rb_jump_tag(NUM2INT(cb_state)); 01267 01268 if (ret > 0) 01269 break; 01270 01271 switch((ret2 = ssl_get_error(ssl, ret))){ 01272 case SSL_ERROR_WANT_WRITE: 01273 write_would_block(nonblock); 01274 rb_io_wait_writable(FPTR_TO_FD(fptr)); 01275 continue; 01276 case SSL_ERROR_WANT_READ: 01277 read_would_block(nonblock); 01278 rb_io_wait_readable(FPTR_TO_FD(fptr)); 01279 continue; 01280 case SSL_ERROR_SYSCALL: 01281 if (errno) rb_sys_fail(funcname); 01282 ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl)); 01283 default: 01284 ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl)); 01285 } 01286 } 01287 01288 return self; 01289 } 01290 01291 /* 01292 * call-seq: 01293 * ssl.connect => self 01294 * 01295 * Initiates an SSL/TLS handshake with a server. The handshake may be started 01296 * after unencrypted data has been sent over the socket. 01297 */ 01298 static VALUE 01299 ossl_ssl_connect(VALUE self) 01300 { 01301 ossl_ssl_setup(self); 01302 return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0); 01303 } 01304 01305 /* 01306 * call-seq: 01307 * ssl.connect_nonblock => self 01308 * 01309 * Initiates the SSL/TLS handshake as a client in non-blocking manner. 01310 * 01311 * # emulates blocking connect 01312 * begin 01313 * ssl.connect_nonblock 01314 * rescue IO::WaitReadable 01315 * IO.select([s2]) 01316 * retry 01317 * rescue IO::WaitWritable 01318 * IO.select(nil, [s2]) 01319 * retry 01320 * end 01321 * 01322 */ 01323 static VALUE 01324 ossl_ssl_connect_nonblock(VALUE self) 01325 { 01326 ossl_ssl_setup(self); 01327 return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1); 01328 } 01329 01330 /* 01331 * call-seq: 01332 * ssl.accept => self 01333 * 01334 * Waits for a SSL/TLS client to initiate a handshake. The handshake may be 01335 * started after unencrypted data has been sent over the socket. 01336 */ 01337 static VALUE 01338 ossl_ssl_accept(VALUE self) 01339 { 01340 ossl_ssl_setup(self); 01341 return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0); 01342 } 01343 01344 /* 01345 * call-seq: 01346 * ssl.accept_nonblock => self 01347 * 01348 * Initiates the SSL/TLS handshake as a server in non-blocking manner. 01349 * 01350 * # emulates blocking accept 01351 * begin 01352 * ssl.accept_nonblock 01353 * rescue IO::WaitReadable 01354 * IO.select([s2]) 01355 * retry 01356 * rescue IO::WaitWritable 01357 * IO.select(nil, [s2]) 01358 * retry 01359 * end 01360 * 01361 */ 01362 static VALUE 01363 ossl_ssl_accept_nonblock(VALUE self) 01364 { 01365 ossl_ssl_setup(self); 01366 return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1); 01367 } 01368 01369 static VALUE 01370 ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) 01371 { 01372 SSL *ssl; 01373 int ilen, nread = 0; 01374 VALUE len, str; 01375 rb_io_t *fptr; 01376 01377 rb_scan_args(argc, argv, "11", &len, &str); 01378 ilen = NUM2INT(len); 01379 if(NIL_P(str)) str = rb_str_new(0, ilen); 01380 else{ 01381 StringValue(str); 01382 rb_str_modify(str); 01383 rb_str_resize(str, ilen); 01384 } 01385 if(ilen == 0) return str; 01386 01387 Data_Get_Struct(self, SSL, ssl); 01388 GetOpenFile(ossl_ssl_get_io(self), fptr); 01389 if (ssl) { 01390 if(!nonblock && SSL_pending(ssl) <= 0) 01391 rb_thread_wait_fd(FPTR_TO_FD(fptr)); 01392 for (;;){ 01393 nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LENINT(str)); 01394 switch(ssl_get_error(ssl, nread)){ 01395 case SSL_ERROR_NONE: 01396 goto end; 01397 case SSL_ERROR_ZERO_RETURN: 01398 rb_eof_error(); 01399 case SSL_ERROR_WANT_WRITE: 01400 write_would_block(nonblock); 01401 rb_io_wait_writable(FPTR_TO_FD(fptr)); 01402 continue; 01403 case SSL_ERROR_WANT_READ: 01404 read_would_block(nonblock); 01405 rb_io_wait_readable(FPTR_TO_FD(fptr)); 01406 continue; 01407 case SSL_ERROR_SYSCALL: 01408 if(ERR_peek_error() == 0 && nread == 0) rb_eof_error(); 01409 rb_sys_fail(0); 01410 default: 01411 ossl_raise(eSSLError, "SSL_read"); 01412 } 01413 } 01414 } 01415 else { 01416 ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread"); 01417 rb_warning("SSL session is not started yet."); 01418 return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str); 01419 } 01420 01421 end: 01422 rb_str_set_len(str, nread); 01423 OBJ_TAINT(str); 01424 01425 return str; 01426 } 01427 01428 /* 01429 * call-seq: 01430 * ssl.sysread(length) => string 01431 * ssl.sysread(length, buffer) => buffer 01432 * 01433 * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+ 01434 * is provided the data will be written into it. 01435 */ 01436 static VALUE 01437 ossl_ssl_read(int argc, VALUE *argv, VALUE self) 01438 { 01439 return ossl_ssl_read_internal(argc, argv, self, 0); 01440 } 01441 01442 /* 01443 * call-seq: 01444 * ssl.sysread_nonblock(length) => string 01445 * ssl.sysread_nonblock(length, buffer) => buffer 01446 * 01447 * A non-blocking version of #sysread. Raises an SSLError if reading would 01448 * block. 01449 * 01450 * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+ 01451 * is provided the data will be written into it. 01452 */ 01453 static VALUE 01454 ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self) 01455 { 01456 return ossl_ssl_read_internal(argc, argv, self, 1); 01457 } 01458 01459 static VALUE 01460 ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock) 01461 { 01462 SSL *ssl; 01463 int nwrite = 0; 01464 rb_io_t *fptr; 01465 01466 StringValue(str); 01467 Data_Get_Struct(self, SSL, ssl); 01468 GetOpenFile(ossl_ssl_get_io(self), fptr); 01469 01470 if (ssl) { 01471 for (;;){ 01472 nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LENINT(str)); 01473 switch(ssl_get_error(ssl, nwrite)){ 01474 case SSL_ERROR_NONE: 01475 goto end; 01476 case SSL_ERROR_WANT_WRITE: 01477 write_would_block(nonblock); 01478 rb_io_wait_writable(FPTR_TO_FD(fptr)); 01479 continue; 01480 case SSL_ERROR_WANT_READ: 01481 read_would_block(nonblock); 01482 rb_io_wait_readable(FPTR_TO_FD(fptr)); 01483 continue; 01484 case SSL_ERROR_SYSCALL: 01485 if (errno) rb_sys_fail(0); 01486 default: 01487 ossl_raise(eSSLError, "SSL_write"); 01488 } 01489 } 01490 } 01491 else { 01492 ID id_syswrite = rb_intern("syswrite"); 01493 rb_warning("SSL session is not started yet."); 01494 return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str); 01495 } 01496 01497 end: 01498 return INT2NUM(nwrite); 01499 } 01500 01501 /* 01502 * call-seq: 01503 * ssl.syswrite(string) => Integer 01504 * 01505 * Writes +string+ to the SSL connection. 01506 */ 01507 static VALUE 01508 ossl_ssl_write(VALUE self, VALUE str) 01509 { 01510 return ossl_ssl_write_internal(self, str, 0); 01511 } 01512 01513 /* 01514 * call-seq: 01515 * ssl.syswrite_nonblock(string) => Integer 01516 * 01517 * Writes +string+ to the SSL connection in a non-blocking manner. Raises an 01518 * SSLError if writing would block. 01519 */ 01520 static VALUE 01521 ossl_ssl_write_nonblock(VALUE self, VALUE str) 01522 { 01523 return ossl_ssl_write_internal(self, str, 1); 01524 } 01525 01526 /* 01527 * call-seq: 01528 * ssl.sysclose => nil 01529 * 01530 * Shuts down the SSL connection and prepares it for another connection. 01531 */ 01532 static VALUE 01533 ossl_ssl_close(VALUE self) 01534 { 01535 SSL *ssl; 01536 01537 ossl_ssl_data_get_struct(self, ssl); 01538 01539 if (ssl) { 01540 VALUE io = ossl_ssl_get_io(self); 01541 if (!RTEST(rb_funcall(io, rb_intern("closed?"), 0))) { 01542 ossl_ssl_shutdown(ssl); 01543 SSL_free(ssl); 01544 DATA_PTR(self) = NULL; 01545 if (RTEST(ossl_ssl_get_sync_close(self))) 01546 rb_funcall(io, rb_intern("close"), 0); 01547 } 01548 } 01549 01550 return Qnil; 01551 } 01552 01553 /* 01554 * call-seq: 01555 * ssl.cert => cert or nil 01556 * 01557 * The X509 certificate for this socket endpoint. 01558 */ 01559 static VALUE 01560 ossl_ssl_get_cert(VALUE self) 01561 { 01562 SSL *ssl; 01563 X509 *cert = NULL; 01564 01565 ossl_ssl_data_get_struct(self, ssl); 01566 01567 /* 01568 * Is this OpenSSL bug? Should add a ref? 01569 * TODO: Ask for. 01570 */ 01571 cert = SSL_get_certificate(ssl); /* NO DUPs => DON'T FREE. */ 01572 01573 if (!cert) { 01574 return Qnil; 01575 } 01576 return ossl_x509_new(cert); 01577 } 01578 01579 /* 01580 * call-seq: 01581 * ssl.peer_cert => cert or nil 01582 * 01583 * The X509 certificate for this socket's peer. 01584 */ 01585 static VALUE 01586 ossl_ssl_get_peer_cert(VALUE self) 01587 { 01588 SSL *ssl; 01589 X509 *cert = NULL; 01590 VALUE obj; 01591 01592 ossl_ssl_data_get_struct(self, ssl); 01593 01594 cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */ 01595 01596 if (!cert) { 01597 return Qnil; 01598 } 01599 obj = ossl_x509_new(cert); 01600 X509_free(cert); 01601 01602 return obj; 01603 } 01604 01605 /* 01606 * call-seq: 01607 * ssl.peer_cert_chain => [cert, ...] or nil 01608 * 01609 * The X509 certificate chain for this socket's peer. 01610 */ 01611 static VALUE 01612 ossl_ssl_get_peer_cert_chain(VALUE self) 01613 { 01614 SSL *ssl; 01615 STACK_OF(X509) *chain; 01616 X509 *cert; 01617 VALUE ary; 01618 int i, num; 01619 01620 ossl_ssl_data_get_struct(self, ssl); 01621 01622 chain = SSL_get_peer_cert_chain(ssl); 01623 if(!chain) return Qnil; 01624 num = sk_X509_num(chain); 01625 ary = rb_ary_new2(num); 01626 for (i = 0; i < num; i++){ 01627 cert = sk_X509_value(chain, i); 01628 rb_ary_push(ary, ossl_x509_new(cert)); 01629 } 01630 01631 return ary; 01632 } 01633 01634 /* 01635 * call-seq: 01636 * ssl.version => String 01637 * 01638 * Returns a String representing the SSL/TLS version that was negotiated 01639 * for the connection, for example "TLSv1.2". 01640 */ 01641 static VALUE 01642 ossl_ssl_get_version(VALUE self) 01643 { 01644 SSL *ssl; 01645 01646 ossl_ssl_data_get_struct(self, ssl); 01647 01648 return rb_str_new2(SSL_get_version(ssl)); 01649 } 01650 01651 /* 01652 * call-seq: 01653 * ssl.cipher => [name, version, bits, alg_bits] 01654 * 01655 * The cipher being used for the current connection 01656 */ 01657 static VALUE 01658 ossl_ssl_get_cipher(VALUE self) 01659 { 01660 SSL *ssl; 01661 SSL_CIPHER *cipher; 01662 01663 ossl_ssl_data_get_struct(self, ssl); 01664 01665 cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl); 01666 01667 return ossl_ssl_cipher_to_ary(cipher); 01668 } 01669 01670 /* 01671 * call-seq: 01672 * ssl.state => string 01673 * 01674 * A description of the current connection state. 01675 */ 01676 static VALUE 01677 ossl_ssl_get_state(VALUE self) 01678 { 01679 SSL *ssl; 01680 VALUE ret; 01681 01682 ossl_ssl_data_get_struct(self, ssl); 01683 01684 ret = rb_str_new2(SSL_state_string(ssl)); 01685 if (ruby_verbose) { 01686 rb_str_cat2(ret, ": "); 01687 rb_str_cat2(ret, SSL_state_string_long(ssl)); 01688 } 01689 return ret; 01690 } 01691 01692 /* 01693 * call-seq: 01694 * ssl.pending => Integer 01695 * 01696 * The number of bytes that are immediately available for reading 01697 */ 01698 static VALUE 01699 ossl_ssl_pending(VALUE self) 01700 { 01701 SSL *ssl; 01702 01703 ossl_ssl_data_get_struct(self, ssl); 01704 01705 return INT2NUM(SSL_pending(ssl)); 01706 } 01707 01708 /* 01709 * call-seq: 01710 * ssl.session_reused? -> true | false 01711 * 01712 * Returns true if a reused session was negotiated during the handshake. 01713 */ 01714 static VALUE 01715 ossl_ssl_session_reused(VALUE self) 01716 { 01717 SSL *ssl; 01718 01719 ossl_ssl_data_get_struct(self, ssl); 01720 01721 switch(SSL_session_reused(ssl)) { 01722 case 1: return Qtrue; 01723 case 0: return Qfalse; 01724 default: ossl_raise(eSSLError, "SSL_session_reused"); 01725 } 01726 01727 UNREACHABLE; 01728 } 01729 01730 /* 01731 * call-seq: 01732 * ssl.session = session -> session 01733 * 01734 * Sets the Session to be used when the connection is established. 01735 */ 01736 static VALUE 01737 ossl_ssl_set_session(VALUE self, VALUE arg1) 01738 { 01739 SSL *ssl; 01740 SSL_SESSION *sess; 01741 01742 /* why is ossl_ssl_setup delayed? */ 01743 ossl_ssl_setup(self); 01744 01745 ossl_ssl_data_get_struct(self, ssl); 01746 01747 SafeGetSSLSession(arg1, sess); 01748 01749 if (SSL_set_session(ssl, sess) != 1) 01750 ossl_raise(eSSLError, "SSL_set_session"); 01751 01752 return arg1; 01753 } 01754 01755 /* 01756 * call-seq: 01757 * ssl.verify_result => Integer 01758 * 01759 * Returns the result of the peer certificates verification. See verify(1) 01760 * for error values and descriptions. 01761 * 01762 * If no peer certificate was presented X509_V_OK is returned. 01763 */ 01764 static VALUE 01765 ossl_ssl_get_verify_result(VALUE self) 01766 { 01767 SSL *ssl; 01768 01769 ossl_ssl_data_get_struct(self, ssl); 01770 01771 return INT2FIX(SSL_get_verify_result(ssl)); 01772 } 01773 01774 /* 01775 * call-seq: 01776 * ssl.client_ca => [x509name, ...] 01777 * 01778 * Returns the list of client CAs. Please note that in contrast to 01779 * SSLContext#client_ca= no array of X509::Certificate is returned but 01780 * X509::Name instances of the CA's subject distinguished name. 01781 * 01782 * In server mode, returns the list set by SSLContext#client_ca=. 01783 * In client mode, returns the list of client CAs sent from the server. 01784 */ 01785 static VALUE 01786 ossl_ssl_get_client_ca_list(VALUE self) 01787 { 01788 SSL *ssl; 01789 STACK_OF(X509_NAME) *ca; 01790 01791 ossl_ssl_data_get_struct(self, ssl); 01792 01793 ca = SSL_get_client_CA_list(ssl); 01794 return ossl_x509name_sk2ary(ca); 01795 } 01796 01797 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED 01798 /* 01799 * call-seq: 01800 * ssl.npn_protocol => String 01801 * 01802 * Returns the protocol string that was finally selected by the client 01803 * during the handshake. 01804 */ 01805 static VALUE 01806 ossl_ssl_npn_protocol(VALUE self) 01807 { 01808 SSL *ssl; 01809 const unsigned char *out; 01810 unsigned int outlen; 01811 01812 ossl_ssl_data_get_struct(self, ssl); 01813 01814 SSL_get0_next_proto_negotiated(ssl, &out, &outlen); 01815 if (!outlen) 01816 return Qnil; 01817 else 01818 return rb_str_new((const char *) out, outlen); 01819 } 01820 #endif 01821 01822 void 01823 Init_ossl_ssl() 01824 { 01825 int i; 01826 VALUE ary; 01827 01828 #if 0 01829 mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ 01830 #endif 01831 01832 ID_callback_state = rb_intern("@callback_state"); 01833 01834 ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0); 01835 ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0); 01836 ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_ptr_idx",0,0,0); 01837 ossl_ssl_ex_client_cert_cb_idx = 01838 SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_client_cert_cb_idx",0,0,0); 01839 ossl_ssl_ex_tmp_dh_callback_idx = 01840 SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_tmp_dh_callback_idx",0,0,0); 01841 01842 /* Document-module: OpenSSL::SSL 01843 * 01844 * Use SSLContext to set up the parameters for a TLS (former SSL) 01845 * connection. Both client and server TLS connections are supported, 01846 * SSLSocket and SSLServer may be used in conjunction with an instance 01847 * of SSLContext to set up connections. 01848 */ 01849 mSSL = rb_define_module_under(mOSSL, "SSL"); 01850 /* Document-class: OpenSSL::SSL::SSLError 01851 * 01852 * Generic error class raised by SSLSocket and SSLContext. 01853 */ 01854 eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError); 01855 01856 Init_ossl_ssl_session(); 01857 01858 /* Document-class: OpenSSL::SSL::SSLContext 01859 * 01860 * An SSLContext is used to set various options regarding certificates, 01861 * algorithms, verification, session caching, etc. The SSLContext is 01862 * used to create an SSLSocket. 01863 * 01864 * All attributes must be set before creating an SSLSocket as the 01865 * SSLContext will be frozen afterward. 01866 * 01867 * The following attributes are available but don't show up in rdoc: 01868 * * ssl_version, cert, key, client_ca, ca_file, ca_path, timeout, 01869 * * verify_mode, verify_depth client_cert_cb, tmp_dh_callback, 01870 * * session_id_context, session_add_cb, session_new_cb, session_remove_cb 01871 */ 01872 cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject); 01873 rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc); 01874 01875 /* 01876 * Context certificate 01877 */ 01878 rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse); 01879 01880 /* 01881 * Context private key 01882 */ 01883 rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse); 01884 01885 /* 01886 * A certificate or Array of certificates that will be sent to the client. 01887 */ 01888 rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse); 01889 01890 /* 01891 * The path to a file containing a PEM-format CA certificate 01892 */ 01893 rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse); 01894 01895 /* 01896 * The path to a directory containing CA certificates in PEM format. 01897 * 01898 * Files are looked up by subject's X509 name's hash value. 01899 */ 01900 rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse); 01901 01902 /* 01903 * Maximum session lifetime. 01904 */ 01905 rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse); 01906 01907 /* 01908 * Session verification mode. 01909 * 01910 * Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE, 01911 * VERIFY_FAIL_IF_NO_PEER_CERT and defined on OpenSSL::SSL 01912 */ 01913 rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse); 01914 01915 /* 01916 * Number of CA certificates to walk when verifying a certificate chain. 01917 */ 01918 rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse); 01919 01920 /* 01921 * A callback for additional certificate verification. The callback is 01922 * invoked for each certificate in the chain. 01923 * 01924 * The callback is invoked with two values. +preverify_ok+ indicates 01925 * indicates if the verification was passed (true) or not (false). 01926 * +store_context+ is an OpenSSL::X509::StoreContext containing the 01927 * context used for certificate verification. 01928 * 01929 * If the callback returns false verification is stopped. 01930 */ 01931 rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse); 01932 01933 /* 01934 * Sets various OpenSSL options. 01935 */ 01936 rb_attr(cSSLContext, rb_intern("options"), 1, 1, Qfalse); 01937 01938 /* 01939 * An OpenSSL::X509::Store used for certificate verification 01940 */ 01941 rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse); 01942 01943 /* 01944 * An Array of extra X509 certificates to be added to the certificate 01945 * chain. 01946 */ 01947 rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse); 01948 01949 /* 01950 * A callback invoked when a client certificate is requested by a server 01951 * and no certificate has been set. 01952 * 01953 * The callback is invoked with a Session and must return an Array 01954 * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any 01955 * other value is returned the handshake is suspended. 01956 */ 01957 rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse); 01958 01959 /* 01960 * A callback invoked when DH parameters are required. 01961 * 01962 * The callback is invoked with the Session for the key exchange, an 01963 * flag indicating the use of an export cipher and the keylength 01964 * required. 01965 * 01966 * The callback must return an OpenSSL::PKey::DH instance of the correct 01967 * key length. 01968 */ 01969 rb_attr(cSSLContext, rb_intern("tmp_dh_callback"), 1, 1, Qfalse); 01970 01971 /* 01972 * Sets the context in which a session can be reused. This allows 01973 * sessions for multiple applications to be distinguished, for exapmle, by 01974 * name. 01975 */ 01976 rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse); 01977 01978 /* 01979 * A callback invoked on a server when a session is proposed by the client 01980 * but the session could not be found in the server's internal cache. 01981 * 01982 * The callback is invoked with the SSLSocket and session id. The 01983 * callback may return a Session from an external cache. 01984 */ 01985 rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse); 01986 01987 /* 01988 * A callback invoked when a new session was negotiatied. 01989 * 01990 * The callback is invoked with an SSLSocket. If false is returned the 01991 * session will be removed from the internal cache. 01992 */ 01993 rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse); 01994 01995 /* 01996 * A callback invoked when a session is removed from the internal cache. 01997 * 01998 * The callback is invoked with an SSLContext and a Session. 01999 */ 02000 rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse); 02001 02002 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME 02003 /* 02004 * A callback invoked at connect time to distinguish between multiple 02005 * server names. 02006 * 02007 * The callback is invoked with an SSLSocket and a server name. The 02008 * callback must return an SSLContext for the server name or nil. 02009 */ 02010 rb_attr(cSSLContext, rb_intern("servername_cb"), 1, 1, Qfalse); 02011 #endif 02012 /* 02013 * A callback invoked whenever a new handshake is initiated. May be used 02014 * to disable renegotiation entirely. 02015 * 02016 * The callback is invoked with the active SSLSocket. The callback's 02017 * return value is irrelevant, normal return indicates "approval" of the 02018 * renegotiation and will continue the process. To forbid renegotiation 02019 * and to cancel the process, an Error may be raised within the callback. 02020 * 02021 * === Disable client renegotiation 02022 * 02023 * When running a server, it is often desirable to disable client 02024 * renegotiation entirely. You may use a callback as follows to implement 02025 * this feature: 02026 * 02027 * num_handshakes = 0 02028 * ctx.renegotiation_cb = lambda do |ssl| 02029 * num_handshakes += 1 02030 * raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1 02031 * end 02032 */ 02033 rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse); 02034 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED 02035 /* 02036 * An Enumerable of Strings. Each String represents a protocol to be 02037 * advertised as the list of supported protocols for Next Protocol 02038 * Negotiation. Supported in OpenSSL 1.0.1 and higher. Has no effect 02039 * on the client side. If not set explicitly, the NPN extension will 02040 * not be sent by the server in the handshake. 02041 * 02042 * === Example 02043 * 02044 * ctx.npn_protocols = ["http/1.1", "spdy/2"] 02045 */ 02046 rb_attr(cSSLContext, rb_intern("npn_protocols"), 1, 1, Qfalse); 02047 /* 02048 * A callback invoked on the client side when the client needs to select 02049 * a protocol from the list sent by the server. Supported in OpenSSL 1.0.1 02050 * and higher. The client MUST select a protocol of those advertised by 02051 * the server. If none is acceptable, raising an error in the callback 02052 * will cause the handshake to fail. Not setting this callback explicitly 02053 * means not supporting the NPN extension on the client - any protocols 02054 * advertised by the server will be ignored. 02055 * 02056 * === Example 02057 * 02058 * ctx.npn_select_cb = lambda do |protocols| 02059 * #inspect the protocols and select one 02060 * protocols.first 02061 * end 02062 */ 02063 rb_attr(cSSLContext, rb_intern("npn_select_cb"), 1, 1, Qfalse); 02064 #endif 02065 02066 rb_define_alias(cSSLContext, "ssl_timeout", "timeout"); 02067 rb_define_alias(cSSLContext, "ssl_timeout=", "timeout="); 02068 rb_define_method(cSSLContext, "initialize", ossl_sslctx_initialize, -1); 02069 rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1); 02070 rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0); 02071 rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1); 02072 02073 rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0); 02074 02075 /* 02076 * No session caching for client or server 02077 */ 02078 rb_define_const(cSSLContext, "SESSION_CACHE_OFF", LONG2FIX(SSL_SESS_CACHE_OFF)); 02079 02080 /* 02081 * Client sessions are added to the session cache 02082 */ 02083 rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT", LONG2FIX(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */ 02084 02085 /* 02086 * Server sessions are added to the session cache 02087 */ 02088 rb_define_const(cSSLContext, "SESSION_CACHE_SERVER", LONG2FIX(SSL_SESS_CACHE_SERVER)); 02089 02090 /* 02091 * Both client and server sessions are added to the session cache 02092 */ 02093 rb_define_const(cSSLContext, "SESSION_CACHE_BOTH", LONG2FIX(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */ 02094 02095 /* 02096 * Normally the session cache is checked for expired sessions every 255 02097 * connections. Since this may lead to a delay that cannot be controlled, 02098 * the automatic flushing may be disabled and #flush_sessions can be 02099 * called explicitly. 02100 */ 02101 rb_define_const(cSSLContext, "SESSION_CACHE_NO_AUTO_CLEAR", LONG2FIX(SSL_SESS_CACHE_NO_AUTO_CLEAR)); 02102 02103 /* 02104 * Always perform external lookups of sessions even if they are in the 02105 * internal cache. 02106 * 02107 * This flag has no effect on clients 02108 */ 02109 rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_LOOKUP", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)); 02110 02111 /* 02112 * Never automatically store sessions in the internal store. 02113 */ 02114 rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_STORE", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_STORE)); 02115 02116 /* 02117 * Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and 02118 * SESSION_CACHE_NO_INTERNAL_STORE. 02119 */ 02120 rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL)); 02121 02122 rb_define_method(cSSLContext, "session_add", ossl_sslctx_session_add, 1); 02123 rb_define_method(cSSLContext, "session_remove", ossl_sslctx_session_remove, 1); 02124 rb_define_method(cSSLContext, "session_cache_mode", ossl_sslctx_get_session_cache_mode, 0); 02125 rb_define_method(cSSLContext, "session_cache_mode=", ossl_sslctx_set_session_cache_mode, 1); 02126 rb_define_method(cSSLContext, "session_cache_size", ossl_sslctx_get_session_cache_size, 0); 02127 rb_define_method(cSSLContext, "session_cache_size=", ossl_sslctx_set_session_cache_size, 1); 02128 rb_define_method(cSSLContext, "session_cache_stats", ossl_sslctx_get_session_cache_stats, 0); 02129 rb_define_method(cSSLContext, "flush_sessions", ossl_sslctx_flush_sessions, -1); 02130 02131 ary = rb_ary_new2(numberof(ossl_ssl_method_tab)); 02132 for (i = 0; i < numberof(ossl_ssl_method_tab); i++) { 02133 rb_ary_push(ary, ID2SYM(rb_intern(ossl_ssl_method_tab[i].name))); 02134 } 02135 rb_obj_freeze(ary); 02136 /* The list of available SSL/TLS methods */ 02137 rb_define_const(cSSLContext, "METHODS", ary); 02138 02139 /* 02140 * Document-class: OpenSSL::SSL::SSLSocket 02141 * 02142 * The following attributes are available but don't show up in rdoc. 02143 * * io, context, sync_close 02144 * 02145 */ 02146 cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject); 02147 rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc); 02148 for(i = 0; i < numberof(ossl_ssl_attr_readers); i++) 02149 rb_attr(cSSLSocket, rb_intern(ossl_ssl_attr_readers[i]), 1, 0, Qfalse); 02150 for(i = 0; i < numberof(ossl_ssl_attrs); i++) 02151 rb_attr(cSSLSocket, rb_intern(ossl_ssl_attrs[i]), 1, 1, Qfalse); 02152 rb_define_alias(cSSLSocket, "to_io", "io"); 02153 rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1); 02154 rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0); 02155 rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, 0); 02156 rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0); 02157 rb_define_method(cSSLSocket, "accept_nonblock", ossl_ssl_accept_nonblock, 0); 02158 rb_define_method(cSSLSocket, "sysread", ossl_ssl_read, -1); 02159 rb_define_private_method(cSSLSocket, "sysread_nonblock", ossl_ssl_read_nonblock, -1); 02160 rb_define_method(cSSLSocket, "syswrite", ossl_ssl_write, 1); 02161 rb_define_private_method(cSSLSocket, "syswrite_nonblock", ossl_ssl_write_nonblock, 1); 02162 rb_define_method(cSSLSocket, "sysclose", ossl_ssl_close, 0); 02163 rb_define_method(cSSLSocket, "cert", ossl_ssl_get_cert, 0); 02164 rb_define_method(cSSLSocket, "peer_cert", ossl_ssl_get_peer_cert, 0); 02165 rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0); 02166 rb_define_method(cSSLSocket, "ssl_version", ossl_ssl_get_version, 0); 02167 rb_define_method(cSSLSocket, "cipher", ossl_ssl_get_cipher, 0); 02168 rb_define_method(cSSLSocket, "state", ossl_ssl_get_state, 0); 02169 rb_define_method(cSSLSocket, "pending", ossl_ssl_pending, 0); 02170 rb_define_method(cSSLSocket, "session_reused?", ossl_ssl_session_reused, 0); 02171 /* implementation of OpenSSL::SSL::SSLSocket#session is in lib/openssl/ssl.rb */ 02172 rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1); 02173 rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0); 02174 rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0); 02175 #ifdef HAVE_OPENSSL_NPN_NEGOTIATED 02176 rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0); 02177 #endif 02178 02179 #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2NUM(SSL_##x)) 02180 02181 ossl_ssl_def_const(VERIFY_NONE); 02182 ossl_ssl_def_const(VERIFY_PEER); 02183 ossl_ssl_def_const(VERIFY_FAIL_IF_NO_PEER_CERT); 02184 ossl_ssl_def_const(VERIFY_CLIENT_ONCE); 02185 /* Introduce constants included in OP_ALL. These constants are mostly for 02186 * unset some bits in OP_ALL such as; 02187 * ctx.options = OP_ALL & ~OP_DONT_INSERT_EMPTY_FRAGMENTS 02188 */ 02189 ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG); 02190 ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG); 02191 ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG); 02192 ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG); 02193 ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER); 02194 ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING); 02195 ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG); 02196 ossl_ssl_def_const(OP_TLS_D5_BUG); 02197 ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG); 02198 ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS); 02199 ossl_ssl_def_const(OP_ALL); 02200 #if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION) 02201 ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); 02202 #endif 02203 #if defined(SSL_OP_SINGLE_ECDH_USE) 02204 ossl_ssl_def_const(OP_SINGLE_ECDH_USE); 02205 #endif 02206 ossl_ssl_def_const(OP_SINGLE_DH_USE); 02207 ossl_ssl_def_const(OP_EPHEMERAL_RSA); 02208 #if defined(SSL_OP_CIPHER_SERVER_PREFERENCE) 02209 ossl_ssl_def_const(OP_CIPHER_SERVER_PREFERENCE); 02210 #endif 02211 ossl_ssl_def_const(OP_TLS_ROLLBACK_BUG); 02212 ossl_ssl_def_const(OP_NO_SSLv2); 02213 ossl_ssl_def_const(OP_NO_SSLv3); 02214 ossl_ssl_def_const(OP_NO_TLSv1); 02215 #if defined(SSL_OP_NO_TLSv1_1) 02216 ossl_ssl_def_const(OP_NO_TLSv1_1); 02217 #endif 02218 #if defined(SSL_OP_NO_TLSv1_2) 02219 ossl_ssl_def_const(OP_NO_TLSv1_2); 02220 #endif 02221 #if defined(SSL_OP_NO_TICKET) 02222 ossl_ssl_def_const(OP_NO_TICKET); 02223 #endif 02224 #if defined(SSL_OP_NO_COMPRESSION) 02225 ossl_ssl_def_const(OP_NO_COMPRESSION); 02226 #endif 02227 ossl_ssl_def_const(OP_PKCS1_CHECK_1); 02228 ossl_ssl_def_const(OP_PKCS1_CHECK_2); 02229 ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG); 02230 ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); 02231 } 02232