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