Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions ext/openssl/ossl_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,30 @@ ossl_sslctx_set_min_version(VALUE self, VALUE v)
return v;
}

/*
* call-seq:
* ssl.min_version = OpenSSL::SSL::TLS1_2_VERSION
* ssl.min_version = :TLS1_2
* ssl.min_version = 0
* ssl.min_version = nil
*
* Sets the lower bound of the supported SSL/TLS protocol version range for
* this connection only. See SSLContext#min_version= for the possible values.
*/
static VALUE
ossl_ssl_set_min_version(VALUE self, VALUE v)
{
SSL *ssl;
int version;

GetSSL(self, ssl);
version = parse_proto_version(v);

if (!SSL_set_min_proto_version(ssl, version))
ossl_raise(eSSLError, "SSL_set_min_proto_version");
return v;
}

/*
* call-seq:
* ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
Expand All @@ -979,6 +1003,30 @@ ossl_sslctx_set_max_version(VALUE self, VALUE v)
return v;
}

/*
* call-seq:
* ssl.max_version = OpenSSL::SSL::TLS1_2_VERSION
* ssl.max_version = :TLS1_2
* ssl.max_version = 0
* ssl.max_version = nil
*
* Sets the upper bound of the supported SSL/TLS protocol version range for
* this connection only. See #min_version= for details.
*/
static VALUE
ossl_ssl_set_max_version(VALUE self, VALUE v)
{
SSL *ssl;
int version;

GetSSL(self, ssl);
version = parse_proto_version(v);

if (!SSL_set_max_proto_version(ssl, version))
ossl_raise(eSSLError, "SSL_set_max_proto_version");
return v;
}

static VALUE
ossl_ssl_cipher_to_ary(const SSL_CIPHER *cipher)
{
Expand Down Expand Up @@ -2973,6 +3021,8 @@ Init_ossl_ssl(void)
rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
/* #hostname is defined in lib/openssl/ssl.rb */
rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
rb_define_method(cSSLSocket, "min_version=", ossl_ssl_set_min_version, 1);
rb_define_method(cSSLSocket, "max_version=", ossl_ssl_set_max_version, 1);
rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0);
rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0);
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
Expand Down
33 changes: 33 additions & 0 deletions test/openssl/test_ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1500,6 +1500,39 @@ def test_minmax_version_symbols
}
end

def test_socket_minmax_version
start_server { |port|
sock = TCPSocket.new("127.0.0.1", port)
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
ssl.min_version = ssl.max_version = :TLS1_2
ssl.connect
assert_equal("TLSv1.2", ssl.ssl_version)
ssl.close
}

# Invalid
IO.pipe { |r, _w|
ssl = OpenSSL::SSL::SSLSocket.new(r)
assert_raise(ArgumentError) { ssl.min_version = :bogus }
assert_raise(ArgumentError) { ssl.max_version = :bogus }
}
end

def test_socket_minmax_version_server
sctx = make_server_context
server_proc = -> sock {
ssl = OpenSSL::SSL::SSLSocket.new(sock, sctx)
ssl.max_version = OpenSSL::SSL::TLS1_2_VERSION
ssl.accept
}
start_server_proc(server_proc) { |port|
server_connect(port) { |ssl|
assert_equal("TLSv1.2", ssl.ssl_version)
}
}
end

def test_minmax_version_system_default
omit "LibreSSL and AWS-LC do not support OPENSSL_CONF" if libressl? || aws_lc?

Expand Down
Loading