Skip to content

Commit

Permalink
Tweak name and add one more test
Browse files Browse the repository at this point in the history
  • Loading branch information
nabla-c0d3 committed Dec 26, 2024
1 parent 311b0ba commit cfb473a
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 25 deletions.
8 changes: 5 additions & 3 deletions nassl/ssl_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,9 +466,11 @@ def set_ciphersuites(self, cipher_suites: str) -> None:
# TODO(AD): Eventually merge this method with get/set_cipher_list()
self._ssl.set_ciphersuites(cipher_suites)

def set_sigalgs(self, sigalgs: List[Tuple[OpenSslDigestNidEnum, OpenSslEvpPkeyEnum]]) -> None:
"""Set the enabled signature algorithms for the key exchange."""
flattened_sigalgs = [item for sublist in sigalgs for item in sublist]
def set_signature_algorithms(self, algorithms: List[Tuple[OpenSslDigestNidEnum, OpenSslEvpPkeyEnum]]) -> None:
"""Set the enabled signature algorithms for the key exchange.
The algorithms parameter is a list of a public key algorithm and a digest."""
flattened_sigalgs = [item for sublist in algorithms for item in sublist]
self._ssl.set1_sigalgs(flattened_sigalgs)

def get_peer_signature_nid(self) -> OpenSslDigestNidEnum:
Expand Down
82 changes: 60 additions & 22 deletions tests/ssl_client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
OpenSslVerifyEnum,
SslClient,
OpenSSLError,
OpenSslEarlyDataStatusEnum, OpenSslDigestNidEnum,
OpenSslEarlyDataStatusEnum,
OpenSslDigestNidEnum,
)
from nassl.ephemeral_key_info import (
OpenSslEvpPkeyEnum,
Expand Down Expand Up @@ -219,7 +220,6 @@ def test_get_verified_chain(self) -> None:
# And when requesting the verified certificate chain, it returns it
assert ssl_client.get_verified_chain()

assert ssl_client.get_peer_signature_nid() == OpenSslDigestNidEnum.SHA256
finally:
ssl_client.shutdown()

Expand Down Expand Up @@ -363,16 +363,20 @@ def test_set_groups_curve_x448(self) -> None:
assert len(dh_info.public_bytes) == 56

def test_get_extended_master_secret_not_used(self) -> None:
# Given a TLS server that does NOT support the Extended Master Secret extension
with LegacyOpenSslServer() as server:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect((server.hostname, server.port))

# When a client connects to it
ssl_client = SslClient(
ssl_version=OpenSslVersionEnum.TLSV1_2,
underlying_socket=sock,
ssl_verify=OpenSslVerifyEnum.NONE,
)

# Then, before the handshake, the client cannot tell if Extended Master Secret was used
exms_support_before_handshake = ssl_client.get_extended_master_secret_support()
assert exms_support_before_handshake == ExtendedMasterSecretSupportEnum.UNKNOWN

Expand All @@ -381,29 +385,83 @@ def test_get_extended_master_secret_not_used(self) -> None:
finally:
ssl_client.shutdown()

# And after the handshake, the client can tell that Extended Master Secret was NOT used
exms_support = ssl_client.get_extended_master_secret_support()
assert exms_support == ExtendedMasterSecretSupportEnum.NOT_USED_IN_CURRENT_SESSION

def test_get_extended_master_secret_used(self) -> None:
# Given a TLS server that DOES support the Extended Master Secret extension
with ModernOpenSslServer() as server:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect((server.hostname, server.port))

# When a client connects to it
ssl_client = SslClient(
ssl_version=OpenSslVersionEnum.TLSV1_2,
underlying_socket=sock,
ssl_verify=OpenSslVerifyEnum.NONE,
)

# Then, before the handshake, the client cannot tell if Extended Master Secret was used
exms_support_before_handshake = ssl_client.get_extended_master_secret_support()
assert exms_support_before_handshake == ExtendedMasterSecretSupportEnum.UNKNOWN

try:
ssl_client.do_handshake()
finally:
ssl_client.shutdown()

# And after the handshake, the client can tell that Extended Master Secret was used
exms_support = ssl_client.get_extended_master_secret_support()
assert exms_support == ExtendedMasterSecretSupportEnum.USED_IN_CURRENT_SESSION

def test_set_signature_algorithms(self) -> None:
# Given a TLS server
with ModernOpenSslServer() as server:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect((server.hostname, server.port))

# And a client
ssl_client = SslClient(
ssl_version=OpenSslVersionEnum.TLSV1_2,
underlying_socket=sock,
ssl_verify=OpenSslVerifyEnum.NONE,
)
# That's configured to use a specific signature algorithm
ssl_client.set_signature_algorithms([(OpenSslDigestNidEnum.SHA256, OpenSslEvpPkeyEnum.RSA)])

# When the client connects to the server, it succeeds
try:
ssl_client.do_handshake()
finally:
ssl_client.shutdown()

# And the configured signature algorithm was used
assert ssl_client.get_peer_signature_nid() == OpenSslDigestNidEnum.SHA256

def test_set_signature_algorithms_but_not_supported(self) -> None:
# Given a TLS server
with ModernOpenSslServer() as server:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect((server.hostname, server.port))

# And a client
ssl_client = SslClient(
ssl_version=OpenSslVersionEnum.TLSV1_3,
underlying_socket=sock,
ssl_verify=OpenSslVerifyEnum.NONE,
)
# That's configured to use signature algorithms that are NOT supported
ssl_client.set_signature_algorithms([(OpenSslDigestNidEnum.SHA512, OpenSslEvpPkeyEnum.EC)])

# Then, when the client connects to the server, the handshake fails
with pytest.raises(OpenSSLError, match="handshake failure"):
ssl_client.do_handshake()
ssl_client.shutdown()


class TestLegacySslClientOnline:
def test_ssl_2(self) -> None:
Expand Down Expand Up @@ -469,26 +527,6 @@ def test_set_ciphersuites(self) -> None:
# And client's cipher suite was used
assert "TLS_CHACHA20_POLY1305_SHA256" == ssl_client.get_current_cipher_name()

def test_set_sigalgs(self):
with ModernOpenSslServer() as server:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect((server.hostname, server.port))

ssl_client = SslClient(
ssl_version=OpenSslVersionEnum.TLSV1_3,
underlying_socket=sock,
ssl_verify=OpenSslVerifyEnum.NONE,
)
# These signature algorithms are unsupported
ssl_client.set_sigalgs([
(OpenSslDigestNidEnum.SHA512, OpenSslEvpPkeyEnum.EC)
])

with pytest.raises(OpenSSLError):
ssl_client.do_handshake()
ssl_client.shutdown()

@staticmethod
def _create_tls_1_3_session(server_host: str, server_port: int) -> _nassl.SSL_SESSION:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Expand Down

0 comments on commit cfb473a

Please sign in to comment.