Skip to content

ssl: rename SSLContext#ecdh_curves= to #groups= #900

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
32 changes: 17 additions & 15 deletions ext/openssl/ossl_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1120,47 +1120,48 @@ ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg)
}
#endif

#if !defined(OPENSSL_NO_EC)
/*
* call-seq:
* ctx.ecdh_curves = curve_list -> curve_list
* ctx.groups = groups_list
* ctx.ecdh_curves = groups_list
*
* Sets the list of "supported elliptic curves" for this context.
* Sets the list of supported groups for key agreement for this context.
*
* For a TLS client, the list is directly used in the Supported Elliptic Curves
* Extension. For a server, the list is used by OpenSSL to determine the set of
* shared curves. OpenSSL will pick the most appropriate one from it.
* For a TLS client, the list is directly used in the "supported_groups"
* extension. For a server, the list is used by OpenSSL to determine the set of
* shared supported groups. OpenSSL will pick the most appropriate one from it.
*
* #ecdh_curves= is a deprecated alias for #groups=.
*
* See also the man page SSL_CTX_set1_groups_list(3).
*
* === Example
* ctx1 = OpenSSL::SSL::SSLContext.new
* ctx1.ecdh_curves = "X25519:P-256:P-224"
* ctx1.groups = "X25519:P-256:P-224"
* svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx1)
* Thread.new { svr.accept }
*
* ctx2 = OpenSSL::SSL::SSLContext.new
* ctx2.ecdh_curves = "P-256"
* ctx2.groups = "P-256"
* cli = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx2)
* cli.connect
*
* p cli.tmp_key.group.curve_name
* # => "prime256v1" (is an alias for NIST P-256)
*/
static VALUE
ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
ossl_sslctx_set_groups(VALUE self, VALUE arg)
{
SSL_CTX *ctx;

rb_check_frozen(self);
GetSSLCTX(self, ctx);
StringValueCStr(arg);

if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
ossl_raise(eSSLError, NULL);
if (!SSL_CTX_set1_groups_list(ctx, RSTRING_PTR(arg)))
ossl_raise(eSSLError, "SSL_CTX_set1_groups_list");
return arg;
}
#else
#define ossl_sslctx_set_ecdh_curves rb_f_notimplement
#endif

/*
* call-seq:
Expand Down Expand Up @@ -2890,7 +2891,8 @@ Init_ossl_ssl(void)
#ifndef OPENSSL_NO_DH
rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
#endif
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
rb_define_method(cSSLContext, "groups=", ossl_sslctx_set_groups, 1);
rb_define_alias(cSSLContext, "ecdh_curves=", "groups=");
rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0);
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1);
#ifdef SSL_MODE_SEND_FALLBACK_SCSV
Expand Down
50 changes: 26 additions & 24 deletions test/openssl/test_ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1764,33 +1764,28 @@ def test_get_ephemeral_key
end
end

if !aws_lc? # AWS-LC does not support DHE ciphersuites.
# DHE
# TODO: SSL_CTX_set1_groups() is required for testing this with TLS 1.3
ctx_proc2 = proc { |ctx|
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.ciphers = "EDH"
ctx.tmp_dh = Fixtures.pkey("dh-1")
}
start_server(ctx_proc: ctx_proc2) do |port|
# DHE
# OpenSSL 3.0 added support for named FFDHE groups in TLS 1.3
# LibreSSL does not support named FFDHE groups currently
# AWS-LC does not support DHE ciphersuites
if openssl?(3, 0, 0)
start_server do |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.ciphers = "EDH"
ctx.groups = "ffdhe3072"
server_connect(port, ctx) { |ssl|
assert_instance_of OpenSSL::PKey::DH, ssl.tmp_key
assert_equal 3072, ssl.tmp_key.p.num_bits
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
}
end
end

# ECDHE
ctx_proc3 = proc { |ctx|
ctx.ciphers = "DEFAULT:!kRSA:!kEDH"
ctx.ecdh_curves = "P-256"
ctx.groups = "P-256"
}
start_server(ctx_proc: ctx_proc3) do |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.ciphers = "DEFAULT:!kRSA:!kEDH"
server_connect(port, ctx) { |ssl|
server_connect(port) { |ssl|
assert_instance_of OpenSSL::PKey::EC, ssl.tmp_key
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
}
Expand Down Expand Up @@ -2001,17 +1996,17 @@ def test_tmp_dh
end
end

def test_ecdh_curves_tls12
def test_set_groups_tls12
ctx_proc = -> ctx {
# Enable both ECDHE (~ TLS 1.2) cipher suites and TLS 1.3
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
ctx.ciphers = "kEECDH"
ctx.ecdh_curves = "P-384:P-521"
ctx.groups = "P-384:P-521"
}
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
# Test 1: Client=P-256:P-384, Server=P-384:P-521 --> P-384
ctx = OpenSSL::SSL::SSLContext.new
ctx.ecdh_curves = "P-256:P-384"
ctx.groups = "P-256:P-384"
server_connect(port, ctx) { |ssl|
cs = ssl.cipher[0]
assert_match (/\AECDH/), cs
Expand All @@ -2021,29 +2016,36 @@ def test_ecdh_curves_tls12

# Test 2: Client=P-256, Server=P-521:P-384 --> Fail
ctx = OpenSSL::SSL::SSLContext.new
ctx.ecdh_curves = "P-256"
ctx.groups = "P-256"
assert_raise(OpenSSL::SSL::SSLError) {
server_connect(port, ctx) { }
}

# Test 3: Client=P-521:P-384, Server=P-521:P-384 --> P-521
ctx = OpenSSL::SSL::SSLContext.new
ctx.ecdh_curves = "P-521:P-384"
ctx.groups = "P-521:P-384"
server_connect(port, ctx) { |ssl|
assert_equal "secp521r1", ssl.tmp_key.group.curve_name
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
}

# Test 4: #ecdh_curves= alias
ctx = OpenSSL::SSL::SSLContext.new
ctx.ecdh_curves = "P-256:P-384"
server_connect(port, ctx) { |ssl|
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
}
end
end

def test_ecdh_curves_tls13
def test_set_groups_tls13
ctx_proc = -> ctx {
# Assume TLS 1.3 is enabled and chosen by default
ctx.ecdh_curves = "P-384:P-521"
ctx.groups = "P-384:P-521"
}
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.ecdh_curves = "P-256:P-384" # disable P-521
ctx.groups = "P-256:P-384" # disable P-521

server_connect(port, ctx) { |ssl|
assert_equal "TLSv1.3", ssl.ssl_version
Expand Down