Object
class SSLSocket
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); }
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); }
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 67 def post_connection_check(hostname) check_common_name = true cert = peer_cert cert.extensions.each{|ext| next if ext.oid != "subjectAltName" ext.value.split(/,\s+/).each{|general_name| if /\ADNS:(.*)/ =~ general_name check_common_name = false reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+") return true if /\A#{reg}\z/i =~ hostname elsif /\AIP Address:(.*)/ =~ general_name check_common_name = false return true if $1 == hostname end } } if check_common_name cert.subject.to_a.each{|oid, value| if oid == "CN" reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+") return true if /\A#{reg}\z/i =~ hostname end } end raise SSLError, "hostname was not match with the server certificate" end
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; }
static VALUE ossl_ssl_read(int argc, VALUE *argv, VALUE self) { SSL *ssl; int ilen, nread = 0; VALUE len, str; OpenFile *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(fileno(fptr->f)); for (;;){ nread = SSL_read(ssl, RSTRING(str)->ptr, RSTRING(str)->len); 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(fileno(fptr->f)); continue; case SSL_ERROR_WANT_READ: rb_io_wait_readable(fileno(fptr->f)); 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: RSTRING(str)->len = nread; RSTRING(str)->ptr[nread] = 0; OBJ_TAINT(str); return str; }
static VALUE ossl_ssl_write(VALUE self, VALUE str) { SSL *ssl; int nwrite = 0; OpenFile *fptr; StringValue(str); Data_Get_Struct(self, SSL, ssl); GetOpenFile(ossl_ssl_get_io(self), fptr); if (ssl) { for (;;){ nwrite = SSL_write(ssl, RSTRING(str)->ptr, RSTRING(str)->len); switch(ssl_get_error(ssl, nwrite)){ case SSL_ERROR_NONE: goto end; case SSL_ERROR_WANT_WRITE: rb_io_wait_writable(fileno(fptr->f)); continue; case SSL_ERROR_WANT_READ: rb_io_wait_readable(fileno(fptr->f)); 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); }