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