Object
class SSLSocket
The following attributes are available but don't show up in rdoc. * io, context, sync_close
io
is a real ruby IO object. Not an IO like object that
responds to read/write.
ctx
is an OpenSSLSSL::SSLContext.
The OpenSSL::Buffering module provides additional IO methods.
This method will freeze the SSLContext if one is provided; however, session management is still allowed in the frozen SSLContext.
static VALUE ossl_ssl_initialize(int argc, VALUE *argv, VALUE self) { VALUE io, ctx; if (rb_scan_args(argc, argv, "11", &io, &ctx) == 1) { ctx = rb_funcall(cSSLContext, rb_intern("new"), 0); } OSSL_Check_Kind(ctx, cSSLContext); Check_Type(io, T_FILE); ossl_ssl_set_io(self, io); ossl_ssl_set_ctx(self, ctx); ossl_ssl_set_sync_close(self, Qfalse); ossl_sslctx_setup(ctx); rb_call_super(0, 0); return self; }
static VALUE ossl_ssl_accept(VALUE self) { ossl_ssl_setup(self); return ossl_start_ssl(self, SSL_accept, "SSL_accept"); }
static VALUE ossl_ssl_get_cert(VALUE self) { SSL *ssl; X509 *cert = NULL; Data_Get_Struct(self, SSL, ssl); if (ssl) { rb_warning("SSL session is not started yet."); return Qnil; } /* * Is this OpenSSL bug? Should add a ref? * TODO: Ask for. */ cert = SSL_get_certificate(ssl); /* NO DUPs => DON'T FREE. */ if (!cert) { return Qnil; } return ossl_x509_new(cert); }
static VALUE ossl_ssl_get_cipher(VALUE self) { SSL *ssl; SSL_CIPHER *cipher; Data_Get_Struct(self, SSL, ssl); if (!ssl) { rb_warning("SSL session is not started yet."); return Qnil; } cipher = SSL_get_current_cipher(ssl); return ossl_ssl_cipher_to_ary(cipher); }
static VALUE ossl_ssl_connect(VALUE self) { ossl_ssl_setup(self); return ossl_start_ssl(self, SSL_connect, "SSL_connect"); }
static VALUE ossl_ssl_get_peer_cert(VALUE self) { SSL *ssl; X509 *cert = NULL; VALUE obj; Data_Get_Struct(self, SSL, ssl); if (!ssl){ rb_warning("SSL session is not started yet."); return Qnil; } cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */ if (!cert) { return Qnil; } obj = ossl_x509_new(cert); X509_free(cert); return obj; }
static VALUE ossl_ssl_get_peer_cert_chain(VALUE self) { SSL *ssl; STACK_OF(X509) *chain; X509 *cert; VALUE ary; int i, num; Data_Get_Struct(self, SSL, ssl); if(!ssl){ rb_warning("SSL session is not started yet."); return Qnil; } chain = SSL_get_peer_cert_chain(ssl); if(!chain) return Qnil; num = sk_num(chain); ary = rb_ary_new2(num); for (i = 0; i < num; i++){ cert = (X509*)sk_value(chain, i); rb_ary_push(ary, ossl_x509_new(cert)); } return ary; }
static VALUE ossl_ssl_pending(VALUE self) { SSL *ssl; Data_Get_Struct(self, SSL, ssl); if (!ssl) { rb_warning("SSL session is not started yet."); return Qnil; } return INT2NUM(SSL_pending(ssl)); }
# File openssl/lib/openssl/ssl.rb, line 120 def post_connection_check(hostname) unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) raise SSLError, "hostname was not match with the server certificate" end return true end
# File openssl/lib/openssl/ssl.rb, line 127 def session SSL::Session.new(self) rescue SSL::Session::SessionError nil end
static VALUE ossl_ssl_set_session(VALUE self, VALUE arg1) { SSL *ssl; SSL_SESSION *sess; /* why is ossl_ssl_setup delayed? */ ossl_ssl_setup(self); Data_Get_Struct(self, SSL, ssl); if (!ssl) { rb_warning("SSL session is not started yet."); return Qnil; } SafeGetSSLSession(arg1, sess); if (SSL_set_session(ssl, sess) != 1) ossl_raise(eSSLError, "SSL_set_session"); return arg1; }
static VALUE ossl_ssl_session_reused(VALUE self) { SSL *ssl; Data_Get_Struct(self, SSL, ssl); if (!ssl) { rb_warning("SSL session is not started yet."); return Qnil; } switch(SSL_session_reused(ssl)) { case 1: return Qtrue; case 0: return Qfalse; default: ossl_raise(eSSLError, "SSL_session_reused"); } }
static VALUE ossl_ssl_get_state(VALUE self) { SSL *ssl; VALUE ret; Data_Get_Struct(self, SSL, ssl); if (!ssl) { rb_warning("SSL session is not started yet."); return Qnil; } ret = rb_str_new2(SSL_state_string(ssl)); if (ruby_verbose) { rb_str_cat2(ret, ": "); rb_str_cat2(ret, SSL_state_string_long(ssl)); } return ret; }
static VALUE ossl_ssl_close(VALUE self) { SSL *ssl; Data_Get_Struct(self, SSL, ssl); ossl_ssl_shutdown(ssl); if (RTEST(ossl_ssl_get_sync_close(self))) rb_funcall(ossl_ssl_get_io(self), rb_intern("close"), 0); return Qnil; }
length
is a positive integer.
buffer
is a string used to store the result.
static VALUE ossl_ssl_read(int argc, VALUE *argv, VALUE self) { SSL *ssl; int ilen, nread = 0; VALUE len, str; rb_io_t *fptr; rb_scan_args(argc, argv, "11", &len, &str); ilen = NUM2INT(len); if(NIL_P(str)) str = rb_str_new(0, ilen); else{ StringValue(str); rb_str_modify(str); rb_str_resize(str, ilen); } if(ilen == 0) return str; Data_Get_Struct(self, SSL, ssl); GetOpenFile(ossl_ssl_get_io(self), fptr); if (ssl) { if(SSL_pending(ssl) <= 0) rb_thread_wait_fd(FPTR_TO_FD(fptr)); for (;;){ nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LEN(str)); switch(ssl_get_error(ssl, nread)){ case SSL_ERROR_NONE: goto end; case SSL_ERROR_ZERO_RETURN: rb_eof_error(); case SSL_ERROR_WANT_WRITE: rb_io_wait_writable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_WANT_READ: rb_io_wait_readable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_SYSCALL: if(ERR_peek_error() == 0 && nread == 0) rb_eof_error(); rb_sys_fail(0); default: ossl_raise(eSSLError, "SSL_read:"); } } } else { ID id_sysread = rb_intern("sysread"); rb_warning("SSL session is not started yet."); return rb_funcall(ossl_ssl_get_io(self), id_sysread, 2, len, str); } end: rb_str_set_len(str, nread); OBJ_TAINT(str); return str; }
static VALUE ossl_ssl_write(VALUE self, VALUE str) { SSL *ssl; int nwrite = 0; rb_io_t *fptr; StringValue(str); Data_Get_Struct(self, SSL, ssl); GetOpenFile(ossl_ssl_get_io(self), fptr); if (ssl) { for (;;){ nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LEN(str)); switch(ssl_get_error(ssl, nwrite)){ case SSL_ERROR_NONE: goto end; case SSL_ERROR_WANT_WRITE: rb_io_wait_writable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_WANT_READ: rb_io_wait_readable(FPTR_TO_FD(fptr)); continue; case SSL_ERROR_SYSCALL: if (errno) rb_sys_fail(0); default: ossl_raise(eSSLError, "SSL_write:"); } } } else { ID id_syswrite = rb_intern("syswrite"); rb_warning("SSL session is not started yet."); return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str); } end: return INT2NUM(nwrite); }