Ruby 1.9.3p327(2012-11-10revision37606)
ext/openssl/ossl_ssl.c
Go to the documentation of this file.
00001 /*
00002  * $Id: ossl_ssl.c 34524 2012-02-09 17:04:41Z emboss $
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     ossl_ssl_shutdown(ssl);
00999     SSL_free(ssl);
01000 }
01001 
01002 static VALUE
01003 ossl_ssl_s_alloc(VALUE klass)
01004 {
01005     return Data_Wrap_Struct(klass, 0, ossl_ssl_free, NULL);
01006 }
01007 
01008 /*
01009  * call-seq:
01010  *    SSLSocket.new(io) => aSSLSocket
01011  *    SSLSocket.new(io, ctx) => aSSLSocket
01012  *
01013  * Creates a new SSL socket from +io+ which must be a real ruby object (not an
01014  * IO-like object that responds to read/write.
01015  *
01016  * If +ctx+ is provided the SSL Sockets initial params will be taken from
01017  * the context.
01018  *
01019  * The OpenSSL::Buffering module provides additional IO methods.
01020  *
01021  * This method will freeze the SSLContext if one is provided;
01022  * however, session management is still allowed in the frozen SSLContext.
01023  */
01024 static VALUE
01025 ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
01026 {
01027     VALUE io, ctx;
01028 
01029     if (rb_scan_args(argc, argv, "11", &io, &ctx) == 1) {
01030         ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
01031     }
01032     OSSL_Check_Kind(ctx, cSSLContext);
01033     Check_Type(io, T_FILE);
01034     ossl_ssl_set_io(self, io);
01035     ossl_ssl_set_ctx(self, ctx);
01036     ossl_ssl_set_sync_close(self, Qfalse);
01037     ossl_sslctx_setup(ctx);
01038 
01039     rb_iv_set(self, "@hostname", Qnil);
01040 
01041     rb_call_super(0, 0);
01042 
01043     return self;
01044 }
01045 
01046 static VALUE
01047 ossl_ssl_setup(VALUE self)
01048 {
01049     VALUE io, v_ctx, cb;
01050     SSL_CTX *ctx;
01051     SSL *ssl;
01052     rb_io_t *fptr;
01053 
01054     Data_Get_Struct(self, SSL, ssl);
01055     if(!ssl){
01056 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
01057         VALUE hostname = rb_iv_get(self, "@hostname");
01058 #endif
01059 
01060         v_ctx = ossl_ssl_get_ctx(self);
01061         Data_Get_Struct(v_ctx, SSL_CTX, ctx);
01062 
01063         ssl = SSL_new(ctx);
01064         if (!ssl) {
01065             ossl_raise(eSSLError, "SSL_new:");
01066         }
01067         DATA_PTR(self) = ssl;
01068 
01069 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
01070         if (!NIL_P(hostname)) {
01071            if (SSL_set_tlsext_host_name(ssl, StringValuePtr(hostname)) != 1)
01072                ossl_raise(eSSLError, "SSL_set_tlsext_host_name:");
01073         }
01074 #endif
01075         io = ossl_ssl_get_io(self);
01076         GetOpenFile(io, fptr);
01077         rb_io_check_readable(fptr);
01078         rb_io_check_writable(fptr);
01079         SSL_set_fd(ssl, TO_SOCKET(FPTR_TO_FD(fptr)));
01080         SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void*)self);
01081         cb = ossl_sslctx_get_verify_cb(v_ctx);
01082         SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void*)cb);
01083         cb = ossl_sslctx_get_client_cert_cb(v_ctx);
01084         SSL_set_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx, (void*)cb);
01085         cb = ossl_sslctx_get_tmp_dh_cb(v_ctx);
01086         SSL_set_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx, (void*)cb);
01087     }
01088 
01089     return Qtrue;
01090 }
01091 
01092 #ifdef _WIN32
01093 #define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
01094 #else
01095 #define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret))
01096 #endif
01097 
01098 static void
01099 write_would_block(int nonblock)
01100 {
01101     if (nonblock) {
01102         VALUE exc = ossl_exc_new(eSSLError, "write would block");
01103         rb_extend_object(exc, rb_mWaitWritable);
01104         rb_exc_raise(exc);
01105     }
01106 }
01107 
01108 static void
01109 read_would_block(int nonblock)
01110 {
01111     if (nonblock) {
01112         VALUE exc = ossl_exc_new(eSSLError, "read would block");
01113         rb_extend_object(exc, rb_mWaitReadable);
01114         rb_exc_raise(exc);
01115     }
01116 }
01117 
01118 static VALUE
01119 ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, int nonblock)
01120 {
01121     SSL *ssl;
01122     rb_io_t *fptr;
01123     int ret, ret2;
01124     VALUE cb_state;
01125 
01126     rb_ivar_set(self, ID_callback_state, Qnil);
01127 
01128     Data_Get_Struct(self, SSL, ssl);
01129     GetOpenFile(ossl_ssl_get_io(self), fptr);
01130     for(;;){
01131         ret = func(ssl);
01132 
01133         cb_state = rb_ivar_get(self, ID_callback_state);
01134         if (!NIL_P(cb_state))
01135             rb_jump_tag(NUM2INT(cb_state));
01136 
01137         if (ret > 0)
01138             break;
01139 
01140         switch((ret2 = ssl_get_error(ssl, ret))){
01141         case SSL_ERROR_WANT_WRITE:
01142             write_would_block(nonblock);
01143             rb_io_wait_writable(FPTR_TO_FD(fptr));
01144             continue;
01145         case SSL_ERROR_WANT_READ:
01146             read_would_block(nonblock);
01147             rb_io_wait_readable(FPTR_TO_FD(fptr));
01148             continue;
01149         case SSL_ERROR_SYSCALL:
01150             if (errno) rb_sys_fail(funcname);
01151             ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
01152         default:
01153             ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
01154         }
01155     }
01156 
01157     return self;
01158 }
01159 
01160 /*
01161  * call-seq:
01162  *    ssl.connect => self
01163  *
01164  * Initiates an SSL/TLS handshake with a server.  The handshake may be started
01165  * after unencrypted data has been sent over the socket.
01166  */
01167 static VALUE
01168 ossl_ssl_connect(VALUE self)
01169 {
01170     ossl_ssl_setup(self);
01171     return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0);
01172 }
01173 
01174 /*
01175  * call-seq:
01176  *    ssl.connect_nonblock => self
01177  *
01178  * Initiates the SSL/TLS handshake as a client in non-blocking manner.
01179  *
01180  *   # emulates blocking connect
01181  *   begin
01182  *     ssl.connect_nonblock
01183  *   rescue IO::WaitReadable
01184  *     IO.select([s2])
01185  *     retry
01186  *   rescue IO::WaitWritable
01187  *     IO.select(nil, [s2])
01188  *     retry
01189  *   end
01190  *
01191  */
01192 static VALUE
01193 ossl_ssl_connect_nonblock(VALUE self)
01194 {
01195     ossl_ssl_setup(self);
01196     return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1);
01197 }
01198 
01199 /*
01200  * call-seq:
01201  *    ssl.accept => self
01202  *
01203  * Waits for a SSL/TLS client to initiate a handshake.  The handshake may be
01204  * started after unencrypted data has been sent over the socket.
01205  */
01206 static VALUE
01207 ossl_ssl_accept(VALUE self)
01208 {
01209     ossl_ssl_setup(self);
01210     return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0);
01211 }
01212 
01213 /*
01214  * call-seq:
01215  *    ssl.accept_nonblock => self
01216  *
01217  * Initiates the SSL/TLS handshake as a server in non-blocking manner.
01218  *
01219  *   # emulates blocking accept
01220  *   begin
01221  *     ssl.accept_nonblock
01222  *   rescue IO::WaitReadable
01223  *     IO.select([s2])
01224  *     retry
01225  *   rescue IO::WaitWritable
01226  *     IO.select(nil, [s2])
01227  *     retry
01228  *   end
01229  *
01230  */
01231 static VALUE
01232 ossl_ssl_accept_nonblock(VALUE self)
01233 {
01234     ossl_ssl_setup(self);
01235     return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1);
01236 }
01237 
01238 static VALUE
01239 ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
01240 {
01241     SSL *ssl;
01242     int ilen, nread = 0;
01243     VALUE len, str;
01244     rb_io_t *fptr;
01245 
01246     rb_scan_args(argc, argv, "11", &len, &str);
01247     ilen = NUM2INT(len);
01248     if(NIL_P(str)) str = rb_str_new(0, ilen);
01249     else{
01250         StringValue(str);
01251         rb_str_modify(str);
01252         rb_str_resize(str, ilen);
01253     }
01254     if(ilen == 0) return str;
01255 
01256     Data_Get_Struct(self, SSL, ssl);
01257     GetOpenFile(ossl_ssl_get_io(self), fptr);
01258     if (ssl) {
01259         if(!nonblock && SSL_pending(ssl) <= 0)
01260             rb_thread_wait_fd(FPTR_TO_FD(fptr));
01261         for (;;){
01262             nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
01263             switch(ssl_get_error(ssl, nread)){
01264             case SSL_ERROR_NONE:
01265                 goto end;
01266             case SSL_ERROR_ZERO_RETURN:
01267                 rb_eof_error();
01268             case SSL_ERROR_WANT_WRITE:
01269                 write_would_block(nonblock);
01270                 rb_io_wait_writable(FPTR_TO_FD(fptr));
01271                 continue;
01272             case SSL_ERROR_WANT_READ:
01273                 read_would_block(nonblock);
01274                 rb_io_wait_readable(FPTR_TO_FD(fptr));
01275                 continue;
01276             case SSL_ERROR_SYSCALL:
01277                 if(ERR_peek_error() == 0 && nread == 0) rb_eof_error();
01278                 rb_sys_fail(0);
01279             default:
01280                 ossl_raise(eSSLError, "SSL_read:");
01281             }
01282         }
01283     }
01284     else {
01285         ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
01286         rb_warning("SSL session is not started yet.");
01287         return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str);
01288     }
01289 
01290   end:
01291     rb_str_set_len(str, nread);
01292     OBJ_TAINT(str);
01293 
01294     return str;
01295 }
01296 
01297 
01298 /*
01299  * call-seq:
01300  *    ssl.sysread(length) => string
01301  *    ssl.sysread(length, buffer) => buffer
01302  *
01303  * Reads +length+ bytes from the SSL connection.  If a pre-allocated +buffer+
01304  * is provided the data will be written into it.
01305  */
01306 static VALUE
01307 ossl_ssl_read(int argc, VALUE *argv, VALUE self)
01308 {
01309     return ossl_ssl_read_internal(argc, argv, self, 0);
01310 }
01311 
01312 /*
01313  * call-seq:
01314  *    ssl.sysread_nonblock(length) => string
01315  *    ssl.sysread_nonblock(length, buffer) => buffer
01316  *
01317  * A non-blocking version of #sysread.  Raises an SSLError if reading would
01318  * block.
01319  *
01320  * Reads +length+ bytes from the SSL connection.  If a pre-allocated +buffer+
01321  * is provided the data will be written into it.
01322  */
01323 static VALUE
01324 ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
01325 {
01326     return ossl_ssl_read_internal(argc, argv, self, 1);
01327 }
01328 
01329 static VALUE
01330 ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock)
01331 {
01332     SSL *ssl;
01333     int nwrite = 0;
01334     rb_io_t *fptr;
01335 
01336     StringValue(str);
01337     Data_Get_Struct(self, SSL, ssl);
01338     GetOpenFile(ossl_ssl_get_io(self), fptr);
01339 
01340     if (ssl) {
01341         for (;;){
01342             nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
01343             switch(ssl_get_error(ssl, nwrite)){
01344             case SSL_ERROR_NONE:
01345                 goto end;
01346             case SSL_ERROR_WANT_WRITE:
01347                 write_would_block(nonblock);
01348                 rb_io_wait_writable(FPTR_TO_FD(fptr));
01349                 continue;
01350             case SSL_ERROR_WANT_READ:
01351                 read_would_block(nonblock);
01352                 rb_io_wait_readable(FPTR_TO_FD(fptr));
01353                 continue;
01354             case SSL_ERROR_SYSCALL:
01355                 if (errno) rb_sys_fail(0);
01356             default:
01357                 ossl_raise(eSSLError, "SSL_write:");
01358             }
01359         }
01360     }
01361     else {
01362         ID id_syswrite = rb_intern("syswrite");
01363         rb_warning("SSL session is not started yet.");
01364         return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str);
01365     }
01366 
01367   end:
01368     return INT2NUM(nwrite);
01369 }
01370 
01371 /*
01372  * call-seq:
01373  *    ssl.syswrite(string) => Integer
01374  *
01375  * Writes +string+ to the SSL connection.
01376  */
01377 static VALUE
01378 ossl_ssl_write(VALUE self, VALUE str)
01379 {
01380     return ossl_ssl_write_internal(self, str, 0);
01381 }
01382 
01383 /*
01384  * call-seq:
01385  *    ssl.syswrite_nonblock(string) => Integer
01386  *
01387  * Writes +string+ to the SSL connection in a non-blocking manner.  Raises an
01388  * SSLError if writing would block.
01389  */
01390 static VALUE
01391 ossl_ssl_write_nonblock(VALUE self, VALUE str)
01392 {
01393     return ossl_ssl_write_internal(self, str, 1);
01394 }
01395 
01396 /*
01397  * call-seq:
01398  *    ssl.sysclose => nil
01399  *
01400  * Shuts down the SSL connection and prepares it for another connection.
01401  */
01402 static VALUE
01403 ossl_ssl_close(VALUE self)
01404 {
01405     SSL *ssl;
01406 
01407     Data_Get_Struct(self, SSL, ssl);
01408     ossl_ssl_shutdown(ssl);
01409     if (RTEST(ossl_ssl_get_sync_close(self)))
01410         rb_funcall(ossl_ssl_get_io(self), rb_intern("close"), 0);
01411 
01412     return Qnil;
01413 }
01414 
01415 /*
01416  * call-seq:
01417  *    ssl.cert => cert or nil
01418  *
01419  * The X509 certificate for this socket endpoint.
01420  */
01421 static VALUE
01422 ossl_ssl_get_cert(VALUE self)
01423 {
01424     SSL *ssl;
01425     X509 *cert = NULL;
01426 
01427     Data_Get_Struct(self, SSL, ssl);
01428     if (!ssl) {
01429         rb_warning("SSL session is not started yet.");
01430         return Qnil;
01431     }
01432 
01433     /*
01434      * Is this OpenSSL bug? Should add a ref?
01435      * TODO: Ask for.
01436      */
01437     cert = SSL_get_certificate(ssl); /* NO DUPs => DON'T FREE. */
01438 
01439     if (!cert) {
01440         return Qnil;
01441     }
01442     return ossl_x509_new(cert);
01443 }
01444 
01445 /*
01446  * call-seq:
01447  *    ssl.peer_cert => cert or nil
01448  *
01449  * The X509 certificate for this socket's peer.
01450  */
01451 static VALUE
01452 ossl_ssl_get_peer_cert(VALUE self)
01453 {
01454     SSL *ssl;
01455     X509 *cert = NULL;
01456     VALUE obj;
01457 
01458     Data_Get_Struct(self, SSL, ssl);
01459 
01460     if (!ssl){
01461         rb_warning("SSL session is not started yet.");
01462         return Qnil;
01463     }
01464 
01465     cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */
01466 
01467     if (!cert) {
01468         return Qnil;
01469     }
01470     obj = ossl_x509_new(cert);
01471     X509_free(cert);
01472 
01473     return obj;
01474 }
01475 
01476 /*
01477  * call-seq:
01478  *    ssl.peer_cert_chain => [cert, ...] or nil
01479  *
01480  * The X509 certificate chain for this socket's peer.
01481  */
01482 static VALUE
01483 ossl_ssl_get_peer_cert_chain(VALUE self)
01484 {
01485     SSL *ssl;
01486     STACK_OF(X509) *chain;
01487     X509 *cert;
01488     VALUE ary;
01489     int i, num;
01490 
01491     Data_Get_Struct(self, SSL, ssl);
01492     if(!ssl){
01493         rb_warning("SSL session is not started yet.");
01494         return Qnil;
01495     }
01496     chain = SSL_get_peer_cert_chain(ssl);
01497     if(!chain) return Qnil;
01498     num = sk_X509_num(chain);
01499     ary = rb_ary_new2(num);
01500     for (i = 0; i < num; i++){
01501         cert = sk_X509_value(chain, i);
01502         rb_ary_push(ary, ossl_x509_new(cert));
01503     }
01504 
01505     return ary;
01506 }
01507 
01508 /*
01509  * call-seq:
01510  *    ssl.cipher => [name, version, bits, alg_bits]
01511  *
01512  * The cipher being used for the current connection
01513  */
01514 static VALUE
01515 ossl_ssl_get_cipher(VALUE self)
01516 {
01517     SSL *ssl;
01518     SSL_CIPHER *cipher;
01519 
01520     Data_Get_Struct(self, SSL, ssl);
01521     if (!ssl) {
01522         rb_warning("SSL session is not started yet.");
01523         return Qnil;
01524     }
01525     cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl);
01526 
01527     return ossl_ssl_cipher_to_ary(cipher);
01528 }
01529 
01530 /*
01531  * call-seq:
01532  *    ssl.state => string
01533  *
01534  * A description of the current connection state.
01535  */
01536 static VALUE
01537 ossl_ssl_get_state(VALUE self)
01538 {
01539     SSL *ssl;
01540     VALUE ret;
01541 
01542     Data_Get_Struct(self, SSL, ssl);
01543     if (!ssl) {
01544         rb_warning("SSL session is not started yet.");
01545         return Qnil;
01546     }
01547     ret = rb_str_new2(SSL_state_string(ssl));
01548     if (ruby_verbose) {
01549         rb_str_cat2(ret, ": ");
01550         rb_str_cat2(ret, SSL_state_string_long(ssl));
01551     }
01552     return ret;
01553 }
01554 
01555 /*
01556  * call-seq:
01557  *    ssl.pending => Integer
01558  *
01559  * The number of bytes that are immediately available for reading
01560  */
01561 static VALUE
01562 ossl_ssl_pending(VALUE self)
01563 {
01564     SSL *ssl;
01565 
01566     Data_Get_Struct(self, SSL, ssl);
01567     if (!ssl) {
01568         rb_warning("SSL session is not started yet.");
01569         return Qnil;
01570     }
01571 
01572     return INT2NUM(SSL_pending(ssl));
01573 }
01574 
01575 /*
01576  * call-seq:
01577  *    ssl.session_reused? -> true | false
01578  *
01579  * Returns true if a reused session was negotiated during the handshake.
01580  */
01581 static VALUE
01582 ossl_ssl_session_reused(VALUE self)
01583 {
01584     SSL *ssl;
01585 
01586     Data_Get_Struct(self, SSL, ssl);
01587     if (!ssl) {
01588         rb_warning("SSL session is not started yet.");
01589         return Qnil;
01590     }
01591 
01592     switch(SSL_session_reused(ssl)) {
01593     case 1:     return Qtrue;
01594     case 0:     return Qfalse;
01595     default:    ossl_raise(eSSLError, "SSL_session_reused");
01596     }
01597 }
01598 
01599 /*
01600  * call-seq:
01601  *    ssl.session = session -> session
01602  *
01603  * Sets the Session to be used when the connection is established.
01604  */
01605 static VALUE
01606 ossl_ssl_set_session(VALUE self, VALUE arg1)
01607 {
01608     SSL *ssl;
01609     SSL_SESSION *sess;
01610 
01611 /* why is ossl_ssl_setup delayed? */
01612     ossl_ssl_setup(self);
01613 
01614     Data_Get_Struct(self, SSL, ssl);
01615     if (!ssl) {
01616         rb_warning("SSL session is not started yet.");
01617         return Qnil;
01618     }
01619 
01620     SafeGetSSLSession(arg1, sess);
01621 
01622     if (SSL_set_session(ssl, sess) != 1)
01623         ossl_raise(eSSLError, "SSL_set_session");
01624 
01625     return arg1;
01626 }
01627 
01628 /*
01629  * call-seq:
01630  *    ssl.verify_result => Integer
01631  *
01632  * Returns the result of the peer certificates verification.  See verify(1)
01633  * for error values and descriptions.
01634  *
01635  * If no peer certificate was presented X509_V_OK is returned.
01636  */
01637 static VALUE
01638 ossl_ssl_get_verify_result(VALUE self)
01639 {
01640     SSL *ssl;
01641 
01642     Data_Get_Struct(self, SSL, ssl);
01643     if (!ssl) {
01644         rb_warning("SSL session is not started yet.");
01645         return Qnil;
01646     }
01647 
01648     return INT2FIX(SSL_get_verify_result(ssl));
01649 }
01650 
01651 /*
01652  * call-seq:
01653  *    ssl.client_ca => [x509name, ...]
01654  *
01655  * Returns the list of client CAs. Please note that in contrast to
01656  * SSLContext#client_ca= no array of X509::Certificate is returned but
01657  * X509::Name instances of the CA's subject distinguished name.
01658  *
01659  * In server mode, returns the list set by SSLContext#client_ca=.
01660  * In client mode, returns the list of client CAs sent from the server.
01661  */
01662 static VALUE
01663 ossl_ssl_get_client_ca_list(VALUE self)
01664 {
01665     SSL *ssl;
01666     STACK_OF(X509_NAME) *ca;
01667 
01668     Data_Get_Struct(self, SSL, ssl);
01669     if (!ssl) {
01670         rb_warning("SSL session is not started yet.");
01671         return Qnil;
01672     }
01673 
01674     ca = SSL_get_client_CA_list(ssl);
01675     return ossl_x509name_sk2ary(ca);
01676 }
01677 
01678 void
01679 Init_ossl_ssl()
01680 {
01681     int i;
01682     VALUE ary;
01683 
01684 #if 0
01685     mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
01686 #endif
01687 
01688     ID_callback_state = rb_intern("@callback_state");
01689 
01690     ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0);
01691     ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0);
01692     ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_ptr_idx",0,0,0);
01693     ossl_ssl_ex_client_cert_cb_idx =
01694         SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_client_cert_cb_idx",0,0,0);
01695     ossl_ssl_ex_tmp_dh_callback_idx =
01696         SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_tmp_dh_callback_idx",0,0,0);
01697 
01698     mSSL = rb_define_module_under(mOSSL, "SSL");
01699     eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError);
01700 
01701     Init_ossl_ssl_session();
01702 
01703     /* Document-class: OpenSSL::SSL::SSLContext
01704      *
01705      * An SSLContext is used to set various options regarding certificates,
01706      * algorithms, verification, session caching, etc.  The SSLContext is
01707      * used to create an SSLSocket.
01708      *
01709      * All attributes must be set before creating an SSLSocket as the
01710      * SSLContext will be frozen afterward.
01711      *
01712      * The following attributes are available but don't show up in rdoc:
01713      * * ssl_version, cert, key, client_ca, ca_file, ca_path, timeout,
01714      * * verify_mode, verify_depth client_cert_cb, tmp_dh_callback,
01715      * * session_id_context, session_add_cb, session_new_cb, session_remove_cb
01716      */
01717     cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject);
01718     rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc);
01719 
01720     /*
01721      * Context certificate
01722      */
01723     rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse);
01724 
01725     /*
01726      * Context private key
01727      */
01728     rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse);
01729 
01730     /*
01731      * A certificate or Array of certificates that will be sent to the client.
01732      */
01733     rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse);
01734 
01735     /*
01736      * The path to a file containing a PEM-format CA certificate
01737      */
01738     rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse);
01739 
01740     /*
01741      * The path to a directory containing CA certificates in PEM format.
01742      *
01743      * Files are looked up by subject's X509 name's hash value.
01744      */
01745     rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse);
01746 
01747     /*
01748      * Maximum session lifetime.
01749      */
01750     rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse);
01751 
01752     /*
01753      * Session verification mode.
01754      *
01755      * Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE,
01756      * VERIFY_FAIL_IF_NO_PEER_CERT and defined on OpenSSL::SSL
01757      */
01758     rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse);
01759 
01760     /*
01761      * Number of CA certificates to walk when verifying a certificate chain.
01762      */
01763     rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse);
01764 
01765     /*
01766      * A callback for additional certificate verification.  The callback is
01767      * invoked for each certificate in the chain.
01768      *
01769      * The callback is invoked with two values.  +preverify_ok+ indicates
01770      * indicates if the verification was passed (true) or not (false).
01771      * +store_context+ is an OpenSSL::X509::StoreContext containing the
01772      * context used for certificate verification.
01773      *
01774      * If the callback returns false verification is stopped.
01775      */
01776     rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
01777 
01778     /*
01779      * Sets various OpenSSL options.
01780      */
01781     rb_attr(cSSLContext, rb_intern("options"), 1, 1, Qfalse);
01782 
01783     /*
01784      * An OpenSSL::X509::Store used for certificate verification
01785      */
01786     rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse);
01787 
01788     /*
01789      * An Array of extra X509 certificates to be added to the certificate
01790      * chain.
01791      */
01792     rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse);
01793 
01794     /*
01795      * A callback invoked when a client certificate is requested by a server
01796      * and no certificate has been set.
01797      *
01798      * The callback is invoked with a Session and must return an Array
01799      * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey.  If any
01800      * other value is returned the handshake is suspended.
01801      */
01802     rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
01803 
01804     /*
01805      * A callback invoked when DH parameters are required.
01806      *
01807      * The callback is invoked with the Session for the key exchange, an
01808      * flag indicating the use of an export cipher and the keylength
01809      * required.
01810      *
01811      * The callback must return an OpenSSL::PKey::DH instance of the correct
01812      * key length.
01813      */
01814     rb_attr(cSSLContext, rb_intern("tmp_dh_callback"), 1, 1, Qfalse);
01815 
01816     /*
01817      * Sets the context in which a session can be reused.  This allows
01818      * sessions for multiple applications to be distinguished, for exapmle, by
01819      * name.
01820      */
01821     rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse);
01822 
01823     /*
01824      * A callback invoked on a server when a session is proposed by the client
01825      * but the session could not be found in the server's internal cache.
01826      *
01827      * The callback is invoked with the SSLSocket and session id.  The
01828      * callback may return a Session from an external cache.
01829      */
01830     rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse);
01831 
01832     /*
01833      * A callback invoked when a new session was negotiatied.
01834      *
01835      * The callback is invoked with an SSLSocket.  If false is returned the
01836      * session will be removed from the internal cache.
01837      */
01838     rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse);
01839 
01840     /*
01841      * A callback invoked when a session is removed from the internal cache.
01842      *
01843      * The callback is invoked with an SSLContext and a Session.
01844      */
01845     rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
01846 
01847 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
01848     /*
01849      * A callback invoked at connect time to distinguish between multiple
01850      * server names.
01851      *
01852      * The callback is invoked with an SSLSocket and a server name.  The
01853      * callback must return an SSLContext for the server name or nil.
01854      */
01855     rb_attr(cSSLContext, rb_intern("servername_cb"), 1, 1, Qfalse);
01856 #endif
01857 
01858     rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
01859     rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
01860     rb_define_method(cSSLContext, "initialize",  ossl_sslctx_initialize, -1);
01861     rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1);
01862     rb_define_method(cSSLContext, "ciphers",     ossl_sslctx_get_ciphers, 0);
01863     rb_define_method(cSSLContext, "ciphers=",    ossl_sslctx_set_ciphers, 1);
01864 
01865     rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
01866 
01867 
01868     /*
01869      * No session caching for client or server
01870      */
01871     rb_define_const(cSSLContext, "SESSION_CACHE_OFF", LONG2FIX(SSL_SESS_CACHE_OFF));
01872 
01873     /*
01874      * Client sessions are added to the session cache
01875      */
01876     rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT", LONG2FIX(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */
01877 
01878     /*
01879      * Server sessions are added to the session cache
01880      */
01881     rb_define_const(cSSLContext, "SESSION_CACHE_SERVER", LONG2FIX(SSL_SESS_CACHE_SERVER));
01882 
01883     /*
01884      * Both client and server sessions are added to the session cache
01885      */
01886     rb_define_const(cSSLContext, "SESSION_CACHE_BOTH", LONG2FIX(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */
01887 
01888     /*
01889      * Normally the sesison cache is checked for expired sessions every 255
01890      * connections.  Since this may lead to a delay that cannot be controlled,
01891      * the automatic flushing may be disabled and #flush_sessions can be
01892      * called explicitly.
01893      */
01894     rb_define_const(cSSLContext, "SESSION_CACHE_NO_AUTO_CLEAR", LONG2FIX(SSL_SESS_CACHE_NO_AUTO_CLEAR));
01895 
01896     /*
01897      * Always perform external lookups of sessions even if they are in the
01898      * internal cache.
01899      *
01900      * This flag has no effect on clients
01901      */
01902     rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_LOOKUP", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP));
01903 
01904     /*
01905      * Never automatically store sessions in the internal store.
01906      */
01907     rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_STORE", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_STORE));
01908 
01909     /*
01910      * Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and
01911      * SESSION_CACHE_NO_INTERNAL_STORE.
01912      */
01913     rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL));
01914 
01915     rb_define_method(cSSLContext, "session_add",     ossl_sslctx_session_add, 1);
01916     rb_define_method(cSSLContext, "session_remove",     ossl_sslctx_session_remove, 1);
01917     rb_define_method(cSSLContext, "session_cache_mode",     ossl_sslctx_get_session_cache_mode, 0);
01918     rb_define_method(cSSLContext, "session_cache_mode=",     ossl_sslctx_set_session_cache_mode, 1);
01919     rb_define_method(cSSLContext, "session_cache_size",     ossl_sslctx_get_session_cache_size, 0);
01920     rb_define_method(cSSLContext, "session_cache_size=",     ossl_sslctx_set_session_cache_size, 1);
01921     rb_define_method(cSSLContext, "session_cache_stats",     ossl_sslctx_get_session_cache_stats, 0);
01922     rb_define_method(cSSLContext, "flush_sessions",     ossl_sslctx_flush_sessions, -1);
01923 
01924     ary = rb_ary_new2(numberof(ossl_ssl_method_tab));
01925     for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
01926         rb_ary_push(ary, ID2SYM(rb_intern(ossl_ssl_method_tab[i].name)));
01927     }
01928     rb_obj_freeze(ary);
01929     /* The list of available SSL/TLS methods */
01930     rb_define_const(cSSLContext, "METHODS", ary);
01931 
01932     /*
01933      * Document-class: OpenSSL::SSL::SSLSocket
01934      *
01935      * The following attributes are available but don't show up in rdoc.
01936      * * io, context, sync_close
01937      *
01938      */
01939     cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
01940     rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
01941     for(i = 0; i < numberof(ossl_ssl_attr_readers); i++)
01942         rb_attr(cSSLSocket, rb_intern(ossl_ssl_attr_readers[i]), 1, 0, Qfalse);
01943     for(i = 0; i < numberof(ossl_ssl_attrs); i++)
01944         rb_attr(cSSLSocket, rb_intern(ossl_ssl_attrs[i]), 1, 1, Qfalse);
01945     rb_define_alias(cSSLSocket, "to_io", "io");
01946     rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
01947     rb_define_method(cSSLSocket, "connect",    ossl_ssl_connect, 0);
01948     rb_define_method(cSSLSocket, "connect_nonblock",    ossl_ssl_connect_nonblock, 0);
01949     rb_define_method(cSSLSocket, "accept",     ossl_ssl_accept, 0);
01950     rb_define_method(cSSLSocket, "accept_nonblock",     ossl_ssl_accept_nonblock, 0);
01951     rb_define_method(cSSLSocket, "sysread",    ossl_ssl_read, -1);
01952     rb_define_private_method(cSSLSocket, "sysread_nonblock",    ossl_ssl_read_nonblock, -1);
01953     rb_define_method(cSSLSocket, "syswrite",   ossl_ssl_write, 1);
01954     rb_define_private_method(cSSLSocket, "syswrite_nonblock",    ossl_ssl_write_nonblock, 1);
01955     rb_define_method(cSSLSocket, "sysclose",   ossl_ssl_close, 0);
01956     rb_define_method(cSSLSocket, "cert",       ossl_ssl_get_cert, 0);
01957     rb_define_method(cSSLSocket, "peer_cert",  ossl_ssl_get_peer_cert, 0);
01958     rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0);
01959     rb_define_method(cSSLSocket, "cipher",     ossl_ssl_get_cipher, 0);
01960     rb_define_method(cSSLSocket, "state",      ossl_ssl_get_state, 0);
01961     rb_define_method(cSSLSocket, "pending",    ossl_ssl_pending, 0);
01962     rb_define_method(cSSLSocket, "session_reused?",    ossl_ssl_session_reused, 0);
01963     rb_define_method(cSSLSocket, "session=",    ossl_ssl_set_session, 1);
01964     rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
01965     rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
01966 
01967 #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2NUM(SSL_##x))
01968 
01969     ossl_ssl_def_const(VERIFY_NONE);
01970     ossl_ssl_def_const(VERIFY_PEER);
01971     ossl_ssl_def_const(VERIFY_FAIL_IF_NO_PEER_CERT);
01972     ossl_ssl_def_const(VERIFY_CLIENT_ONCE);
01973     /* Introduce constants included in OP_ALL.  These constants are mostly for
01974      * unset some bits in OP_ALL such as:
01975      *   ctx.options = OP_ALL & ~OP_DONT_INSERT_EMPTY_FRAGMENTS
01976      */
01977     ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG);
01978     ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG);
01979     ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
01980     ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG);
01981     ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER);
01982     ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING);
01983     ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG);
01984     ossl_ssl_def_const(OP_TLS_D5_BUG);
01985     ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG);
01986     ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS);
01987     ossl_ssl_def_const(OP_ALL);
01988 #if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
01989     ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
01990 #endif
01991 #if defined(SSL_OP_SINGLE_ECDH_USE)
01992     ossl_ssl_def_const(OP_SINGLE_ECDH_USE);
01993 #endif
01994     ossl_ssl_def_const(OP_SINGLE_DH_USE);
01995     ossl_ssl_def_const(OP_EPHEMERAL_RSA);
01996 #if defined(SSL_OP_CIPHER_SERVER_PREFERENCE)
01997     ossl_ssl_def_const(OP_CIPHER_SERVER_PREFERENCE);
01998 #endif
01999     ossl_ssl_def_const(OP_TLS_ROLLBACK_BUG);
02000     ossl_ssl_def_const(OP_NO_SSLv2);
02001     ossl_ssl_def_const(OP_NO_SSLv3);
02002     ossl_ssl_def_const(OP_NO_TLSv1);
02003 #if defined(SSL_OP_NO_TICKET)
02004     ossl_ssl_def_const(OP_NO_TICKET);
02005 #endif
02006 #if defined(SSL_OP_NO_COMPRESSION)
02007     ossl_ssl_def_const(OP_NO_COMPRESSION);
02008 #endif
02009     ossl_ssl_def_const(OP_PKCS1_CHECK_1);
02010     ossl_ssl_def_const(OP_PKCS1_CHECK_2);
02011     ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG);
02012     ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
02013 }
02014