Ruby  2.0.0p247(2013-06-27revision41674)
ext/openssl/ossl_ssl.c
Go to the documentation of this file.
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