-
Notifications
You must be signed in to change notification settings - Fork 122
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
Refactor TLS 1.3 cipher selection and fix SSL_get_ciphers #2092
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2092 +/- ##
==========================================
+ Coverage 78.95% 78.98% +0.03%
==========================================
Files 610 610
Lines 105293 105381 +88
Branches 14911 14937 +26
==========================================
+ Hits 83129 83231 +102
+ Misses 21511 21499 -12
+ Partials 653 651 -2 ☔ View full report in Codecov by Sentry. |
// Note: TLS 1.3 ciphersuites are only configurable via | ||
// |SSL_CTX_set_ciphersuites| or |SSL_set_ciphersuites|. Other setter functions have | ||
// no impact on TLS 1.3 ciphersuites. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have tests that attempt to set 1.3 ciphers and ensure they are rejected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean use the TLS 1.2 setter functions to set TLS 1.3 ciphers? If so yes you get a no cipher match error.
|
||
if (!collect_cipher_protocol_ids(ciphers, &child, mask_k, | ||
mask_a, hs->max_version, hs->min_version, &any_enabled)) { | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you filtering the TLS 1.3 ciphers again here? From line 276 we already know we want 1.3 ciphers and tls13_cipher_list only has 1.3 ciphers in it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually can these two blocks be combined into a single flow:
- Call SSL_get_ciphers to get all 1.2 and 1.3 ciphers
- Filter that based on min/max
- Write that to the CBB
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cannot combine the two blocks. Different cases for ECH (discussed offline)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree you can't combine the two blocks into one shared block, but I'm still curious about the filtering, can this just use ciphers
from up above which only includes 1.3 ciphers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you saying use the same SSL_get_ciphers call below as well?
The reason we can't do this is if you are a ECH ClientHelloInner, and you support TLS versions less than 1.3, by RFC we still only send TLS 1.3 ciphersuites. Since collect_ciphers takes min max version from the handshake, using the above ciphers var would erroneously pull in TLS 1.2 and below ciphersuites. Therefore, we specifically pass in only the tls13_ciphersuites in the else block
if (!collect_cipher_protocol_ids(SSL_get_ciphers(ssl), &child, mask_k, | ||
mask_a, hs->max_version, hs->min_version, &any_enabled)) { | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Double checking my understanding: this is in an if/else block so only hs->min_version < TLS1_3_VERSION
or hs->max_version >= TLS1_3_VERSION
will run. If min is less than 1.3 we want to add both, and SSL_get_ciphers
returns both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes if min is less than 1.3, we want to add min to max (where max could also be anything). We pass this in to collect_cipher_protocol_ids.
SSL_get_ciphers will return the SSL level (if configured) and otherwise SSL_CTX main cipher list which now holds all ciphersuites.
@@ -1690,10 +1690,9 @@ OPENSSL_EXPORT size_t SSL_get_all_standard_cipher_names(const char **out, | |||
// Once an equal-preference group is used, future directives must be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update SSL_get_ciphers documentation to note it returns all ciphers 1.2 and 1.3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current documentation covers this case ("cipher list for |ssl|") but I'll make it more explicit. We just weren't living up to this contract initially.
} | ||
std::fill(updated_in_group_flags.begin(), updated_in_group_flags.end(), false); | ||
|
||
// Copy in_group_flags from |ctx->tls13_cipher_list| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does in_group_flags
do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Ensure value of last element in |in_group_flags| is 0. The last cipher | ||
// in a list must be the end of any group in that list. | ||
if (tls13_flags[num_added_tls13_ciphers - 1] != 0) { | ||
tls13_flags[num_added_tls13_ciphers - 1] = false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this fail here instead? If this happens does that mean something happened up above and the wrong number of things got added?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can a group include a 1.3 and 1.2 cipher suite?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, you can only group ciphersuites within the same TLS version
if (!ssl_create_cipher_list(&ctx->cipher_list, has_aes_hw, str, | ||
false /* not strict */, | ||
false /* don't configure TLSv1.3 ciphers */); | ||
false /* don't configure TLSv1.3 ciphers */)) { | ||
return 0; | ||
} | ||
|
||
return update_cipher_list(ctx->cipher_list, ctx->cipher_list, ctx->tls13_cipher_list); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we just pass the 1.3 ciphers to ssl_create_cipher_list
and have it put them at the beginning automatically?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same ssl_create_cipher_list function is used to create tls13_cipher_lists and the main cipher_list. Therefore, I have chosen to do update's separately to properly distinguish what is being set.
Issues:
CryptoAlg-2559
Description of changes:
SSL_CTX_new
now configuresctx->tls13_cipher_suites
with default TLS 1.3 ciphers (did not previously). The default preference order for TLS 1.3 ciphersuites differs based on whether AES Hardware acceleration is enabled in AWS-LC, we match this behavior in SSL_CTX_new.SSL_CONFIG
object holds it's own TLS 1.3 ciphersuites nowSSL_CONFIG
SSL_CTX
orSSL_CONFIG
, the maincipher_list
is updated with values from its owntls13_cipher_suites
via a new functionupdate_cipher_list
. This function also updatesin_group_flags
accordingly. This means, TLS 1.3 ciphersuites are stored seperately while the maincipher_list
var holds ALL ciphersuites in both objectsCall-outs:
Note
SSL_CTX
generally has a longer lifetime than anSSL
object.SSL_CONFIG
objects live onSSL
objects. BothSSL_CTX
andSSL_CONFIG
have their owncipher_list
andtls13_cipher_list
fields. We supportSSL_[CTX]_set_...
APIs to set these fields.In general, our TLS implementations pick cipher suites against the given connection constraints/parameters. Adding TLS 1.3 ciphersuites to
ctx->cipher_list
orconfig->cipher_list
does not modify this behavior or introduce new problems.Testing:
Added new testing to validate cipher selection behavior between SSL_CTX and SSL_CONFIG objects
Added change detection test for TLS 1.3 Client Hello
Updated old tests and to-do's regarding TLS 1.3
Testing to ensure
SSL_get_ciphers
returns ALL ciphersuites instead of TLS 1.2 and below.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.