diff options
author | David Benjamin <davidben@google.com> | 2023-05-26 21:23:39 -0400 |
---|---|---|
committer | Boringssl LUCI CQ <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-05-31 15:13:19 +0000 |
commit | 2da5ba91205f9f3cbb423064e11c165580307f82 (patch) | |
tree | a190e2e61bfe23ee252dad6eaff909420f4c4b0a /ssl/ssl_lib.cc | |
parent | 4631ccc1bf95d296340e6d1e20a55890e55466a5 (diff) | |
download | boringssl-2da5ba91205f9f3cbb423064e11c165580307f82.zip boringssl-2da5ba91205f9f3cbb423064e11c165580307f82.tar.gz boringssl-2da5ba91205f9f3cbb423064e11c165580307f82.tar.bz2 |
Align on using the "group" over "curve" for ECDH in TLS
We're this awkward mix of "group" and "curve" right now. On the spec
side, this is because they used to be "curves", but then RFC 7919
renamed to "group" in an attempt to generalize FFDH and ECDH. The
negotiated FFDH stuff never really went anywhere (the way it used cipher
suite values in TLS 1.2 made it unusable), but the name change stuck.
In our implementation and API, we originally called it "curve". In
preparation for TLS 1.3, we renamed the internals to "group" to match
the spec in
https://boringssl-review.googlesource.com/c/boringssl/+/7955, but the
public API was still "curve".
Then we exported a few more things in
https://boringssl-review.googlesource.com/c/boringssl/+/8565, but I left
it at "curve" to keep the public API self-consistent.
Then we added OpenSSL's new "group" APIs in
https://boringssl-review.googlesource.com/c/boringssl/+/54306, but
didn't go as far to deprecate the old ones yet.
Now I'd like to add new APIs to clear up the weird mix of TLS codepoints
and NIDs that appear in our APIs. But our naming is a mess, so either
choice of "group" or "curve" for the new API looks weird.
In hindsight, we probably should have left it at "curve". Both terms are
equally useless for the future post-quantum KEMs, but at least "curve"
is more unique of a name than "group". But at this point, I think we're
too far through the "group" rename to really backtrack:
- Chromium says "group" in its internals
- QUICHE says "group" in its internals and public API
- Our internals say "group"
- OpenSSL has switched to "group" and deprecated "curve", so new APIs
will be based on "group"
So align with all this and say "group". This CL handles set1_curves and
set1_curves_list APIs, which already have "group" replacements from
OpenSSL. A follow-up CL will handle our APIs. This is a soft deprecation
because I don't think updating things is particularly worth the churn,
but get the old names out of the way, so new code can have a simpler API
to target.
Also rewrite the documentation for that section accordingly. I don't
think we need to talk about how it's always enabled now. That's a
reference to some very, very old OpenSSL behavior where ECDH negotiation
needed to be separately enabled.
Change-Id: I7a356793d36419fc668364c912ca7b4f5c6c23a2
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60206
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Diffstat (limited to 'ssl/ssl_lib.cc')
-rw-r--r-- | ssl/ssl_lib.cc | 93 |
1 files changed, 65 insertions, 28 deletions
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc index 838761a..066fe69 100644 --- a/ssl/ssl_lib.cc +++ b/ssl/ssl_lib.cc @@ -1939,44 +1939,81 @@ int SSL_CTX_set_tlsext_ticket_key_cb( return 1; } -int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, size_t curves_len) { - return tls1_set_curves(&ctx->supported_group_list, - MakeConstSpan(curves, curves_len)); -} +static bool ssl_nids_to_group_ids(Array<uint16_t> *out_group_ids, + Span<const int> nids) { + Array<uint16_t> group_ids; + if (!group_ids.Init(nids.size())) { + return false; + } -int SSL_set1_curves(SSL *ssl, const int *curves, size_t curves_len) { - if (!ssl->config) { - return 0; + for (size_t i = 0; i < nids.size(); i++) { + if (!ssl_nid_to_group_id(&group_ids[i], nids[i])) { + return false; + } } - return tls1_set_curves(&ssl->config->supported_group_list, - MakeConstSpan(curves, curves_len)); + + *out_group_ids = std::move(group_ids); + return true; } -int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves) { - return tls1_set_curves_list(&ctx->supported_group_list, curves); +int SSL_CTX_set1_groups(SSL_CTX *ctx, const int *groups, size_t num_groups) { + return ssl_nids_to_group_ids(&ctx->supported_group_list, + MakeConstSpan(groups, num_groups)); } -int SSL_set1_curves_list(SSL *ssl, const char *curves) { +int SSL_set1_groups(SSL *ssl, const int *groups, size_t num_groups) { if (!ssl->config) { return 0; } - return tls1_set_curves_list(&ssl->config->supported_group_list, curves); + return ssl_nids_to_group_ids(&ssl->config->supported_group_list, + MakeConstSpan(groups, num_groups)); } -int SSL_CTX_set1_groups(SSL_CTX *ctx, const int *groups, size_t groups_len) { - return SSL_CTX_set1_curves(ctx, groups, groups_len); -} +static bool ssl_str_to_group_ids(Array<uint16_t> *out_group_ids, + const char *str) { + // Count the number of groups in the list. + size_t count = 0; + const char *ptr = str, *col; + do { + col = strchr(ptr, ':'); + count++; + if (col) { + ptr = col + 1; + } + } while (col); -int SSL_set1_groups(SSL *ssl, const int *groups, size_t groups_len) { - return SSL_set1_curves(ssl, groups, groups_len); + Array<uint16_t> group_ids; + if (!group_ids.Init(count)) { + return false; + } + + size_t i = 0; + ptr = str; + do { + col = strchr(ptr, ':'); + if (!ssl_name_to_group_id(&group_ids[i++], ptr, + col ? (size_t)(col - ptr) : strlen(ptr))) { + return false; + } + if (col) { + ptr = col + 1; + } + } while (col); + + assert(i == count); + *out_group_ids = std::move(group_ids); + return true; } int SSL_CTX_set1_groups_list(SSL_CTX *ctx, const char *groups) { - return SSL_CTX_set1_curves_list(ctx, groups); + return ssl_str_to_group_ids(&ctx->supported_group_list, groups); } int SSL_set1_groups_list(SSL *ssl, const char *groups) { - return SSL_set1_curves_list(ssl, groups); + if (!ssl->config) { + return 0; + } + return ssl_str_to_group_ids(&ssl->config->supported_group_list, groups); } uint16_t SSL_get_curve_id(const SSL *ssl) { @@ -3040,7 +3077,7 @@ int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key) { return 0; } int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); - return SSL_CTX_set1_curves(ctx, &nid, 1); + return SSL_CTX_set1_groups(ctx, &nid, 1); } int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) { @@ -3049,7 +3086,7 @@ int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) { return 0; } int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); - return SSL_set1_curves(ssl, &nid, 1); + return SSL_set1_groups(ssl, &nid, 1); } void SSL_CTX_set_ticket_aead_method(SSL_CTX *ctx, @@ -3151,7 +3188,7 @@ namespace fips202205 { // Section 3.3.1 // "The server shall be configured to only use cipher suites that are // composed entirely of NIST approved algorithms" -static const int kCurves[] = {NID_X9_62_prime256v1, NID_secp384r1}; +static const int kGroups[] = {NID_X9_62_prime256v1, NID_secp384r1}; static const uint16_t kSigAlgs[] = { SSL_SIGN_RSA_PKCS1_SHA256, @@ -3188,7 +3225,7 @@ static int Configure(SSL_CTX *ctx) { // Encrypt-then-MAC extension is required for all CBC cipher suites and so // it's easier to drop them. SSL_CTX_set_strict_cipher_list(ctx, kTLS12Ciphers) && - SSL_CTX_set1_curves(ctx, kCurves, OPENSSL_ARRAY_SIZE(kCurves)) && + SSL_CTX_set1_groups(ctx, kGroups, OPENSSL_ARRAY_SIZE(kGroups)) && SSL_CTX_set_signing_algorithm_prefs(ctx, kSigAlgs, OPENSSL_ARRAY_SIZE(kSigAlgs)) && SSL_CTX_set_verify_algorithm_prefs(ctx, kSigAlgs, @@ -3202,7 +3239,7 @@ static int Configure(SSL *ssl) { return SSL_set_min_proto_version(ssl, TLS1_2_VERSION) && SSL_set_max_proto_version(ssl, TLS1_3_VERSION) && SSL_set_strict_cipher_list(ssl, kTLS12Ciphers) && - SSL_set1_curves(ssl, kCurves, OPENSSL_ARRAY_SIZE(kCurves)) && + SSL_set1_groups(ssl, kGroups, OPENSSL_ARRAY_SIZE(kGroups)) && SSL_set_signing_algorithm_prefs(ssl, kSigAlgs, OPENSSL_ARRAY_SIZE(kSigAlgs)) && SSL_set_verify_algorithm_prefs(ssl, kSigAlgs, @@ -3215,7 +3252,7 @@ namespace wpa202304 { // See WPA version 3.1, section 3.5. -static const int kCurves[] = {NID_secp384r1}; +static const int kGroups[] = {NID_secp384r1}; static const uint16_t kSigAlgs[] = { SSL_SIGN_RSA_PKCS1_SHA384, // @@ -3235,7 +3272,7 @@ static int Configure(SSL_CTX *ctx) { return SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION) && SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION) && SSL_CTX_set_strict_cipher_list(ctx, kTLS12Ciphers) && - SSL_CTX_set1_curves(ctx, kCurves, OPENSSL_ARRAY_SIZE(kCurves)) && + SSL_CTX_set1_groups(ctx, kGroups, OPENSSL_ARRAY_SIZE(kGroups)) && SSL_CTX_set_signing_algorithm_prefs(ctx, kSigAlgs, OPENSSL_ARRAY_SIZE(kSigAlgs)) && SSL_CTX_set_verify_algorithm_prefs(ctx, kSigAlgs, @@ -3248,7 +3285,7 @@ static int Configure(SSL *ssl) { return SSL_set_min_proto_version(ssl, TLS1_2_VERSION) && SSL_set_max_proto_version(ssl, TLS1_3_VERSION) && SSL_set_strict_cipher_list(ssl, kTLS12Ciphers) && - SSL_set1_curves(ssl, kCurves, OPENSSL_ARRAY_SIZE(kCurves)) && + SSL_set1_groups(ssl, kGroups, OPENSSL_ARRAY_SIZE(kGroups)) && SSL_set_signing_algorithm_prefs(ssl, kSigAlgs, OPENSSL_ARRAY_SIZE(kSigAlgs)) && SSL_set_verify_algorithm_prefs(ssl, kSigAlgs, |