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
Class Method Summary collapse
-
.open(remote_host, remote_port, local_host = nil, local_port = nil, context: nil) ⇒ Object
call-seq: open(remote_host, remote_port, local_host=nil, local_port=nil, context: nil).
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.
-
#finished_message ⇒ Object
Returns the last Finished message sent.
-
#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.
-
#peer_finished_message ⇒ Object
Returns the last Finished message received.
-
#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, #fileno, #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.
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 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 |
# File 'ossl_ssl.c', line 1565
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.
364 365 366 |
# File 'lib/openssl/ssl.rb', line 364 def context @context end |
#hostname ⇒ Object (readonly)
Returns the value of attribute hostname.
357 358 359 |
# File 'lib/openssl/ssl.rb', line 357 def hostname @hostname end |
#io ⇒ Object (readonly) Also known as: to_io
The underlying IO object.
360 361 362 |
# File 'lib/openssl/ssl.rb', line 360 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
.
368 369 370 |
# File 'lib/openssl/ssl.rb', line 368 def sync_close @sync_close end |
Class Method Details
.open(remote_host, remote_port, local_host = nil, local_port = nil, context: nil) ⇒ Object
call-seq:
open(remote_host, remote_port, local_host=nil, local_port=nil, context: nil)
Creates a new instance of SSLSocket. remotehost_ and remoteport_ are used to open TCPSocket. If localhost_ and localport_ are specified, then those parameters are used on the local end to establish the connection. If context is provided, the SSL Sockets initial params will be taken from the context.
Examples
sock = OpenSSL::SSL::SSLSocket.open('localhost', 443)
sock.connect # Initiates a connection to localhost:443
with SSLContext:
ctx = OpenSSL::SSL::SSLContext.new
sock = OpenSSL::SSL::SSLSocket.open('localhost', 443, context: ctx)
sock.connect # Initiates a connection to localhost:443 with SSLContext
467 468 469 470 471 472 473 474 |
# File 'lib/openssl/ssl.rb', line 467 def open(remote_host, remote_port, local_host=nil, local_port=nil, context: nil) sock = ::TCPSocket.open(remote_host, remote_port, local_host, local_port) if context.nil? return OpenSSL::SSL::SSLSocket.new(sock) else return OpenSSL::SSL::SSLSocket.new(sock, context) end 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.
1776 1777 1778 1779 1780 1781 1782 |
# File 'ossl_ssl.c', line 1776
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.
1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 |
# File 'ossl_ssl.c', line 1806
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.
2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 |
# File 'ossl_ssl.c', line 2421
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.
2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 |
# File 'ossl_ssl.c', line 2083
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.
2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 |
# File 'ossl_ssl.c', line 2182
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.
2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 |
# File 'ossl_ssl.c', line 2376
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.
1728 1729 1730 1731 1732 1733 1734 |
# File 'ossl_ssl.c', line 1728
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.
1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 |
# File 'ossl_ssl.c', line 1758
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);
}
|
#finished_message ⇒ Object
Returns the last Finished message sent
2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 |
# File 'ossl_ssl.c', line 2322
static VALUE
ossl_ssl_get_finished(VALUE self)
{
SSL *ssl;
char sizer[1], *buf;
size_t len;
GetSSL(self, ssl);
len = SSL_get_finished(ssl, sizer, 0);
if (len == 0)
return Qnil;
buf = ALLOCA_N(char, len);
SSL_get_finished(ssl, buf, len);
return rb_str_new(buf, len);
}
|
#hostname=(hostname) ⇒ Object (readonly)
Sets the server hostname used for SNI. This needs to be set before SSLSocket#connect.
2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 |
# File 'ossl_ssl.c', line 2276
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.
2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 |
# File 'ossl_ssl.c', line 2396
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.
2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 |
# File 'ossl_ssl.c', line 2109
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.
2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 |
# File 'ossl_ssl.c', line 2135
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;
}
|
#peer_finished_message ⇒ Object
Returns the last Finished message received
2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 |
# File 'ossl_ssl.c', line 2347
static VALUE
ossl_ssl_get_peer_finished(VALUE self)
{
SSL *ssl;
char sizer[1], *buf;
size_t len;
GetSSL(self, ssl);
len = SSL_get_peer_finished(ssl, sizer, 0);
if (len == 0)
return Qnil;
buf = ALLOCA_N(char, len);
SSL_get_peer_finished(ssl, buf, len);
return rb_str_new(buf, len);
}
|
#pending ⇒ Integer
The number of bytes that are immediately available for reading.
2222 2223 2224 2225 2226 2227 2228 2229 2230 |
# File 'ossl_ssl.c', line 2222
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.
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 |
# File 'lib/openssl/ssl.rb', line 390 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.
411 412 413 414 415 |
# File 'lib/openssl/ssl.rb', line 411 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.
2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 |
# File 'ossl_ssl.c', line 2254
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.
2238 2239 2240 2241 2242 2243 2244 2245 2246 |
# File 'ossl_ssl.c', line 2238
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”.
2165 2166 2167 2168 2169 2170 2171 2172 2173 |
# File 'ossl_ssl.c', line 2165
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.
2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 |
# File 'ossl_ssl.c', line 2200
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.
377 378 379 380 381 |
# File 'lib/openssl/ssl.rb', line 377 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.
1924 1925 1926 1927 1928 |
# File 'ossl_ssl.c', line 1924
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.
2022 2023 2024 2025 2026 |
# File 'ossl_ssl.c', line 2022
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.
2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 |
# File 'ossl_ssl.c', line 2445
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.
2305 2306 2307 2308 2309 2310 2311 2312 2313 |
# File 'ossl_ssl.c', line 2305
static VALUE
ossl_ssl_get_verify_result(VALUE self)
{
SSL *ssl;
GetSSL(self, ssl);
return LONG2NUM(SSL_get_verify_result(ssl));
}
|