diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9f58d7897..6a8a4a0c4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -24,7 +24,9 @@ Deprecations: Changes: ^^^^^^^^ - +- Added the ``OpenSSL.SSL.Context.set_ciphersuites`` method to + allow setting the TLS 1.3 ciphersuites. + `#963 `_ - Added a new optional ``chain`` parameter to ``OpenSSL.crypto.X509StoreContext()`` where additional untrusted certificates can be specified to help chain building. `#948 `_ diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py index 315342626..dcadf970a 100644 --- a/src/OpenSSL/SSL.py +++ b/src/OpenSSL/SSL.py @@ -1129,6 +1129,25 @@ def set_cipher_list(self, cipher_list): ], ) + def set_ciphersuites(self, ciphersuites): + """ + Set the list of TLS 1.3 ciphersuites to be used in this context. + + See the OpenSSL manual for more information (e.g. + :manpage:`ciphers(1)`). + + :param bytes ciphersuites: An OpenSSL ciphersuites string. + :return: None + """ + ciphersuites = _text_to_bytes_and_warn("ciphersuites", ciphersuites) + + if not isinstance(ciphersuites, bytes): + raise TypeError("ciphersuites must be a byte string.") + + _openssl_assert( + _lib.SSL_CTX_set_ciphersuites(self._context, ciphersuites) == 1 + ) + def set_client_ca_list(self, certificate_authorities): """ Set the list of preferred client certificate signers for this server diff --git a/tests/test_ssl.py b/tests/test_ssl.py index aed236703..5d5623331 100644 --- a/tests/test_ssl.py +++ b/tests/test_ssl.py @@ -521,6 +521,29 @@ def test_set_cipher_list_no_cipher_match(self, context): ], ) + @pytest.mark.parametrize( + "ciphersuites", + [b"TLS_AES_256_GCM_SHA384", u"TLS_AES_256_GCM_SHA384"], + ) + def test_set_ciphersuites(self, context, ciphersuites): + """ + `Context.set_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_ciphersuites(ciphersuites) + conn = Connection(context, None) + + assert "TLS_AES_256_GCM_SHA384" in conn.get_cipher_list() + + def test_set_ciphersuites_wrong_type(self, context): + """ + `Context.set_ciphersuites` raises `TypeError` when passed a non-string + argument. + """ + with pytest.raises(TypeError): + context.set_ciphersuites(object()) + def test_load_client_ca(self, context, ca_file): """ `Context.load_client_ca` works as far as we can tell.