Class: OpenSSL::SSL::SSLSocket

Inherits:
Object
  • Object
show all
Includes:
Buffering, Nonblock, SocketForwarder
Defined in:
ossl_ssl.c,
lib/openssl/ssl.rb,
ossl_ssl.c

Overview

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

  • io, context, sync_close

Constant Summary

Constants included from Buffering

Buffering::BLOCK_SIZE

Instance Attribute Summary

Attributes included from Buffering

#sync

Instance Method Summary collapse

Methods included from SocketForwarder

#addr, #closed?, #do_not_reverse_lookup=, #fcntl, #getsockopt, #peeraddr, #setsockopt

Methods included from Buffering

#<<, #close, #each, #each_byte, #eof?, #flush, #getc, #gets, #print, #printf, #puts, #read, #read_nonblock, #readchar, #readline, #readlines, #readpartial, #ungetc, #write, #write_nonblock

Constructor Details

#new(io) ⇒ aSSLSocket #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.



1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
# File 'ossl_ssl.c', line 1150

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;
}

Instance Method Details

#acceptself

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



1341
1342
1343
1344
1345
1346
# File 'ossl_ssl.c', line 1341

static VALUE
ossl_ssl_accept(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0);
}

#accept_nonblockself

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


1366
1367
1368
1369
1370
1371
# File 'ossl_ssl.c', line 1366

static VALUE
ossl_ssl_accept_nonblock(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1);
}

#certnil

The X509 certificate for this socket endpoint.



1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
# File 'ossl_ssl.c', line 1588

static VALUE
ossl_ssl_get_cert(VALUE self)
{
    SSL *ssl;
    X509 *cert = NULL;

    ossl_ssl_data_get_struct(self, ssl);

    /*
     * 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);
}

#cipherArray

The cipher being used for the current connection



1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
# File 'ossl_ssl.c', line 1686

static VALUE
ossl_ssl_get_cipher(VALUE self)
{
    SSL *ssl;
    SSL_CIPHER *cipher;

    ossl_ssl_data_get_struct(self, ssl);

    cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl);

    return ossl_ssl_cipher_to_ary(cipher);
}

#client_caArray

Returns the list of client CAs. Please note that in contrast to 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 SSLContext#client_ca=. In client mode, returns the list of client CAs sent from the server.



1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
# File 'ossl_ssl.c', line 1814

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

    ossl_ssl_data_get_struct(self, ssl);

    ca = SSL_get_client_CA_list(ssl);
    return ossl_x509name_sk2ary(ca);
}

#connectself

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



1302
1303
1304
1305
1306
1307
# File 'ossl_ssl.c', line 1302

static VALUE
ossl_ssl_connect(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0);
}

#connect_nonblockself

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


1327
1328
1329
1330
1331
1332
# File 'ossl_ssl.c', line 1327

static VALUE
ossl_ssl_connect_nonblock(VALUE self)
{
    ossl_ssl_setup(self);
    return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1);
}

#npn_protocolString

Returns the protocol string that was finally selected by the client during the handshake.



1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
# File 'ossl_ssl.c', line 1834

static VALUE
ossl_ssl_npn_protocol(VALUE self)
{
    SSL *ssl;
    const unsigned char *out;
    unsigned int outlen;

    ossl_ssl_data_get_struct(self, ssl);

    SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
    if (!outlen)
  return Qnil;
    else
  return rb_str_new((const char *) out, outlen);
}

#peer_certnil

The X509 certificate for this socket’s peer.



1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
# File 'ossl_ssl.c', line 1614

static VALUE
ossl_ssl_get_peer_cert(VALUE self)
{
    SSL *ssl;
    X509 *cert = NULL;
    VALUE obj;

    ossl_ssl_data_get_struct(self, ssl);

    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_chainArray?

The X509 certificate chain for this socket’s peer.



1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
# File 'ossl_ssl.c', line 1640

static VALUE
ossl_ssl_get_peer_cert_chain(VALUE self)
{
    SSL *ssl;
    STACK_OF(X509) *chain;
    X509 *cert;
    VALUE ary;
    int i, num;

    ossl_ssl_data_get_struct(self, ssl);

    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;
}

#pendingInteger

The number of bytes that are immediately available for reading



1727
1728
1729
1730
1731
1732
1733
1734
1735
# File 'ossl_ssl.c', line 1727

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

    ossl_ssl_data_get_struct(self, ssl);

    return INT2NUM(SSL_pending(ssl));
}

#post_connection_check(hostname) ⇒ Object

Perform hostname verification after an SSL connection is established

This method MUST be called after calling #connect to ensure that the hostname of a remote peer has been verified.



230
231
232
233
234
235
# File 'lib/openssl/ssl.rb', line 230

def post_connection_check(hostname)
  unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
    raise SSLError, "hostname \"#{hostname}\" does not match the server certificate"
  end
  return true
end

#sessionObject



237
238
239
240
241
# File 'lib/openssl/ssl.rb', line 237

def session
  SSL::Session.new(self)
rescue SSL::Session::SessionError
  nil
end

#session=(session) ⇒ Object

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



1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
# File 'ossl_ssl.c', line 1765

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);

    ossl_ssl_data_get_struct(self, ssl);

    SafeGetSSLSession(arg1, sess);

    if (SSL_set_session(ssl, sess) != 1)
        ossl_raise(eSSLError, "SSL_set_session");

    return arg1;
}

#session_reused?Boolean

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



1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
# File 'ossl_ssl.c', line 1743

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

    ossl_ssl_data_get_struct(self, ssl);

    switch(SSL_session_reused(ssl)) {
    case 1: return Qtrue;
    case 0: return Qfalse;
    default:  ossl_raise(eSSLError, "SSL_session_reused");
    }

    UNREACHABLE;
}

#ssl_versionString

Returns a String representing the SSL/TLS version that was negotiated for the connection, for example “TLSv1.2”.



1670
1671
1672
1673
1674
1675
1676
1677
1678
# File 'ossl_ssl.c', line 1670

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

    ossl_ssl_data_get_struct(self, ssl);

    return rb_str_new2(SSL_get_version(ssl));
}

#stateString

A description of the current connection state.



1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
# File 'ossl_ssl.c', line 1705

static VALUE
ossl_ssl_get_state(VALUE self)
{
    SSL *ssl;
    VALUE ret;

    ossl_ssl_data_get_struct(self, ssl);

    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;
}

#sysclosenil

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



1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
# File 'ossl_ssl.c', line 1561

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

    ossl_ssl_data_get_struct(self, 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 #sysread(length, buffer) ⇒ Object

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



1452
1453
1454
1455
1456
# File 'ossl_ssl.c', line 1452

static VALUE
ossl_ssl_read(int argc, VALUE *argv, VALUE self)
{
    return ossl_ssl_read_internal(argc, argv, self, 0);
}

#syswrite(string) ⇒ Integer

Writes string to the SSL connection.



1527
1528
1529
1530
1531
# File 'ossl_ssl.c', line 1527

static VALUE
ossl_ssl_write(VALUE self, VALUE str)
{
    return ossl_ssl_write_internal(self, str, 0, 0);
}

#verify_resultInteger

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.



1793
1794
1795
1796
1797
1798
1799
1800
1801
# File 'ossl_ssl.c', line 1793

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

    ossl_ssl_data_get_struct(self, ssl);

    return INT2FIX(SSL_get_verify_result(ssl));
}