import ctypes
import pytest
import soyokaze
from soyokaze import ECHConfigList, ECHKeys, Identity, TLSConfig
def test_ech_keys_publish_a_parsable_config_list():
keys = ECHKeys.generate("public.example", config_id=7)
assert len(keys.private_key) == 32, "an X25519 private key is 32 octets"
published = keys.config_list()
parsed = ECHConfigList.parse(published)
assert len(parsed.configs) == 1
assert parsed.configs[0].public_name == "public.example"
assert parsed.configs[0].version == 0xFE0D
assert parsed.configs[0].maximum_name_length == 64
def test_ech_keys_rebuild_from_their_parts():
keys = ECHKeys.generate("public.example")
rebuilt = ECHKeys(keys.config, keys.private_key)
assert rebuilt.config_list() == keys.config_list()
def test_a_config_list_that_will_not_parse_is_refused():
with pytest.raises(soyokaze.TLSError):
ECHConfigList.parse(b"\x00")
with pytest.raises(soyokaze.TLSError):
ECHConfigList.parse(b"\x00\x04\x00\x00\x00\x00"), "an unsupported version alone is no list"
def test_an_identity_holds_its_blobs_without_parsing_them():
Identity([b"not a certificate"], b"not a key"), "malformed blobs surface when a server is built"
def test_a_pkcs12_archive_that_will_not_parse_is_refused():
with pytest.raises(soyokaze.TLSError):
Identity.from_pkcs12(b"not an archive", "")
def test_a_tls_config_defaults_to_changing_nothing():
struct = TLSConfig().build()
assert not struct.ciphers.data, "an absent list keeps the profile's ciphers"
assert not struct.groups.data
assert not struct.signature_algorithms.data
assert not struct.prefer_server_ciphers
assert struct.session_tickets, "tickets are on unless turned off"
assert not struct.early_data
assert not struct.certificate_compression
def test_a_tls_config_carries_its_lists_and_flags():
config = TLSConfig(ciphers="ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305", groups="X25519:P-256", signature_algorithms="ecdsa_secp384r1_sha384", prefer_server_ciphers=True, session_tickets=False, early_data=True, certificate_compression=True)
struct = config.build()
assert ctypes.string_at(struct.groups.data, struct.groups.len) == b"X25519:P-256"
assert ctypes.string_at(struct.signature_algorithms.data, struct.signature_algorithms.len) == b"ecdsa_secp384r1_sha384"
assert struct.prefer_server_ciphers
assert not struct.session_tickets
assert struct.early_data
assert struct.certificate_compression
def test_a_client_and_a_server_take_a_tls_config():
from soyokaze import Client, ClientConfig, Server, ServerConfig
client = Client(ClientConfig(tls=TLSConfig(groups="X25519")))
assert client.handle, "a client must accept TLS details the way it accepts roots"
server = Server(ServerConfig(tls=TLSConfig(session_tickets=False, certificate_compression=True)))
assert server.handle, "a server must accept TLS details the way it accepts an identity"