ext/openssl/ossl_ssl.c

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

Generated on 19 Jul 2016 for Ruby by  doxygen 1.4.7