Class: OpenSSL::SSL::SSLSocket
- Inherits:
-
Object
- Object
- OpenSSL::SSL::SSLSocket
- Includes:
- Buffering, SocketForwarder
- Defined in:
- lib/openssl/ssl.rb,
ossl_ssl.c
Constant Summary
Constants included from Buffering
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
The SSLContext object used in this connection.
-
#hostname ⇒ Object
readonly
Returns the value of attribute hostname.
-
#io ⇒ Object
(also: #to_io)
readonly
The underlying IO object.
-
#sync_close ⇒ Object
Whether to close the underlying socket as well, when the SSL/TLS connection is shut down.
Attributes included from Buffering
Instance Method Summary collapse
-
#accept ⇒ self
Waits for a SSL/TLS client to initiate a handshake.
-
#accept_nonblock([options]) ⇒ self
Initiates the SSL/TLS handshake as a server in non-blocking manner.
-
#alpn_protocol ⇒ String | nil
Returns the ALPN protocol string that was finally selected by the server during the handshake.
-
#cert ⇒ nil
The X509 certificate for this socket endpoint.
-
#cipher ⇒ nil, Array
Returns the cipher suite actually used in the current session, or nil if no session has been established.
-
#client_ca ⇒ Array
Returns the list of client CAs.
-
#connect ⇒ self
Initiates an SSL/TLS handshake with a server.
-
#connect_nonblock([options]) ⇒ self
Initiates the SSL/TLS handshake as a client in non-blocking manner.
-
#hostname(hostname) ⇒ Object
readonly
Sets the server hostname used for SNI.
-
#initialize(*args) ⇒ Object
constructor
Creates a new SSL socket from io which must be a real IO object (not an IO-like object that responds to read/write).
-
#npn_protocol ⇒ String | nil
Returns the protocol string that was finally selected by the client during the handshake.
-
#peer_cert ⇒ nil
The X509 certificate for this socket’s peer.
-
#peer_cert_chain ⇒ Array?
The X509 certificate chain for this socket’s peer.
-
#pending ⇒ Integer
The number of bytes that are immediately available for reading.
-
#post_connection_check(hostname) ⇒ Object
call-seq: ssl.post_connection_check(hostname) -> true.
-
#session ⇒ Object
call-seq: ssl.session -> aSession.
-
#session=(session) ⇒ Object
Sets the Session to be used when the connection is established.
-
#session_reused? ⇒ Boolean
Returns
true
if a reused session was negotiated during the handshake. -
#ssl_version ⇒ String
Returns a String representing the SSL/TLS version that was negotiated for the connection, for example “TLSv1.2”.
-
#state ⇒ String
A description of the current connection state.
-
#sysclose ⇒ Object
call-seq: ssl.sysclose => nil.
-
#sysread(*args) ⇒ Object
Reads length bytes from the SSL connection.
-
#syswrite(string) ⇒ Integer
Writes string to the SSL connection.
-
#tmp_key ⇒ PKey?
Returns the ephemeral key used in case of forward secrecy cipher.
-
#verify_result ⇒ Integer
Returns the result of the peer certificates verification.
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 IO 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.
1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 |
# File 'ossl_ssl.c', line 1554
static VALUE
ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
{
VALUE io, v_ctx, verify_cb;
SSL *ssl;
SSL_CTX *ctx;
TypedData_Get_Struct(self, SSL, &ossl_ssl_type, ssl);
if (ssl)
ossl_raise(eSSLError, "SSL already initialized");
if (rb_scan_args(argc, argv, "11", &io, &v_ctx) == 1)
v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
GetSSLCTX(v_ctx, ctx);
rb_ivar_set(self, id_i_context, v_ctx);
ossl_sslctx_setup(v_ctx);
if (rb_respond_to(io, rb_intern("nonblock=")))
rb_funcall(io, rb_intern("nonblock="), 1, Qtrue);
rb_ivar_set(self, id_i_io, io);
ssl = SSL_new(ctx);
if (!ssl)
ossl_raise(eSSLError, NULL);
RTYPEDDATA_DATA(self) = ssl;
SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
SSL_set_info_callback(ssl, ssl_info_cb);
verify_cb = rb_attr_get(v_ctx, id_i_verify_callback);
SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
rb_call_super(0, NULL);
return self;
}
|
Instance Attribute Details
#context ⇒ Object (readonly)
The SSLContext object used in this connection.
358 359 360 |
# File 'lib/openssl/ssl.rb', line 358 def context @context end |
#hostname ⇒ Object (readonly)
Returns the value of attribute hostname
351 352 353 |
# File 'lib/openssl/ssl.rb', line 351 def hostname @hostname end |
#io ⇒ Object (readonly) Also known as: to_io
The underlying IO object.
354 355 356 |
# File 'lib/openssl/ssl.rb', line 354 def io @io end |
#sync_close ⇒ Object
Whether to close the underlying socket as well, when the SSL/TLS connection is shut down. This defaults to false
.
362 363 364 |
# File 'lib/openssl/ssl.rb', line 362 def sync_close @sync_close end |
Instance Method Details
#accept ⇒ self
Waits for a SSL/TLS client to initiate a handshake. The handshake may be started after unencrypted data has been sent over the socket.
1765 1766 1767 1768 1769 1770 1771 |
# File 'ossl_ssl.c', line 1765
static VALUE
ossl_ssl_accept(VALUE self)
{
ossl_ssl_setup(self);
return ossl_start_ssl(self, SSL_accept, "SSL_accept", Qfalse);
}
|
#accept_nonblock([options]) ⇒ self
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
By specifying a keyword argument exception to false
, you can indicate that accept_nonblock should not raise an IO::WaitReadable or IO::WaitWritable exception, but return the symbol :wait_readable
or :wait_writable
instead.
1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 |
# File 'ossl_ssl.c', line 1795
static VALUE
ossl_ssl_accept_nonblock(int argc, VALUE *argv, VALUE self)
{
VALUE opts;
rb_scan_args(argc, argv, "0:", &opts);
ossl_ssl_setup(self);
return ossl_start_ssl(self, SSL_accept, "SSL_accept", opts);
}
|
#alpn_protocol ⇒ String | nil
Returns the ALPN protocol string that was finally selected by the server during the handshake.
2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 |
# File 'ossl_ssl.c', line 2351
static VALUE
ossl_ssl_alpn_protocol(VALUE self)
{
SSL *ssl;
const unsigned char *out;
unsigned int outlen;
GetSSL(self, ssl);
SSL_get0_alpn_selected(ssl, &out, &outlen);
if (!outlen)
return Qnil;
else
return rb_str_new((const char *) out, outlen);
}
|
#cert ⇒ nil
The X509 certificate for this socket endpoint.
2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 |
# File 'ossl_ssl.c', line 2063
static VALUE
ossl_ssl_get_cert(VALUE self)
{
SSL *ssl;
X509 *cert = NULL;
GetSSL(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);
}
|
#cipher ⇒ nil, Array
Returns the cipher suite actually used in the current session, or nil if no session has been established.
2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 |
# File 'ossl_ssl.c', line 2162
static VALUE
ossl_ssl_get_cipher(VALUE self)
{
SSL *ssl;
const SSL_CIPHER *cipher;
GetSSL(self, ssl);
cipher = SSL_get_current_cipher(ssl);
return cipher ? ossl_ssl_cipher_to_ary(cipher) : Qnil;
}
|
#client_ca ⇒ Array
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.
2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 |
# File 'ossl_ssl.c', line 2306
static VALUE
ossl_ssl_get_client_ca_list(VALUE self)
{
SSL *ssl;
STACK_OF(X509_NAME) *ca;
GetSSL(self, ssl);
ca = SSL_get_client_CA_list(ssl);
return ossl_x509name_sk2ary(ca);
}
|
#connect ⇒ self
Initiates an SSL/TLS handshake with a server. The handshake may be started after unencrypted data has been sent over the socket.
1717 1718 1719 1720 1721 1722 1723 |
# File 'ossl_ssl.c', line 1717
static VALUE
ossl_ssl_connect(VALUE self)
{
ossl_ssl_setup(self);
return ossl_start_ssl(self, SSL_connect, "SSL_connect", Qfalse);
}
|
#connect_nonblock([options]) ⇒ self
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
By specifying a keyword argument exception to false
, you can indicate that connect_nonblock should not raise an IO::WaitReadable or IO::WaitWritable exception, but return the symbol :wait_readable
or :wait_writable
instead.
1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 |
# File 'ossl_ssl.c', line 1747
static VALUE
ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self)
{
VALUE opts;
rb_scan_args(argc, argv, "0:", &opts);
ossl_ssl_setup(self);
return ossl_start_ssl(self, SSL_connect, "SSL_connect", opts);
}
|
#hostname=(hostname) ⇒ Object (readonly)
Sets the server hostname used for SNI. This needs to be set before SSLSocket#connect.
2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 |
# File 'ossl_ssl.c', line 2256
static VALUE
ossl_ssl_set_hostname(VALUE self, VALUE arg)
{
SSL *ssl;
char *hostname = NULL;
GetSSL(self, ssl);
if (!NIL_P(arg))
hostname = StringValueCStr(arg);
if (!SSL_set_tlsext_host_name(ssl, hostname))
ossl_raise(eSSLError, NULL);
/* for SSLSocket#hostname */
rb_ivar_set(self, id_i_hostname, arg);
return arg;
}
|
#npn_protocol ⇒ String | nil
Returns the protocol string that was finally selected by the client during the handshake.
2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 |
# File 'ossl_ssl.c', line 2326
static VALUE
ossl_ssl_npn_protocol(VALUE self)
{
SSL *ssl;
const unsigned char *out;
unsigned int outlen;
GetSSL(self, ssl);
SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
if (!outlen)
return Qnil;
else
return rb_str_new((const char *) out, outlen);
}
|
#peer_cert ⇒ nil
The X509 certificate for this socket’s peer.
2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 |
# File 'ossl_ssl.c', line 2089
static VALUE
ossl_ssl_get_peer_cert(VALUE self)
{
SSL *ssl;
X509 *cert = NULL;
VALUE obj;
GetSSL(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_chain ⇒ Array?
The X509 certificate chain for this socket’s peer.
2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 |
# File 'ossl_ssl.c', line 2115
static VALUE
ossl_ssl_get_peer_cert_chain(VALUE self)
{
SSL *ssl;
STACK_OF(X509) *chain;
X509 *cert;
VALUE ary;
int i, num;
GetSSL(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;
}
|
#pending ⇒ Integer
The number of bytes that are immediately available for reading.
2202 2203 2204 2205 2206 2207 2208 2209 2210 |
# File 'ossl_ssl.c', line 2202
static VALUE
ossl_ssl_pending(VALUE self)
{
SSL *ssl;
GetSSL(self, ssl);
return INT2NUM(SSL_pending(ssl));
}
|
#post_connection_check(hostname) ⇒ Object
call-seq:
ssl.post_connection_check(hostname) -> true
Perform hostname verification following RFC 6125.
This method MUST be called after calling #connect to ensure that the hostname of a remote peer has been verified.
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/openssl/ssl.rb', line 384 def post_connection_check(hostname) if peer_cert.nil? msg = "Peer verification enabled, but no certificate received." if using_anon_cipher? msg += " Anonymous cipher suite #{cipher[0]} was negotiated. " \ "Anonymous suites must be disabled to use peer verification." end raise SSLError, msg end unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) raise SSLError, "hostname \"#{hostname}\" does not match the server certificate" end return true end |
#session ⇒ Object
call-seq:
ssl.session -> aSession
Returns the SSLSession object currently used, or nil if the session is not established.
405 406 407 408 409 |
# File 'lib/openssl/ssl.rb', line 405 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.
2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 |
# File 'ossl_ssl.c', line 2234
static VALUE
ossl_ssl_set_session(VALUE self, VALUE arg1)
{
SSL *ssl;
SSL_SESSION *sess;
GetSSL(self, ssl);
GetSSLSession(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.
2218 2219 2220 2221 2222 2223 2224 2225 2226 |
# File 'ossl_ssl.c', line 2218
static VALUE
ossl_ssl_session_reused(VALUE self)
{
SSL *ssl;
GetSSL(self, ssl);
return SSL_session_reused(ssl) ? Qtrue : Qfalse;
}
|
#ssl_version ⇒ String
Returns a String representing the SSL/TLS version that was negotiated for the connection, for example “TLSv1.2”.
2145 2146 2147 2148 2149 2150 2151 2152 2153 |
# File 'ossl_ssl.c', line 2145
static VALUE
ossl_ssl_get_version(VALUE self)
{
SSL *ssl;
GetSSL(self, ssl);
return rb_str_new2(SSL_get_version(ssl));
}
|
#state ⇒ String
A description of the current connection state. This is for diagnostic purposes only.
2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 |
# File 'ossl_ssl.c', line 2180
static VALUE
ossl_ssl_get_state(VALUE self)
{
SSL *ssl;
VALUE ret;
GetSSL(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;
}
|
#sysclose ⇒ Object
call-seq:
ssl.sysclose => nil
Sends “close notify” to the peer and tries to shut down the SSL connection gracefully.
If sync_close is set to true
, the underlying IO is also closed.
371 372 373 374 375 |
# File 'lib/openssl/ssl.rb', line 371 def sysclose return if closed? stop io.close if sync_close end |
#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.
1907 1908 1909 1910 1911 |
# File 'ossl_ssl.c', line 1907
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.
2000 2001 2002 2003 2004 |
# File 'ossl_ssl.c', line 2000
static VALUE
ossl_ssl_write(VALUE self, VALUE str)
{
return ossl_ssl_write_internal(self, str, Qfalse);
}
|
#tmp_key ⇒ PKey?
Returns the ephemeral key used in case of forward secrecy cipher.
2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 |
# File 'ossl_ssl.c', line 2375
static VALUE
ossl_ssl_tmp_key(VALUE self)
{
SSL *ssl;
EVP_PKEY *key;
GetSSL(self, ssl);
if (!SSL_get_server_tmp_key(ssl, &key))
return Qnil;
return ossl_pkey_new(key);
}
|
#verify_result ⇒ Integer
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.
2285 2286 2287 2288 2289 2290 2291 2292 2293 |
# File 'ossl_ssl.c', line 2285
static VALUE
ossl_ssl_get_verify_result(VALUE self)
{
SSL *ssl;
GetSSL(self, ssl);
return INT2NUM(SSL_get_verify_result(ssl));
}
|