Extended maintenance of Ruby 1.9.3 ended on February 23, 2015. Read more

In Files

  • openssl/lib/openssl/ssl-internal.rb
  • openssl/ossl_ssl.c

Class/Module Index [+]

Quicksearch

OpenSSL::SSL::SSLSocket

The following attributes are available but don't show up in rdoc.

  • io, context, sync_close

Public Class Methods

new(io) => aSSLSocket click to toggle source
new(io, ctx) => aSSLSocket

Creates a new SSL socket from io which must be a real ruby object (not an IO-like object that responds to read/write.

If ctx is provided the SSL Sockets initial params will be taken from the context.

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_iv_set(self, "@hostname", Qnil);

    rb_call_super(0, 0);

    return self;
}
            

Public Instance Methods

accept => self click to toggle source

Waits for a SSL/TLS client to initiate a handshake. The handshake may be started after unencrypted data has been sent over the socket.

 
               static VALUE
ossl_ssl_accept(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0);
}
            
accept_nonblock => self click to toggle source

Initiates the SSL/TLS handshake as a server in non-blocking manner.

# emulates blocking accept
begin
  ssl.accept_nonblock
rescue IO::WaitReadable
  IO.select([s2])
  retry
rescue IO::WaitWritable
  IO.select(nil, [s2])
  retry
end
 
               static VALUE
ossl_ssl_accept_nonblock(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1);
}
            
cert => cert or nil click to toggle source

The X509 certificate for this socket endpoint.

 
               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);
}
            
cipher => [name, version, bits, alg_bits] click to toggle source

The cipher being used for the current connection

 
               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_CIPHER *)SSL_get_current_cipher(ssl);

    return ossl_ssl_cipher_to_ary(cipher);
}
            
client_ca => [x509name, ...] click to toggle source

Returns the list of client CAs. Please note that in contrast to OpenSSL::SSL::SSLContext#client_ca no array of X509::Certificate is returned but X509::Name instances of the CA’s subject distinguished name.

In server mode, returns the list set by OpenSSL::SSL::SSLContext#client_ca. In client mode, returns the list of client CAs sent from the server.

 
               static VALUE
ossl_ssl_get_client_ca_list(VALUE self)
{
    SSL *ssl;
    STACK_OF(X509_NAME) *ca;

    Data_Get_Struct(self, SSL, ssl);
    if (!ssl) {
        rb_warning("SSL session is not started yet.");
        return Qnil;
    }

    ca = SSL_get_client_CA_list(ssl);
    return ossl_x509name_sk2ary(ca);
}
            
connect => self click to toggle source

Initiates an SSL/TLS handshake with a server. The handshake may be started after unencrypted data has been sent over the socket.

 
               static VALUE
ossl_ssl_connect(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0);
}
            
connect_nonblock => self click to toggle source

Initiates the SSL/TLS handshake as a client in non-blocking manner.

# emulates blocking connect
begin
  ssl.connect_nonblock
rescue IO::WaitReadable
  IO.select([s2])
  retry
rescue IO::WaitWritable
  IO.select(nil, [s2])
  retry
end
 
               static VALUE
ossl_ssl_connect_nonblock(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1);
}
            
peer_cert => cert or nil click to toggle source

The X509 certificate for this socket’s peer.

 
               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;
}
            
peer_cert_chain => [cert, ...] or nil click to toggle source

The X509 certificate chain for this socket’s peer.

 
               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_X509_num(chain);
    ary = rb_ary_new2(num);
    for (i = 0; i < num; i++){
        cert = sk_X509_value(chain, i);
        rb_ary_push(ary, ossl_x509_new(cert));
    }

    return ary;
}
            
pending => Integer click to toggle source

The number of bytes that are immediately available for reading

 
               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));
}
            
post_connection_check(hostname) click to toggle source
 
               # File openssl/lib/openssl/ssl-internal.rb, line 168
def post_connection_check(hostname)
  unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
    raise SSLError, "hostname does not match the server certificate"
  end
  return true
end
            
session() click to toggle source
 
               # File openssl/lib/openssl/ssl-internal.rb, line 175
def session
  SSL::Session.new(self)
rescue SSL::Session::SessionError
  nil
end
            
session = session → session click to toggle source

Sets the Session to be used when the connection is established.

 
               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;
}
            
session_reused? → true | false click to toggle source

Returns true if a reused session was negotiated during the handshake.

 
               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");
    }
}
            
state => string click to toggle source

A description of the current connection state.

 
               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;
}
            
sysclose => nil click to toggle source

Shuts down the SSL connection and prepares it for another connection.

 
               static VALUE
ossl_ssl_close(VALUE self)
{
    SSL *ssl;

    Data_Get_Struct(self, SSL, ssl);
    if (ssl) {
        VALUE io = ossl_ssl_get_io(self);
        if (!RTEST(rb_funcall(io, rb_intern("closed?"), 0))) {
            ossl_ssl_shutdown(ssl);
            SSL_free(ssl);
            DATA_PTR(self) = NULL;
            if (RTEST(ossl_ssl_get_sync_close(self)))
                rb_funcall(io, rb_intern("close"), 0);
        }
    }

    return Qnil;
}
            
sysread(length) => string click to toggle source
sysread(length, buffer) => buffer

Reads length bytes from the SSL connection. If a pre-allocated buffer is provided the data will be written into it.

 
               static VALUE
ossl_ssl_read(int argc, VALUE *argv, VALUE self)
{
    return ossl_ssl_read_internal(argc, argv, self, 0);
}
            
syswrite(string) => Integer click to toggle source

Writes string to the SSL connection.

 
               static VALUE
ossl_ssl_write(VALUE self, VALUE str)
{
    return ossl_ssl_write_internal(self, str, 0);
}
            
verify_result => Integer click to toggle source

Returns the result of the peer certificates verification. See verify(1) for error values and descriptions.

If no peer certificate was presented X509_V_OK is returned.

 
               static VALUE
ossl_ssl_get_verify_result(VALUE self)
{
    SSL *ssl;

    Data_Get_Struct(self, SSL, ssl);
    if (!ssl) {
        rb_warning("SSL session is not started yet.");
        return Qnil;
    }

    return INT2FIX(SSL_get_verify_result(ssl));
}
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.