Skip to content

Add ability to TLS 1.3 cipher suites on SSL Context #1432

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

Merged
merged 1 commit into from
Jul 29, 2025
Merged
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
13 changes: 13 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ Changelog

Versions are year-based with a strict backward-compatibility policy.
The third digit is only for regressions.
UNRELEASED
----------

Backward-incompatible changes:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Deprecations:
^^^^^^^^^^^^^

Changes:
^^^^^^^^

- Added ``OpenSSL.SSL.Context.set_tls13_ciphersuites`` that allows the allowed TLS 1.3 ciphers.

25.1.0 (2025-05-17)
-------------------
Expand Down
26 changes: 26 additions & 0 deletions src/OpenSSL/SSL.py
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,9 @@ def set_cipher_list(self, cipher_list: bytes) -> None:
See the OpenSSL manual for more information (e.g.
:manpage:`ciphers(1)`).

Note this API does not change the cipher suites used in TLS 1.3
Use `set_tls13_ciphersuites` for that.

:param bytes cipher_list: An OpenSSL cipher string.
:return: None
"""
Expand Down Expand Up @@ -1501,6 +1504,29 @@ def set_cipher_list(self, cipher_list: bytes) -> None:
],
)

@_require_not_used
def set_tls13_ciphersuites(self, ciphersuites: bytes) -> None:
"""
Set the list of TLS 1.3 ciphers to be used in this context.
OpenSSL maintains a separate list of TLS 1.3+ ciphers to
ciphers for TLS 1.2 and lowers.

See the OpenSSL manual for more information (e.g.
:manpage:`ciphers(1)`).

:param bytes ciphersuites: An OpenSSL cipher string containing
TLS 1.3+ ciphersuites.
:return: None

.. versionadded:: 25.2.0
"""
if not isinstance(ciphersuites, bytes):
raise TypeError("ciphersuites must be a byte string.")

_openssl_assert(
_lib.SSL_CTX_set_ciphersuites(self._context, ciphersuites) == 1
)

@_require_not_used
def set_client_ca_list(
self, certificate_authorities: Sequence[X509Name]
Expand Down
14 changes: 14 additions & 0 deletions tests/test_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,20 @@ def test_set_cipher_list(

assert "AES128-SHA" in conn.get_cipher_list()

def test_set_tls13_ciphersuites(self, context: Context) -> None:
"""
`Context.set_tls13_ciphersuites` accepts both byte and unicode strings
for naming the ciphers which connections created with the context
object will be able to choose from.
"""
context.set_tls13_ciphersuites(b"TLS_AES_128_GCM_SHA256")
conn = Connection(context, None)

# OpenSSL has different APIs for *setting* TLS <=1.2 and >= 1.3
# but only one API for retrieving them
assert "TLS_AES_128_GCM_SHA256" in conn.get_cipher_list()
assert "TLS_AES_256_GCM_SHA384" not in conn.get_cipher_list()

def test_set_cipher_list_wrong_type(self, context: Context) -> None:
"""
`Context.set_cipher_list` raises `TypeError` when passed a non-string
Expand Down