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