Skip to content

Preserve the TLS 1.3 cipher policy when a cipher setter fails - #3638

Open
justsmth wants to merge 1 commit into
aws:mainfrom
justsmth:preserve-tls13-suites-on-setter-failure
Open

justsmth wants to merge 1 commit into
aws:mainfrom
justsmth:preserve-tls13-suites-on-setter-failure

Conversation

@justsmth

@justsmth justsmth commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Context and motivation

A cipher rule that matches nothing currently wipes out the TLS 1.3 suites too. SSL_CTX_set_ciphersuites stores an empty TLS 1.3 list before reporting the failure, and the legacy *_set_cipher_list setters return before re-merging the TLS 1.3 suites into the combined list. Either way the endpoint is left unable to negotiate TLS 1.3; a client rejects the server's choice with SSL_R_WRONG_CIPHER_RETURNED.

Description of changes

A failed TLS 1.3 setter now leaves both lists untouched, and a failed legacy setter keeps the TLS 1.3 suites while still clearing the TLS 1.2 and below suites, as OpenSSL does. The setters also stop pushing a redundant SSL_R_NO_CIPHER_MATCH on top of the error already reported, so a strict parse error surfaces as SSL_R_INVALID_COMMAND (ERR_get_error() ordering is unchanged). The failure semantics are now documented on each setter in ssl.h.

Testing

New ssl_ciphers_test.cc cases check that a no-match rule leaves the TLS 1.3 policy (including order) intact and that TLS 1.3 handshakes still succeed afterwards, which fails on main. A new standalone ssl_ciphers_mem_test fails each allocation in turn to verify the setters are no-ops on failure. ssl_test and ssl_ciphers_mem_test pass in Debug and in a FIPS shared-library build.

Review considerations

Success paths are unchanged. A caller that ignores a 0 return now has working TLS 1.3 instead of no ciphers at all. SSL_CTX_set_cipher_list(ctx, "") still returns 1, an existing divergence from OpenSSL and BoringSSL that is now documented. Making the server honor an explicitly empty per-connection TLS 1.3 list is a deliberate behavior change and will come as a separate PR.

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.

SSL_CTX_set_ciphersuites and SSL_set_ciphersuites installed an empty TLS 1.3 list before reporting that a rule matched nothing, and the legacy cipher-list setters returned before merging the TLS 1.3 suites back in, so a rule that matched nothing left the combined list empty and a TLS 1.3 client rejected whatever suite the server chose. Parse the TLS 1.3 rule aside and commit it only after the combined list is rebuilt, and have the legacy setters always re-merge the TLS 1.3 suites while keeping the OpenSSL behavior of clearing the TLS 1.2 and below suites on no match.

The setters no longer push a redundant SSL_R_NO_CIPHER_MATCH over the error ssl_create_cipher_list already reports, so a strict parse error now surfaces as SSL_R_INVALID_COMMAND; ERR_get_error ordering is unchanged. Document the failure semantics in ssl.h, and add regression tests, including a standalone ssl_ciphers_mem_test that injects allocation failures to check each setter is a no-op on failure.

Testing: ssl_test (2716 passed) in Debug with ENABLE_CRYPTO_POLICIES=ON; ssl_ciphers_mem_test (15 passed) in Debug and in a FIPS shared-library build.
@justsmth
justsmth requested a review from a team as a code owner October 9, 2026 18:36

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

const bool had_local_list = ssl && ssl->config->cipher_list;

ERR_clear_error();
int ret;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'ret' is not initialized [cppcoreguidelines-init-variables]

Suggested change
int ret;
int ret = 0;


ERR_clear_error();
int ret;
size_t count, reallocations;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'count' is not initialized [cppcoreguidelines-init-variables]

Suggested change
size_t count, reallocations;
size_t count = 0, reallocations;


ERR_clear_error();
int ret;
size_t count, reallocations;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'reallocations' is not initialized [cppcoreguidelines-init-variables]

Suggested change
size_t count, reallocations;
size_t count, reallocations = 0;

ERR_clear_error();
int ret;
size_t count, reallocations;
bool failed;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'failed' is not initialized [cppcoreguidelines-init-variables]

Suggested change
bool failed;
bool failed = false;

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

🔒 Security Review — View Report

Please review before merging.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.74436% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.56%. Comparing base (b2fa449) to head (c3a94f1).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
ssl/ssl_ciphers_mem_test.cc 96.18% 3 Missing and 2 partials ⚠️
ssl/ssl_ciphers_test.cc 99.03% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3638      +/-   ##
==========================================
+ Coverage   78.46%   78.56%   +0.09%     
==========================================
  Files         705      706       +1     
  Lines      130645   130932     +287     
  Branches    17912    17948      +36     
==========================================
+ Hits       102516   102866     +350     
+ Misses      27150    27079      -71     
- Partials      979      987       +8     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants