|
Ruby 1.9.2p290(2011-07-09revision32553)
|
00001 /* 00002 * $Id: ossl_ssl.c 32382 2011-07-03 12:24:02Z yugui $ 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 00144 ctx = SSL_CTX_new(SSLv23_method()); 00145 if (!ctx) { 00146 ossl_raise(eSSLError, "SSL_CTX_new:"); 00147 } 00148 SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); 00149 SSL_CTX_set_options(ctx, SSL_OP_ALL); 00150 return Data_Wrap_Struct(klass, 0, ossl_sslctx_free, ctx); 00151 } 00152 00153 static VALUE 00154 ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method) 00155 { 00156 SSL_METHOD *method = NULL; 00157 const char *s; 00158 int i; 00159 00160 SSL_CTX *ctx; 00161 if(TYPE(ssl_method) == T_SYMBOL) 00162 s = rb_id2name(SYM2ID(ssl_method)); 00163 else 00164 s = StringValuePtr(ssl_method); 00165 for (i = 0; i < numberof(ossl_ssl_method_tab); i++) { 00166 if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) { 00167 method = ossl_ssl_method_tab[i].func(); 00168 break; 00169 } 00170 } 00171 if (!method) { 00172 ossl_raise(rb_eArgError, "unknown SSL method `%s'.", s); 00173 } 00174 Data_Get_Struct(self, SSL_CTX, ctx); 00175 if (SSL_CTX_set_ssl_version(ctx, method) != 1) { 00176 ossl_raise(eSSLError, "SSL_CTX_set_ssl_version:"); 00177 } 00178 00179 return ssl_method; 00180 } 00181 00182 /* 00183 * call-seq: 00184 * SSLContext.new => ctx 00185 * SSLContext.new(:TLSv1) => ctx 00186 * SSLContext.new("SSLv23_client") => ctx 00187 * 00188 * You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS 00189 */ 00190 static VALUE 00191 ossl_sslctx_initialize(int argc, VALUE *argv, VALUE self) 00192 { 00193 VALUE ssl_method; 00194 int i; 00195 00196 for(i = 0; i < numberof(ossl_sslctx_attrs); i++){ 00197 char buf[32]; 00198 snprintf(buf, sizeof(buf), "@%s", ossl_sslctx_attrs[i]); 00199 rb_iv_set(self, buf, Qnil); 00200 } 00201 if (rb_scan_args(argc, argv, "01", &ssl_method) == 0){ 00202 return self; 00203 } 00204 ossl_sslctx_set_ssl_version(self, ssl_method); 00205 00206 return self; 00207 } 00208 00209 static VALUE 00210 ossl_call_client_cert_cb(VALUE obj) 00211 { 00212 VALUE cb, ary, cert, key; 00213 SSL *ssl; 00214 00215 Data_Get_Struct(obj, SSL, ssl); 00216 cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx); 00217 if (NIL_P(cb)) return Qfalse; 00218 ary = rb_funcall(cb, rb_intern("call"), 1, obj); 00219 Check_Type(ary, T_ARRAY); 00220 GetX509CertPtr(cert = rb_ary_entry(ary, 0)); 00221 GetPKeyPtr(key = rb_ary_entry(ary, 1)); 00222 ossl_ssl_set_x509(obj, cert); 00223 ossl_ssl_set_key(obj, key); 00224 00225 return Qtrue; 00226 } 00227 00228 static int 00229 ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey) 00230 { 00231 VALUE obj; 00232 int status, success; 00233 00234 obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); 00235 success = rb_protect((VALUE(*)_((VALUE)))ossl_call_client_cert_cb, 00236 obj, &status); 00237 if (status || !success) return 0; 00238 *x509 = DupX509CertPtr(ossl_ssl_get_x509(obj)); 00239 *pkey = DupPKeyPtr(ossl_ssl_get_key(obj)); 00240 00241 return 1; 00242 } 00243 00244 #if !defined(OPENSSL_NO_DH) 00245 static VALUE 00246 ossl_call_tmp_dh_callback(VALUE *args) 00247 { 00248 SSL *ssl; 00249 VALUE cb, dh; 00250 EVP_PKEY *pkey; 00251 00252 Data_Get_Struct(args[0], SSL, ssl); 00253 cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx); 00254 if (NIL_P(cb)) return Qfalse; 00255 dh = rb_funcall(cb, rb_intern("call"), 3, args[0], args[1], args[2]); 00256 pkey = GetPKeyPtr(dh); 00257 if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) return Qfalse; 00258 ossl_ssl_set_tmp_dh(args[0], dh); 00259 00260 return Qtrue; 00261 } 00262 00263 static DH* 00264 ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength) 00265 { 00266 VALUE args[3]; 00267 int status, success; 00268 00269 args[0] = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); 00270 args[1] = INT2FIX(is_export); 00271 args[2] = INT2FIX(keylength); 00272 success = rb_protect((VALUE(*)_((VALUE)))ossl_call_tmp_dh_callback, 00273 (VALUE)args, &status); 00274 if (status || !success) return NULL; 00275 00276 return GetPKeyPtr(ossl_ssl_get_tmp_dh(args[0]))->pkey.dh; 00277 } 00278 00279 static DH* 00280 ossl_default_tmp_dh_callback(SSL *ssl, int is_export, int keylength) 00281 { 00282 rb_warning("using default DH parameters."); 00283 00284 switch(keylength){ 00285 case 512: 00286 return OSSL_DEFAULT_DH_512; 00287 case 1024: 00288 return OSSL_DEFAULT_DH_1024; 00289 } 00290 return NULL; 00291 } 00292 #endif /* OPENSSL_NO_DH */ 00293 00294 static int 00295 ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) 00296 { 00297 VALUE cb; 00298 SSL *ssl; 00299 00300 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); 00301 cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx); 00302 X509_STORE_CTX_set_ex_data(ctx, ossl_verify_cb_idx, (void*)cb); 00303 return ossl_verify_cb(preverify_ok, ctx); 00304 } 00305 00306 static VALUE 00307 ossl_call_session_get_cb(VALUE ary) 00308 { 00309 VALUE ssl_obj, sslctx_obj, cb; 00310 00311 Check_Type(ary, T_ARRAY); 00312 ssl_obj = rb_ary_entry(ary, 0); 00313 00314 sslctx_obj = rb_iv_get(ssl_obj, "@context"); 00315 if (NIL_P(sslctx_obj)) return Qnil; 00316 cb = rb_iv_get(sslctx_obj, "@session_get_cb"); 00317 if (NIL_P(cb)) return Qnil; 00318 00319 return rb_funcall(cb, rb_intern("call"), 1, ary); 00320 } 00321 00322 /* this method is currently only called for servers (in OpenSSL <= 0.9.8e) */ 00323 static SSL_SESSION * 00324 ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy) 00325 { 00326 VALUE ary, ssl_obj, ret_obj; 00327 SSL_SESSION *sess; 00328 void *ptr; 00329 int state = 0; 00330 00331 OSSL_Debug("SSL SESSION get callback entered"); 00332 if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL) 00333 return NULL; 00334 ssl_obj = (VALUE)ptr; 00335 ary = rb_ary_new2(2); 00336 rb_ary_push(ary, ssl_obj); 00337 rb_ary_push(ary, rb_str_new((const char *)buf, len)); 00338 00339 ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_get_cb, ary, &state); 00340 if (state) { 00341 rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); 00342 return NULL; 00343 } 00344 if (!rb_obj_is_instance_of(ret_obj, cSSLSession)) 00345 return NULL; 00346 00347 SafeGetSSLSession(ret_obj, sess); 00348 *copy = 1; 00349 00350 return sess; 00351 } 00352 00353 static VALUE 00354 ossl_call_session_new_cb(VALUE ary) 00355 { 00356 VALUE ssl_obj, sslctx_obj, cb; 00357 00358 Check_Type(ary, T_ARRAY); 00359 ssl_obj = rb_ary_entry(ary, 0); 00360 00361 sslctx_obj = rb_iv_get(ssl_obj, "@context"); 00362 if (NIL_P(sslctx_obj)) return Qnil; 00363 cb = rb_iv_get(sslctx_obj, "@session_new_cb"); 00364 if (NIL_P(cb)) return Qnil; 00365 00366 return rb_funcall(cb, rb_intern("call"), 1, ary); 00367 } 00368 00369 /* return 1 normal. return 0 removes the session */ 00370 static int 00371 ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess) 00372 { 00373 VALUE ary, ssl_obj, sess_obj, ret_obj; 00374 void *ptr; 00375 int state = 0; 00376 00377 OSSL_Debug("SSL SESSION new callback entered"); 00378 00379 if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL) 00380 return 1; 00381 ssl_obj = (VALUE)ptr; 00382 sess_obj = rb_obj_alloc(cSSLSession); 00383 CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION); 00384 DATA_PTR(sess_obj) = sess; 00385 00386 ary = rb_ary_new2(2); 00387 rb_ary_push(ary, ssl_obj); 00388 rb_ary_push(ary, sess_obj); 00389 00390 ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state); 00391 if (state) { 00392 rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); 00393 return 0; /* what should be returned here??? */ 00394 } 00395 00396 return RTEST(ret_obj) ? 1 : 0; 00397 } 00398 00399 #if 0 /* unused */ 00400 static VALUE 00401 ossl_call_session_remove_cb(VALUE ary) 00402 { 00403 VALUE sslctx_obj, cb; 00404 00405 Check_Type(ary, T_ARRAY); 00406 sslctx_obj = rb_ary_entry(ary, 0); 00407 00408 cb = rb_iv_get(sslctx_obj, "@session_remove_cb"); 00409 if (NIL_P(cb)) return Qnil; 00410 00411 return rb_funcall(cb, rb_intern("call"), 1, ary); 00412 } 00413 #endif 00414 00415 static void 00416 ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess) 00417 { 00418 VALUE ary, sslctx_obj, sess_obj, ret_obj; 00419 void *ptr; 00420 int state = 0; 00421 00422 OSSL_Debug("SSL SESSION remove callback entered"); 00423 00424 if ((ptr = SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx)) == NULL) 00425 return; 00426 sslctx_obj = (VALUE)ptr; 00427 sess_obj = rb_obj_alloc(cSSLSession); 00428 CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION); 00429 DATA_PTR(sess_obj) = sess; 00430 00431 ary = rb_ary_new2(2); 00432 rb_ary_push(ary, sslctx_obj); 00433 rb_ary_push(ary, sess_obj); 00434 00435 ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state); 00436 if (state) { 00437 /* 00438 the SSL_CTX is frozen, nowhere to save state. 00439 there is no common accessor method to check it either. 00440 rb_ivar_set(sslctx_obj, ID_callback_state, INT2NUM(state)); 00441 */ 00442 } 00443 } 00444 00445 static VALUE 00446 ossl_sslctx_add_extra_chain_cert_i(VALUE i, VALUE arg) 00447 { 00448 X509 *x509; 00449 SSL_CTX *ctx; 00450 00451 Data_Get_Struct(arg, SSL_CTX, ctx); 00452 x509 = DupX509CertPtr(i); 00453 if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){ 00454 ossl_raise(eSSLError, NULL); 00455 } 00456 00457 return i; 00458 } 00459 00460 static VALUE ossl_sslctx_setup(VALUE self); 00461 00462 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME 00463 static VALUE 00464 ossl_call_servername_cb(VALUE ary) 00465 { 00466 VALUE ssl_obj, sslctx_obj, cb, ret_obj; 00467 00468 Check_Type(ary, T_ARRAY); 00469 ssl_obj = rb_ary_entry(ary, 0); 00470 00471 sslctx_obj = rb_iv_get(ssl_obj, "@context"); 00472 if (NIL_P(sslctx_obj)) return Qnil; 00473 cb = rb_iv_get(sslctx_obj, "@servername_cb"); 00474 if (NIL_P(cb)) return Qnil; 00475 00476 ret_obj = rb_funcall(cb, rb_intern("call"), 1, ary); 00477 if (rb_obj_is_kind_of(ret_obj, cSSLContext)) { 00478 SSL *ssl; 00479 SSL_CTX *ctx2; 00480 00481 ossl_sslctx_setup(ret_obj); 00482 Data_Get_Struct(ssl_obj, SSL, ssl); 00483 Data_Get_Struct(ret_obj, SSL_CTX, ctx2); 00484 SSL_set_SSL_CTX(ssl, ctx2); 00485 } else if (!NIL_P(ret_obj)) { 00486 rb_raise(rb_eArgError, "servername_cb must return an OpenSSL::SSL::SSLContext object or nil"); 00487 } 00488 00489 return ret_obj; 00490 } 00491 00492 static int 00493 ssl_servername_cb(SSL *ssl, int *ad, void *arg) 00494 { 00495 VALUE ary, ssl_obj, ret_obj; 00496 void *ptr; 00497 int state = 0; 00498 const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); 00499 00500 if (!servername) 00501 return SSL_TLSEXT_ERR_OK; 00502 00503 if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL) 00504 return SSL_TLSEXT_ERR_ALERT_FATAL; 00505 ssl_obj = (VALUE)ptr; 00506 ary = rb_ary_new2(2); 00507 rb_ary_push(ary, ssl_obj); 00508 rb_ary_push(ary, rb_str_new2(servername)); 00509 00510 ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_servername_cb, ary, &state); 00511 if (state) { 00512 rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); 00513 return SSL_TLSEXT_ERR_ALERT_FATAL; 00514 } 00515 00516 return SSL_TLSEXT_ERR_OK; 00517 } 00518 #endif 00519 00520 /* 00521 * call-seq: 00522 * ctx.setup => Qtrue # first time 00523 * ctx.setup => nil # thereafter 00524 * 00525 * This method is called automatically when a new SSLSocket is created. 00526 * Normally you do not need to call this method (unless you are writing an extension in C). 00527 */ 00528 static VALUE 00529 ossl_sslctx_setup(VALUE self) 00530 { 00531 SSL_CTX *ctx; 00532 X509 *cert = NULL, *client_ca = NULL; 00533 X509_STORE *store; 00534 EVP_PKEY *key = NULL; 00535 char *ca_path = NULL, *ca_file = NULL; 00536 int i, verify_mode; 00537 VALUE val; 00538 00539 if(OBJ_FROZEN(self)) return Qnil; 00540 Data_Get_Struct(self, SSL_CTX, ctx); 00541 00542 #if !defined(OPENSSL_NO_DH) 00543 if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){ 00544 SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); 00545 } 00546 else{ 00547 SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback); 00548 } 00549 #endif 00550 SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self); 00551 00552 val = ossl_sslctx_get_cert_store(self); 00553 if(!NIL_P(val)){ 00554 /* 00555 * WORKAROUND: 00556 * X509_STORE can count references, but 00557 * X509_STORE_free() doesn't care it. 00558 * So we won't increment it but mark it by ex_data. 00559 */ 00560 store = GetX509StorePtr(val); /* NO NEED TO DUP */ 00561 SSL_CTX_set_cert_store(ctx, store); 00562 SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1); 00563 } 00564 00565 val = ossl_sslctx_get_extra_cert(self); 00566 if(!NIL_P(val)){ 00567 rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self); 00568 } 00569 00570 /* private key may be bundled in certificate file. */ 00571 val = ossl_sslctx_get_cert(self); 00572 cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */ 00573 val = ossl_sslctx_get_key(self); 00574 key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */ 00575 if (cert && key) { 00576 if (!SSL_CTX_use_certificate(ctx, cert)) { 00577 /* Adds a ref => Safe to FREE */ 00578 ossl_raise(eSSLError, "SSL_CTX_use_certificate:"); 00579 } 00580 if (!SSL_CTX_use_PrivateKey(ctx, key)) { 00581 /* Adds a ref => Safe to FREE */ 00582 ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey:"); 00583 } 00584 if (!SSL_CTX_check_private_key(ctx)) { 00585 ossl_raise(eSSLError, "SSL_CTX_check_private_key:"); 00586 } 00587 } 00588 00589 val = ossl_sslctx_get_client_ca(self); 00590 if(!NIL_P(val)){ 00591 if(TYPE(val) == T_ARRAY){ 00592 for(i = 0; i < RARRAY_LEN(val); i++){ 00593 client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]); 00594 if (!SSL_CTX_add_client_CA(ctx, client_ca)){ 00595 /* Copies X509_NAME => FREE it. */ 00596 ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); 00597 } 00598 } 00599 } 00600 else{ 00601 client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */ 00602 if (!SSL_CTX_add_client_CA(ctx, client_ca)){ 00603 /* Copies X509_NAME => FREE it. */ 00604 ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); 00605 } 00606 } 00607 } 00608 00609 val = ossl_sslctx_get_ca_file(self); 00610 ca_file = NIL_P(val) ? NULL : StringValuePtr(val); 00611 val = ossl_sslctx_get_ca_path(self); 00612 ca_path = NIL_P(val) ? NULL : StringValuePtr(val); 00613 if(ca_file || ca_path){ 00614 if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) 00615 rb_warning("can't set verify locations"); 00616 } 00617 00618 val = ossl_sslctx_get_verify_mode(self); 00619 verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val); 00620 SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback); 00621 if (RTEST(ossl_sslctx_get_client_cert_cb(self))) 00622 SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb); 00623 00624 val = ossl_sslctx_get_timeout(self); 00625 if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val)); 00626 00627 val = ossl_sslctx_get_verify_dep(self); 00628 if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2LONG(val)); 00629 00630 val = ossl_sslctx_get_options(self); 00631 if(!NIL_P(val)) SSL_CTX_set_options(ctx, NUM2LONG(val)); 00632 rb_obj_freeze(self); 00633 00634 val = ossl_sslctx_get_sess_id_ctx(self); 00635 if (!NIL_P(val)){ 00636 StringValue(val); 00637 if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val), 00638 RSTRING_LEN(val))){ 00639 ossl_raise(eSSLError, "SSL_CTX_set_session_id_context:"); 00640 } 00641 } 00642 00643 if (RTEST(rb_iv_get(self, "@session_get_cb"))) { 00644 SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb); 00645 OSSL_Debug("SSL SESSION get callback added"); 00646 } 00647 if (RTEST(rb_iv_get(self, "@session_new_cb"))) { 00648 SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb); 00649 OSSL_Debug("SSL SESSION new callback added"); 00650 } 00651 if (RTEST(rb_iv_get(self, "@session_remove_cb"))) { 00652 SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb); 00653 OSSL_Debug("SSL SESSION remove callback added"); 00654 } 00655 00656 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME 00657 val = rb_iv_get(self, "@servername_cb"); 00658 if (!NIL_P(val)) { 00659 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); 00660 OSSL_Debug("SSL TLSEXT servername callback added"); 00661 } 00662 #endif 00663 00664 return Qtrue; 00665 } 00666 00667 static VALUE 00668 ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher) 00669 { 00670 VALUE ary; 00671 int bits, alg_bits; 00672 00673 ary = rb_ary_new2(4); 00674 rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_name(cipher))); 00675 rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_version(cipher))); 00676 bits = SSL_CIPHER_get_bits(cipher, &alg_bits); 00677 rb_ary_push(ary, INT2FIX(bits)); 00678 rb_ary_push(ary, INT2FIX(alg_bits)); 00679 00680 return ary; 00681 } 00682 00683 /* 00684 * call-seq: 00685 * ctx.ciphers => [[name, version, bits, alg_bits], ...] 00686 */ 00687 static VALUE 00688 ossl_sslctx_get_ciphers(VALUE self) 00689 { 00690 SSL_CTX *ctx; 00691 STACK_OF(SSL_CIPHER) *ciphers; 00692 SSL_CIPHER *cipher; 00693 VALUE ary; 00694 int i, num; 00695 00696 Data_Get_Struct(self, SSL_CTX, ctx); 00697 if(!ctx){ 00698 rb_warning("SSL_CTX is not initialized."); 00699 return Qnil; 00700 } 00701 ciphers = ctx->cipher_list; 00702 00703 if (!ciphers) 00704 return rb_ary_new(); 00705 00706 num = sk_num((STACK*)ciphers); 00707 ary = rb_ary_new2(num); 00708 for(i = 0; i < num; i++){ 00709 cipher = (SSL_CIPHER*)sk_value((STACK*)ciphers, i); 00710 rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher)); 00711 } 00712 return ary; 00713 } 00714 00715 /* 00716 * call-seq: 00717 * ctx.ciphers = "cipher1:cipher2:..." 00718 * ctx.ciphers = [name, ...] 00719 * ctx.ciphers = [[name, version, bits, alg_bits], ...] 00720 */ 00721 static VALUE 00722 ossl_sslctx_set_ciphers(VALUE self, VALUE v) 00723 { 00724 SSL_CTX *ctx; 00725 VALUE str, elem; 00726 int i; 00727 00728 rb_check_frozen(self); 00729 if (NIL_P(v)) 00730 return v; 00731 else if (TYPE(v) == T_ARRAY) { 00732 str = rb_str_new(0, 0); 00733 for (i = 0; i < RARRAY_LEN(v); i++) { 00734 elem = rb_ary_entry(v, i); 00735 if (TYPE(elem) == T_ARRAY) elem = rb_ary_entry(elem, 0); 00736 elem = rb_String(elem); 00737 rb_str_append(str, elem); 00738 if (i < RARRAY_LEN(v)-1) rb_str_cat2(str, ":"); 00739 } 00740 } else { 00741 str = v; 00742 StringValue(str); 00743 } 00744 00745 Data_Get_Struct(self, SSL_CTX, ctx); 00746 if(!ctx){ 00747 ossl_raise(eSSLError, "SSL_CTX is not initialized."); 00748 return Qnil; 00749 } 00750 if (!SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(str))) { 00751 ossl_raise(eSSLError, "SSL_CTX_set_cipher_list:"); 00752 } 00753 00754 return v; 00755 } 00756 00757 00758 /* 00759 * call-seq: 00760 * ctx.session_add(session) -> true | false 00761 * 00762 */ 00763 static VALUE 00764 ossl_sslctx_session_add(VALUE self, VALUE arg) 00765 { 00766 SSL_CTX *ctx; 00767 SSL_SESSION *sess; 00768 00769 Data_Get_Struct(self, SSL_CTX, ctx); 00770 SafeGetSSLSession(arg, sess); 00771 00772 return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse; 00773 } 00774 00775 /* 00776 * call-seq: 00777 * ctx.session_remove(session) -> true | false 00778 * 00779 */ 00780 static VALUE 00781 ossl_sslctx_session_remove(VALUE self, VALUE arg) 00782 { 00783 SSL_CTX *ctx; 00784 SSL_SESSION *sess; 00785 00786 Data_Get_Struct(self, SSL_CTX, ctx); 00787 SafeGetSSLSession(arg, sess); 00788 00789 return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse; 00790 } 00791 00792 /* 00793 * call-seq: 00794 * ctx.session_cache_mode -> integer 00795 * 00796 */ 00797 static VALUE 00798 ossl_sslctx_get_session_cache_mode(VALUE self) 00799 { 00800 SSL_CTX *ctx; 00801 00802 Data_Get_Struct(self, SSL_CTX, ctx); 00803 00804 return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx)); 00805 } 00806 00807 /* 00808 * call-seq: 00809 * ctx.session_cache_mode=(integer) -> integer 00810 * 00811 */ 00812 static VALUE 00813 ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg) 00814 { 00815 SSL_CTX *ctx; 00816 00817 Data_Get_Struct(self, SSL_CTX, ctx); 00818 00819 SSL_CTX_set_session_cache_mode(ctx, NUM2LONG(arg)); 00820 00821 return arg; 00822 } 00823 00824 /* 00825 * call-seq: 00826 * ctx.session_cache_size -> integer 00827 * 00828 */ 00829 static VALUE 00830 ossl_sslctx_get_session_cache_size(VALUE self) 00831 { 00832 SSL_CTX *ctx; 00833 00834 Data_Get_Struct(self, SSL_CTX, ctx); 00835 00836 return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx)); 00837 } 00838 00839 /* 00840 * call-seq: 00841 * ctx.session_cache_size=(integer) -> integer 00842 * 00843 */ 00844 static VALUE 00845 ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg) 00846 { 00847 SSL_CTX *ctx; 00848 00849 Data_Get_Struct(self, SSL_CTX, ctx); 00850 00851 SSL_CTX_sess_set_cache_size(ctx, NUM2LONG(arg)); 00852 00853 return arg; 00854 } 00855 00856 /* 00857 * call-seq: 00858 * ctx.session_cache_stats -> Hash 00859 * 00860 */ 00861 static VALUE 00862 ossl_sslctx_get_session_cache_stats(VALUE self) 00863 { 00864 SSL_CTX *ctx; 00865 VALUE hash; 00866 00867 Data_Get_Struct(self, SSL_CTX, ctx); 00868 00869 hash = rb_hash_new(); 00870 rb_hash_aset(hash, ID2SYM(rb_intern("cache_num")), LONG2NUM(SSL_CTX_sess_number(ctx))); 00871 rb_hash_aset(hash, ID2SYM(rb_intern("connect")), LONG2NUM(SSL_CTX_sess_connect(ctx))); 00872 rb_hash_aset(hash, ID2SYM(rb_intern("connect_good")), LONG2NUM(SSL_CTX_sess_connect_good(ctx))); 00873 rb_hash_aset(hash, ID2SYM(rb_intern("connect_renegotiate")), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx))); 00874 rb_hash_aset(hash, ID2SYM(rb_intern("accept")), LONG2NUM(SSL_CTX_sess_accept(ctx))); 00875 rb_hash_aset(hash, ID2SYM(rb_intern("accept_good")), LONG2NUM(SSL_CTX_sess_accept_good(ctx))); 00876 rb_hash_aset(hash, ID2SYM(rb_intern("accept_renegotiate")), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx))); 00877 rb_hash_aset(hash, ID2SYM(rb_intern("cache_hits")), LONG2NUM(SSL_CTX_sess_hits(ctx))); 00878 rb_hash_aset(hash, ID2SYM(rb_intern("cb_hits")), LONG2NUM(SSL_CTX_sess_cb_hits(ctx))); 00879 rb_hash_aset(hash, ID2SYM(rb_intern("cache_misses")), LONG2NUM(SSL_CTX_sess_misses(ctx))); 00880 rb_hash_aset(hash, ID2SYM(rb_intern("cache_full")), LONG2NUM(SSL_CTX_sess_cache_full(ctx))); 00881 rb_hash_aset(hash, ID2SYM(rb_intern("timeouts")), LONG2NUM(SSL_CTX_sess_timeouts(ctx))); 00882 00883 return hash; 00884 } 00885 00886 00887 /* 00888 * call-seq: 00889 * ctx.flush_sessions(time | nil) -> self 00890 * 00891 */ 00892 static VALUE 00893 ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self) 00894 { 00895 VALUE arg1; 00896 SSL_CTX *ctx; 00897 time_t tm = 0; 00898 00899 rb_scan_args(argc, argv, "01", &arg1); 00900 00901 Data_Get_Struct(self, SSL_CTX, ctx); 00902 00903 if (NIL_P(arg1)) { 00904 tm = time(0); 00905 } else if (rb_obj_is_instance_of(arg1, rb_cTime)) { 00906 tm = NUM2LONG(rb_funcall(arg1, rb_intern("to_i"), 0)); 00907 } else { 00908 rb_raise(rb_eArgError, "arg must be Time or nil"); 00909 } 00910 00911 SSL_CTX_flush_sessions(ctx, (long)tm); 00912 00913 return self; 00914 } 00915 00916 /* 00917 * SSLSocket class 00918 */ 00919 static void 00920 ossl_ssl_shutdown(SSL *ssl) 00921 { 00922 if (ssl) { 00923 SSL_shutdown(ssl); 00924 SSL_clear(ssl); 00925 } 00926 } 00927 00928 static void 00929 ossl_ssl_free(SSL *ssl) 00930 { 00931 ossl_ssl_shutdown(ssl); 00932 SSL_free(ssl); 00933 } 00934 00935 static VALUE 00936 ossl_ssl_s_alloc(VALUE klass) 00937 { 00938 return Data_Wrap_Struct(klass, 0, ossl_ssl_free, NULL); 00939 } 00940 00941 /* 00942 * call-seq: 00943 * SSLSocket.new(io) => aSSLSocket 00944 * SSLSocket.new(io, ctx) => aSSLSocket 00945 * 00946 * === Parameters 00947 * * +io+ is a real ruby IO object. Not an IO like object that responds to read/write. 00948 * * +ctx+ is an OpenSSLSSL::SSLContext. 00949 * 00950 * The OpenSSL::Buffering module provides additional IO methods. 00951 * 00952 * This method will freeze the SSLContext if one is provided; 00953 * however, session management is still allowed in the frozen SSLContext. 00954 */ 00955 static VALUE 00956 ossl_ssl_initialize(int argc, VALUE *argv, VALUE self) 00957 { 00958 VALUE io, ctx; 00959 00960 if (rb_scan_args(argc, argv, "11", &io, &ctx) == 1) { 00961 ctx = rb_funcall(cSSLContext, rb_intern("new"), 0); 00962 } 00963 OSSL_Check_Kind(ctx, cSSLContext); 00964 Check_Type(io, T_FILE); 00965 ossl_ssl_set_io(self, io); 00966 ossl_ssl_set_ctx(self, ctx); 00967 ossl_ssl_set_sync_close(self, Qfalse); 00968 ossl_sslctx_setup(ctx); 00969 00970 rb_iv_set(self, "@hostname", Qnil); 00971 00972 rb_call_super(0, 0); 00973 00974 return self; 00975 } 00976 00977 static VALUE 00978 ossl_ssl_setup(VALUE self) 00979 { 00980 VALUE io, v_ctx, cb; 00981 SSL_CTX *ctx; 00982 SSL *ssl; 00983 rb_io_t *fptr; 00984 00985 Data_Get_Struct(self, SSL, ssl); 00986 if(!ssl){ 00987 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME 00988 VALUE hostname = rb_iv_get(self, "@hostname"); 00989 #endif 00990 00991 v_ctx = ossl_ssl_get_ctx(self); 00992 Data_Get_Struct(v_ctx, SSL_CTX, ctx); 00993 00994 ssl = SSL_new(ctx); 00995 if (!ssl) { 00996 ossl_raise(eSSLError, "SSL_new:"); 00997 } 00998 DATA_PTR(self) = ssl; 00999 01000 #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME 01001 if (!NIL_P(hostname)) { 01002 if (SSL_set_tlsext_host_name(ssl, StringValuePtr(hostname)) != 1) 01003 ossl_raise(eSSLError, "SSL_set_tlsext_host_name:"); 01004 } 01005 #endif 01006 io = ossl_ssl_get_io(self); 01007 GetOpenFile(io, fptr); 01008 rb_io_check_readable(fptr); 01009 rb_io_check_writable(fptr); 01010 SSL_set_fd(ssl, TO_SOCKET(FPTR_TO_FD(fptr))); 01011 SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void*)self); 01012 cb = ossl_sslctx_get_verify_cb(v_ctx); 01013 SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void*)cb); 01014 cb = ossl_sslctx_get_client_cert_cb(v_ctx); 01015 SSL_set_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx, (void*)cb); 01016 cb = ossl_sslctx_get_tmp_dh_cb(v_ctx); 01017 SSL_set_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx, (void*)cb); 01018 } 01019 01020 return Qtrue; 01021 } 01022 01023 #ifdef _WIN32 01024 #define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error(ssl, ret)) 01025 #else 01026 #define ssl_get_error(ssl, ret) SSL_get_error(ssl, ret) 01027 #endif 01028 01029 static void 01030 write_would_block(int nonblock) 01031 { 01032 if (nonblock) { 01033 VALUE exc = ossl_exc_new(eSSLError, "write would block"); 01034 rb_extend_object(exc, rb_mWaitWritable); 01035 rb_exc_raise(exc); 01036 } 01037 } 01038 01039 static void 01040 read_would_block(int nonblock) 01041 { 01042 if (nonblock) { 01043 VALUE exc = ossl_exc_new(eSSLError, "read would block"); 01044 rb_extend_object(exc, rb_mWaitReadable); 01045 rb_exc_raise(exc); 01046 } 01047 } 01048 01049 static VALUE 01050 ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, int nonblock) 01051 { 01052 SSL *ssl; 01053 rb_io_t *fptr; 01054 int ret, ret2; 01055 VALUE cb_state; 01056 01057 rb_ivar_set(self, ID_callback_state, Qnil); 01058 01059 Data_Get_Struct(self, SSL, ssl); 01060 GetOpenFile(ossl_ssl_get_io(self), fptr); 01061 for(;;){ 01062 ret = func(ssl); 01063 01064 cb_state = rb_ivar_get(self, ID_callback_state); 01065 if (!NIL_P(cb_state)) 01066 rb_jump_tag(NUM2INT(cb_state)); 01067 01068 if (ret > 0) 01069 break; 01070 01071 switch((ret2 = ssl_get_error(ssl, ret))){ 01072 case SSL_ERROR_WANT_WRITE: 01073 write_would_block(nonblock); 01074 rb_io_wait_writable(FPTR_TO_FD(fptr)); 01075 continue; 01076 case SSL_ERROR_WANT_READ: 01077 read_would_block(nonblock); 01078 rb_io_wait_readable(FPTR_TO_FD(fptr)); 01079 continue; 01080 case SSL_ERROR_SYSCALL: 01081 if (errno) rb_sys_fail(funcname); 01082 ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl)); 01083 default: 01084 ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl)); 01085 } 01086 } 01087 01088 return self; 01089 } 01090 01091 /* 01092 * call-seq: 01093 * ssl.connect => self 01094 */ 01095 static VALUE 01096 ossl_ssl_connect(VALUE self) 01097 { 01098 ossl_ssl_setup(self); 01099 return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0); 01100 } 01101 01102 /* 01103 * call-seq: 01104 * ssl.connect_nonblock => self 01105 * 01106 * initiate the TLS/SSL handshake as a client in non-blocking manner. 01107 * 01108 * # emulates blocking connect 01109 * begin 01110 * ssl.connect_nonblock 01111 * rescue IO::WaitReadable 01112 * IO.select([s2]) 01113 * retry 01114 * rescue IO::WaitWritable 01115 * IO.select(nil, [s2]) 01116 * retry 01117 * end 01118 * 01119 */ 01120 static VALUE 01121 ossl_ssl_connect_nonblock(VALUE self) 01122 { 01123 ossl_ssl_setup(self); 01124 return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1); 01125 } 01126 01127 /* 01128 * call-seq: 01129 * ssl.accept => self 01130 */ 01131 static VALUE 01132 ossl_ssl_accept(VALUE self) 01133 { 01134 ossl_ssl_setup(self); 01135 return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0); 01136 } 01137 01138 /* 01139 * call-seq: 01140 * ssl.accept_nonblock => self 01141 * 01142 * initiate the TLS/SSL handshake as a server in non-blocking manner. 01143 * 01144 * # emulates blocking accept 01145 * begin 01146 * ssl.accept_nonblock 01147 * rescue IO::WaitReadable 01148 * IO.select([s2]) 01149 * retry 01150 * rescue IO::WaitWritable 01151 * IO.select(nil, [s2]) 01152 * retry 01153 * end 01154 * 01155 */ 01156 static VALUE 01157 ossl_ssl_accept_nonblock(VALUE self) 01158 { 01159 ossl_ssl_setup(self); 01160 return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1); 01161 } 01162 01163 static VALUE 01164 ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) 01165 { 01166 SSL *ssl; 01167 int ilen, nread = 0; 01168 VALUE len, str; 01169 rb_io_t *fptr; 01170 01171 rb_scan_args(argc, argv, "11", &len, &str); 01172 ilen = NUM2INT(len); 01173 if(NIL_P(str)) str = rb_str_new(0, ilen); 01174 else{ 01175 StringValue(str); 01176 rb_str_modify(str); 01177 rb_str_resize(str, ilen); 01178 } 01179 if(ilen == 0) return str; 01180 01181 Data_Get_Struct(self, SSL, ssl); 01182 GetOpenFile(ossl_ssl_get_io(self), fptr); 01183 if (ssl) { 01184 if(!nonblock && SSL_pending(ssl) <= 0) 01185 rb_thread_wait_fd(FPTR_TO_FD(fptr)); 01186 for (;;){ 01187 nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LEN(str)); 01188 switch(ssl_get_error(ssl, nread)){ 01189 case SSL_ERROR_NONE: 01190 goto end; 01191 case SSL_ERROR_ZERO_RETURN: 01192 rb_eof_error(); 01193 case SSL_ERROR_WANT_WRITE: 01194 write_would_block(nonblock); 01195 rb_io_wait_writable(FPTR_TO_FD(fptr)); 01196 continue; 01197 case SSL_ERROR_WANT_READ: 01198 read_would_block(nonblock); 01199 rb_io_wait_readable(FPTR_TO_FD(fptr)); 01200 continue; 01201 case SSL_ERROR_SYSCALL: 01202 if(ERR_peek_error() == 0 && nread == 0) rb_eof_error(); 01203 rb_sys_fail(0); 01204 default: 01205 ossl_raise(eSSLError, "SSL_read:"); 01206 } 01207 } 01208 } 01209 else { 01210 ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread"); 01211 rb_warning("SSL session is not started yet."); 01212 return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str); 01213 } 01214 01215 end: 01216 rb_str_set_len(str, nread); 01217 OBJ_TAINT(str); 01218 01219 return str; 01220 } 01221 01222 01223 /* 01224 * call-seq: 01225 * ssl.sysread(length) => string 01226 * ssl.sysread(length, buffer) => buffer 01227 * 01228 * === Parameters 01229 * * +length+ is a positive integer. 01230 * * +buffer+ is a string used to store the result. 01231 */ 01232 static VALUE 01233 ossl_ssl_read(int argc, VALUE *argv, VALUE self) 01234 { 01235 return ossl_ssl_read_internal(argc, argv, self, 0); 01236 } 01237 01238 /* 01239 * call-seq: 01240 * ssl.sysread_nonblock(length) => string 01241 * ssl.sysread_nonblock(length, buffer) => buffer 01242 * 01243 * === Parameters 01244 * * +length+ is a positive integer. 01245 * * +buffer+ is a string used to store the result. 01246 */ 01247 static VALUE 01248 ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self) 01249 { 01250 return ossl_ssl_read_internal(argc, argv, self, 1); 01251 } 01252 01253 static VALUE 01254 ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock) 01255 { 01256 SSL *ssl; 01257 int nwrite = 0; 01258 rb_io_t *fptr; 01259 01260 StringValue(str); 01261 Data_Get_Struct(self, SSL, ssl); 01262 GetOpenFile(ossl_ssl_get_io(self), fptr); 01263 01264 if (ssl) { 01265 for (;;){ 01266 nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LEN(str)); 01267 switch(ssl_get_error(ssl, nwrite)){ 01268 case SSL_ERROR_NONE: 01269 goto end; 01270 case SSL_ERROR_WANT_WRITE: 01271 write_would_block(nonblock); 01272 rb_io_wait_writable(FPTR_TO_FD(fptr)); 01273 continue; 01274 case SSL_ERROR_WANT_READ: 01275 read_would_block(nonblock); 01276 rb_io_wait_readable(FPTR_TO_FD(fptr)); 01277 continue; 01278 case SSL_ERROR_SYSCALL: 01279 if (errno) rb_sys_fail(0); 01280 default: 01281 ossl_raise(eSSLError, "SSL_write:"); 01282 } 01283 } 01284 } 01285 else { 01286 ID id_syswrite = rb_intern("syswrite"); 01287 rb_warning("SSL session is not started yet."); 01288 return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str); 01289 } 01290 01291 end: 01292 return INT2NUM(nwrite); 01293 } 01294 01295 /* 01296 * call-seq: 01297 * ssl.syswrite(string) => integer 01298 */ 01299 static VALUE 01300 ossl_ssl_write(VALUE self, VALUE str) 01301 { 01302 return ossl_ssl_write_internal(self, str, 0); 01303 } 01304 01305 /* 01306 * call-seq: 01307 * ssl.syswrite_nonblock(string) => integer 01308 */ 01309 static VALUE 01310 ossl_ssl_write_nonblock(VALUE self, VALUE str) 01311 { 01312 return ossl_ssl_write_internal(self, str, 1); 01313 } 01314 01315 /* 01316 * call-seq: 01317 * ssl.sysclose => nil 01318 */ 01319 static VALUE 01320 ossl_ssl_close(VALUE self) 01321 { 01322 SSL *ssl; 01323 01324 Data_Get_Struct(self, SSL, ssl); 01325 ossl_ssl_shutdown(ssl); 01326 if (RTEST(ossl_ssl_get_sync_close(self))) 01327 rb_funcall(ossl_ssl_get_io(self), rb_intern("close"), 0); 01328 01329 return Qnil; 01330 } 01331 01332 /* 01333 * call-seq: 01334 * ssl.cert => cert or nil 01335 */ 01336 static VALUE 01337 ossl_ssl_get_cert(VALUE self) 01338 { 01339 SSL *ssl; 01340 X509 *cert = NULL; 01341 01342 Data_Get_Struct(self, SSL, ssl); 01343 if (!ssl) { 01344 rb_warning("SSL session is not started yet."); 01345 return Qnil; 01346 } 01347 01348 /* 01349 * Is this OpenSSL bug? Should add a ref? 01350 * TODO: Ask for. 01351 */ 01352 cert = SSL_get_certificate(ssl); /* NO DUPs => DON'T FREE. */ 01353 01354 if (!cert) { 01355 return Qnil; 01356 } 01357 return ossl_x509_new(cert); 01358 } 01359 01360 /* 01361 * call-seq: 01362 * ssl.peer_cert => cert or nil 01363 */ 01364 static VALUE 01365 ossl_ssl_get_peer_cert(VALUE self) 01366 { 01367 SSL *ssl; 01368 X509 *cert = NULL; 01369 VALUE obj; 01370 01371 Data_Get_Struct(self, SSL, ssl); 01372 01373 if (!ssl){ 01374 rb_warning("SSL session is not started yet."); 01375 return Qnil; 01376 } 01377 01378 cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */ 01379 01380 if (!cert) { 01381 return Qnil; 01382 } 01383 obj = ossl_x509_new(cert); 01384 X509_free(cert); 01385 01386 return obj; 01387 } 01388 01389 /* 01390 * call-seq: 01391 * ssl.peer_cert_chain => [cert, ...] or nil 01392 */ 01393 static VALUE 01394 ossl_ssl_get_peer_cert_chain(VALUE self) 01395 { 01396 SSL *ssl; 01397 STACK_OF(X509) *chain; 01398 X509 *cert; 01399 VALUE ary; 01400 int i, num; 01401 01402 Data_Get_Struct(self, SSL, ssl); 01403 if(!ssl){ 01404 rb_warning("SSL session is not started yet."); 01405 return Qnil; 01406 } 01407 chain = SSL_get_peer_cert_chain(ssl); 01408 if(!chain) return Qnil; 01409 num = sk_X509_num(chain); 01410 ary = rb_ary_new2(num); 01411 for (i = 0; i < num; i++){ 01412 cert = sk_X509_value(chain, i); 01413 rb_ary_push(ary, ossl_x509_new(cert)); 01414 } 01415 01416 return ary; 01417 } 01418 01419 /* 01420 * call-seq: 01421 * ssl.cipher => [name, version, bits, alg_bits] 01422 */ 01423 static VALUE 01424 ossl_ssl_get_cipher(VALUE self) 01425 { 01426 SSL *ssl; 01427 SSL_CIPHER *cipher; 01428 01429 Data_Get_Struct(self, SSL, ssl); 01430 if (!ssl) { 01431 rb_warning("SSL session is not started yet."); 01432 return Qnil; 01433 } 01434 cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl); 01435 01436 return ossl_ssl_cipher_to_ary(cipher); 01437 } 01438 01439 /* 01440 * call-seq: 01441 * ssl.state => string 01442 */ 01443 static VALUE 01444 ossl_ssl_get_state(VALUE self) 01445 { 01446 SSL *ssl; 01447 VALUE ret; 01448 01449 Data_Get_Struct(self, SSL, ssl); 01450 if (!ssl) { 01451 rb_warning("SSL session is not started yet."); 01452 return Qnil; 01453 } 01454 ret = rb_str_new2(SSL_state_string(ssl)); 01455 if (ruby_verbose) { 01456 rb_str_cat2(ret, ": "); 01457 rb_str_cat2(ret, SSL_state_string_long(ssl)); 01458 } 01459 return ret; 01460 } 01461 01462 /* 01463 * call-seq: 01464 * ssl.pending => integer 01465 */ 01466 static VALUE 01467 ossl_ssl_pending(VALUE self) 01468 { 01469 SSL *ssl; 01470 01471 Data_Get_Struct(self, SSL, ssl); 01472 if (!ssl) { 01473 rb_warning("SSL session is not started yet."); 01474 return Qnil; 01475 } 01476 01477 return INT2NUM(SSL_pending(ssl)); 01478 } 01479 01480 /* 01481 * call-seq: 01482 * ssl.session_reused? -> true | false 01483 * 01484 */ 01485 static VALUE 01486 ossl_ssl_session_reused(VALUE self) 01487 { 01488 SSL *ssl; 01489 01490 Data_Get_Struct(self, SSL, ssl); 01491 if (!ssl) { 01492 rb_warning("SSL session is not started yet."); 01493 return Qnil; 01494 } 01495 01496 switch(SSL_session_reused(ssl)) { 01497 case 1: return Qtrue; 01498 case 0: return Qfalse; 01499 default: ossl_raise(eSSLError, "SSL_session_reused"); 01500 } 01501 } 01502 01503 /* 01504 * call-seq: 01505 * ssl.session = session -> session 01506 * 01507 */ 01508 static VALUE 01509 ossl_ssl_set_session(VALUE self, VALUE arg1) 01510 { 01511 SSL *ssl; 01512 SSL_SESSION *sess; 01513 01514 /* why is ossl_ssl_setup delayed? */ 01515 ossl_ssl_setup(self); 01516 01517 Data_Get_Struct(self, SSL, ssl); 01518 if (!ssl) { 01519 rb_warning("SSL session is not started yet."); 01520 return Qnil; 01521 } 01522 01523 SafeGetSSLSession(arg1, sess); 01524 01525 if (SSL_set_session(ssl, sess) != 1) 01526 ossl_raise(eSSLError, "SSL_set_session"); 01527 01528 return arg1; 01529 } 01530 01531 static VALUE 01532 ossl_ssl_get_verify_result(VALUE self) 01533 { 01534 SSL *ssl; 01535 01536 Data_Get_Struct(self, SSL, ssl); 01537 if (!ssl) { 01538 rb_warning("SSL session is not started yet."); 01539 return Qnil; 01540 } 01541 01542 return INT2FIX(SSL_get_verify_result(ssl)); 01543 } 01544 01545 void 01546 Init_ossl_ssl() 01547 { 01548 int i; 01549 VALUE ary; 01550 01551 #if 0 /* let rdoc know about mOSSL */ 01552 mOSSL = rb_define_module("OpenSSL"); 01553 #endif 01554 01555 ID_callback_state = rb_intern("@callback_state"); 01556 01557 ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0); 01558 ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0); 01559 ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_ptr_idx",0,0,0); 01560 ossl_ssl_ex_client_cert_cb_idx = 01561 SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_client_cert_cb_idx",0,0,0); 01562 ossl_ssl_ex_tmp_dh_callback_idx = 01563 SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_tmp_dh_callback_idx",0,0,0); 01564 01565 mSSL = rb_define_module_under(mOSSL, "SSL"); 01566 eSSLError = rb_define_class_under(mSSL, "SSLError", eOSSLError); 01567 01568 Init_ossl_ssl_session(); 01569 01570 /* class SSLContext 01571 * 01572 * The following attributes are available but don't show up in rdoc. 01573 * All attributes must be set before calling SSLSocket.new(io, ctx). 01574 * * ssl_version, cert, key, client_ca, ca_file, ca_path, timeout, 01575 * * verify_mode, verify_depth client_cert_cb, tmp_dh_callback, 01576 * * session_id_context, session_add_cb, session_new_cb, session_remove_cb 01577 */ 01578 cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject); 01579 rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc); 01580 for(i = 0; i < numberof(ossl_sslctx_attrs); i++) 01581 rb_attr(cSSLContext, rb_intern(ossl_sslctx_attrs[i]), 1, 1, Qfalse); 01582 rb_define_alias(cSSLContext, "ssl_timeout", "timeout"); 01583 rb_define_alias(cSSLContext, "ssl_timeout=", "timeout="); 01584 rb_define_method(cSSLContext, "initialize", ossl_sslctx_initialize, -1); 01585 rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1); 01586 rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0); 01587 rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1); 01588 01589 rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0); 01590 01591 01592 rb_define_const(cSSLContext, "SESSION_CACHE_OFF", LONG2FIX(SSL_SESS_CACHE_OFF)); 01593 rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT", LONG2FIX(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */ 01594 rb_define_const(cSSLContext, "SESSION_CACHE_SERVER", LONG2FIX(SSL_SESS_CACHE_SERVER)); 01595 rb_define_const(cSSLContext, "SESSION_CACHE_BOTH", LONG2FIX(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */ 01596 rb_define_const(cSSLContext, "SESSION_CACHE_NO_AUTO_CLEAR", LONG2FIX(SSL_SESS_CACHE_NO_AUTO_CLEAR)); 01597 rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_LOOKUP", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)); 01598 rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_STORE", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_STORE)); 01599 rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL)); 01600 rb_define_method(cSSLContext, "session_add", ossl_sslctx_session_add, 1); 01601 rb_define_method(cSSLContext, "session_remove", ossl_sslctx_session_remove, 1); 01602 rb_define_method(cSSLContext, "session_cache_mode", ossl_sslctx_get_session_cache_mode, 0); 01603 rb_define_method(cSSLContext, "session_cache_mode=", ossl_sslctx_set_session_cache_mode, 1); 01604 rb_define_method(cSSLContext, "session_cache_size", ossl_sslctx_get_session_cache_size, 0); 01605 rb_define_method(cSSLContext, "session_cache_size=", ossl_sslctx_set_session_cache_size, 1); 01606 rb_define_method(cSSLContext, "session_cache_stats", ossl_sslctx_get_session_cache_stats, 0); 01607 rb_define_method(cSSLContext, "flush_sessions", ossl_sslctx_flush_sessions, -1); 01608 01609 ary = rb_ary_new2(numberof(ossl_ssl_method_tab)); 01610 for (i = 0; i < numberof(ossl_ssl_method_tab); i++) { 01611 rb_ary_push(ary, ID2SYM(rb_intern(ossl_ssl_method_tab[i].name))); 01612 } 01613 rb_obj_freeze(ary); 01614 /* holds a list of available SSL/TLS methods */ 01615 rb_define_const(cSSLContext, "METHODS", ary); 01616 01617 /* class SSLSocket 01618 * 01619 * The following attributes are available but don't show up in rdoc. 01620 * * io, context, sync_close 01621 * 01622 */ 01623 cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject); 01624 rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc); 01625 for(i = 0; i < numberof(ossl_ssl_attr_readers); i++) 01626 rb_attr(cSSLSocket, rb_intern(ossl_ssl_attr_readers[i]), 1, 0, Qfalse); 01627 for(i = 0; i < numberof(ossl_ssl_attrs); i++) 01628 rb_attr(cSSLSocket, rb_intern(ossl_ssl_attrs[i]), 1, 1, Qfalse); 01629 rb_define_alias(cSSLSocket, "to_io", "io"); 01630 rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1); 01631 rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0); 01632 rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, 0); 01633 rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0); 01634 rb_define_method(cSSLSocket, "accept_nonblock", ossl_ssl_accept_nonblock, 0); 01635 rb_define_method(cSSLSocket, "sysread", ossl_ssl_read, -1); 01636 rb_define_private_method(cSSLSocket, "sysread_nonblock", ossl_ssl_read_nonblock, -1); 01637 rb_define_method(cSSLSocket, "syswrite", ossl_ssl_write, 1); 01638 rb_define_private_method(cSSLSocket, "syswrite_nonblock", ossl_ssl_write_nonblock, 1); 01639 rb_define_method(cSSLSocket, "sysclose", ossl_ssl_close, 0); 01640 rb_define_method(cSSLSocket, "cert", ossl_ssl_get_cert, 0); 01641 rb_define_method(cSSLSocket, "peer_cert", ossl_ssl_get_peer_cert, 0); 01642 rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0); 01643 rb_define_method(cSSLSocket, "cipher", ossl_ssl_get_cipher, 0); 01644 rb_define_method(cSSLSocket, "state", ossl_ssl_get_state, 0); 01645 rb_define_method(cSSLSocket, "pending", ossl_ssl_pending, 0); 01646 rb_define_method(cSSLSocket, "session_reused?", ossl_ssl_session_reused, 0); 01647 rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1); 01648 rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0); 01649 01650 #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2NUM(SSL_##x)) 01651 01652 ossl_ssl_def_const(VERIFY_NONE); 01653 ossl_ssl_def_const(VERIFY_PEER); 01654 ossl_ssl_def_const(VERIFY_FAIL_IF_NO_PEER_CERT); 01655 ossl_ssl_def_const(VERIFY_CLIENT_ONCE); 01656 /* Not introduce constants included in OP_ALL such as... 01657 * ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG); 01658 * ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG); 01659 * ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG); 01660 * ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG); 01661 * ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER); 01662 * ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING); 01663 * ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG); 01664 * ossl_ssl_def_const(OP_TLS_D5_BUG); 01665 * ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG); 01666 * ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS); 01667 */ 01668 ossl_ssl_def_const(OP_ALL); 01669 #if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION) 01670 ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); 01671 #endif 01672 #if defined(SSL_OP_SINGLE_ECDH_USE) 01673 ossl_ssl_def_const(OP_SINGLE_ECDH_USE); 01674 #endif 01675 ossl_ssl_def_const(OP_SINGLE_DH_USE); 01676 ossl_ssl_def_const(OP_EPHEMERAL_RSA); 01677 #if defined(SSL_OP_CIPHER_SERVER_PREFERENCE) 01678 ossl_ssl_def_const(OP_CIPHER_SERVER_PREFERENCE); 01679 #endif 01680 ossl_ssl_def_const(OP_TLS_ROLLBACK_BUG); 01681 ossl_ssl_def_const(OP_NO_SSLv2); 01682 ossl_ssl_def_const(OP_NO_SSLv3); 01683 ossl_ssl_def_const(OP_NO_TLSv1); 01684 #if defined(SSL_OP_NO_TICKET) 01685 ossl_ssl_def_const(OP_NO_TICKET); 01686 #endif 01687 ossl_ssl_def_const(OP_PKCS1_CHECK_1); 01688 ossl_ssl_def_const(OP_PKCS1_CHECK_2); 01689 ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG); 01690 ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); 01691 } 01692
1.7.3