-
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?
Changes from 17 commits
bc7b951
e80cb6e
c49f32d
bfb369f
ef0f455
aacb978
b6f297b
749513a
1e818d5
425e9a5
656b710
2622e1e
fe430f4
72603cc
eb28574
5fcdd4a
d4e5047
6707995
ff11f99
849bf37
3f467ff
dbbd45c
94d2189
7669f46
fc0c20c
9ee29c8
e38bfa3
dbd660a
272ef8f
0991f2f
0d7b302
2c809d3
7798ef6
8442723
ae84e27
0e66ad6
a755968
2c6d018
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1234,7 +1234,88 @@ static bool is_known_default_alias_keyword_filter_rule(const char *rule, | |
return false; | ||
} | ||
|
||
bool ssl_create_cipher_list(UniquePtr<SSLCipherPreferenceList> *out_cipher_list, | ||
// update_cipher_list updates |ctx->cipher_list| by: | ||
smittals2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// 1. Removing any existing TLS 1.3 ciphersuites | ||
// 2. Adding configured ciphersuites from |ctx->tls13_cipher_list| | ||
// 3. Configuring a new |ctx->cipher_list->in_group_flags| | ||
// This function maintains the ordering of ciphersuites and places TLS 1.3 | ||
// ciphersuites at the front of the list. | ||
smittals2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Returns one on success and zero on failure. | ||
static int update_cipher_list(SSL_CTX *ctx) { | ||
bssl::UniquePtr<STACK_OF(SSL_CIPHER)> tmp_cipher_list; | ||
int num_removed_tls13_ciphers = 0, num_added_tls13_ciphers = 0; | ||
Array<bool> updated_in_group_flags; | ||
|
||
if (ctx->cipher_list && ctx->cipher_list->ciphers) { | ||
tmp_cipher_list.reset(sk_SSL_CIPHER_dup(ctx->cipher_list->ciphers.get())); | ||
} else { | ||
tmp_cipher_list.reset(sk_SSL_CIPHER_new_null()); | ||
} | ||
|
||
if (tmp_cipher_list == NULL) { | ||
smittals2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return 0; | ||
} | ||
|
||
// Delete any existing TLSv1.3 ciphersuites. These will be first in the list | ||
smittals2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
while (sk_SSL_CIPHER_num(tmp_cipher_list.get()) > 0 && | ||
SSL_CIPHER_get_min_version(sk_SSL_CIPHER_value(tmp_cipher_list.get(), 0)) | ||
== TLS1_3_VERSION) { | ||
sk_SSL_CIPHER_delete(tmp_cipher_list.get(), 0); | ||
num_removed_tls13_ciphers++; | ||
} | ||
|
||
int num_updated_tls12_ciphers = sk_SSL_CIPHER_num(tmp_cipher_list.get()); | ||
|
||
// Insert the new TLSv1.3 ciphersuites while maintaining original order | ||
if (ctx->tls13_cipher_list != NULL && ctx->tls13_cipher_list->ciphers != NULL) { | ||
STACK_OF(SSL_CIPHER) *tls13_cipher_stack = ctx->tls13_cipher_list->ciphers.get(); | ||
num_added_tls13_ciphers = sk_SSL_CIPHER_num(tls13_cipher_stack); | ||
for (int i = sk_SSL_CIPHER_num(tls13_cipher_stack) - 1; i >= 0; i--) { | ||
const SSL_CIPHER *tls13_cipher = sk_SSL_CIPHER_value(tls13_cipher_stack, i); | ||
if (!sk_SSL_CIPHER_unshift(tmp_cipher_list.get(), tls13_cipher)) { | ||
return 0; | ||
} | ||
} | ||
} | ||
|
||
if (!updated_in_group_flags.Init(num_added_tls13_ciphers + num_updated_tls12_ciphers)) { | ||
return 0; | ||
} | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. What does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
if (ctx->tls13_cipher_list && ctx->tls13_cipher_list->in_group_flags) { | ||
const auto& tls13_flags = ctx->tls13_cipher_list->in_group_flags; | ||
// 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; | ||
} | ||
Comment on lines
+1287
to
+1291
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. No, you can only group ciphersuites within the same TLS version |
||
for (int i = 0; i < num_added_tls13_ciphers; i++) { | ||
updated_in_group_flags[i] = tls13_flags[i]; | ||
} | ||
} | ||
|
||
// Copy remaining in_group_flags from |ctx->cipher_list| | ||
if (ctx->cipher_list && ctx->cipher_list->in_group_flags) { | ||
for (int i = 0; i < num_updated_tls12_ciphers; i++) { | ||
updated_in_group_flags[i + num_added_tls13_ciphers] = | ||
ctx->cipher_list->in_group_flags[i + num_removed_tls13_ciphers]; | ||
} | ||
} | ||
|
||
Span<const bool> flags_span(updated_in_group_flags.data(), updated_in_group_flags.size()); | ||
ctx->cipher_list = MakeUnique<SSLCipherPreferenceList>(); | ||
if (ctx->cipher_list == NULL) { | ||
return 0; | ||
} | ||
ctx->cipher_list->Init(std::move(tmp_cipher_list), flags_span); | ||
|
||
return 1; | ||
} | ||
|
||
bool ssl_create_cipher_list(SSL_CTX *ctx, | ||
UniquePtr<SSLCipherPreferenceList> *out_cipher_list, | ||
const bool has_aes_hw, const char *rule_str, | ||
bool strict, bool config_tls13) { | ||
// Return with error if nothing to do. | ||
|
@@ -1367,6 +1448,9 @@ bool ssl_create_cipher_list(UniquePtr<SSLCipherPreferenceList> *out_cipher_list, | |
return false; | ||
} | ||
|
||
// Update |ctx->cipher_list| with any ciphers in |ctx->tls13_cipher_list| | ||
update_cipher_list(ctx); | ||
smittals2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return true; | ||
} | ||
|
||
|
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.