Skip to content

Commit c6852a0

Browse files
committed
tls: Add DTLS handshake test
Closes #51
1 parent af7b8ec commit c6852a0

File tree

1 file changed

+138
-2
lines changed

1 file changed

+138
-2
lines changed

tests/test_tls.py

Lines changed: 138 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ def test_wrap_buffers(self, context):
475475
assert isinstance(context.wrap_buffers(), TLSWrappedBuffer)
476476

477477

478-
class TestTLSWrappedBuffer:
478+
class TestTLSHandshake:
479479
@pytest.fixture
480480
def server_hostname(self):
481481
return "hostname"
@@ -497,7 +497,7 @@ def srv_conf(self, psk):
497497
)
498498

499499
@pytest.fixture
500-
def client(Self, cli_conf, server_hostname):
500+
def client(self, cli_conf, server_hostname):
501501
buf = ClientContext(cli_conf).wrap_buffers(server_hostname)
502502
yield buf
503503
buf.shutdown()
@@ -587,3 +587,139 @@ def do_handshake(end, states):
587587
amt = server.write(secret)
588588
do_io(src=server, dst=client)
589589
assert client.read(amt) == secret
590+
591+
592+
class TestDTLSHandshake:
593+
@pytest.fixture
594+
def server_hostname(self):
595+
return "hostname"
596+
597+
@pytest.fixture
598+
def psk(self):
599+
return ("cli", b"secret")
600+
601+
@pytest.fixture
602+
def cli_conf(self, psk):
603+
return DTLSConfiguration(
604+
pre_shared_key=psk, validate_certificates=False
605+
)
606+
607+
@pytest.fixture
608+
def srv_conf(self, psk):
609+
return DTLSConfiguration(
610+
pre_shared_key_store=dict((psk,)), validate_certificates=False
611+
)
612+
613+
@pytest.fixture
614+
def client(self, cli_conf, server_hostname):
615+
buf = ClientContext(cli_conf).wrap_buffers(server_hostname)
616+
yield buf
617+
buf.shutdown()
618+
619+
@pytest.fixture
620+
def server(sefl, srv_conf):
621+
buf = ServerContext(srv_conf).wrap_buffers()
622+
yield buf
623+
buf.shutdown()
624+
625+
@pytest.fixture
626+
def cli_ctx(Self, cli_conf):
627+
return ClientContext(cli_conf)
628+
629+
@pytest.fixture
630+
def srv_ctx(self, srv_conf):
631+
return ServerContext(srv_conf)
632+
633+
def test_e2e_handshake_and_communicate(self, client, server):
634+
def do_io(*, src, dst, amt=1024):
635+
in_transit = src.peek_outgoing(amt)
636+
src.consume_outgoing(len(in_transit))
637+
dst.receive_from_network(in_transit)
638+
639+
def do_handshake(end, states):
640+
while end._handshake_state is not states[0]:
641+
# The backend goes through every state for both
642+
# ends. This is not relevant.
643+
end.do_handshake()
644+
645+
for state in states:
646+
assert end._handshake_state is state
647+
if state is HandshakeStep.HANDSHAKE_OVER:
648+
break
649+
with suppress(WantReadError, WantWriteError):
650+
end.do_handshake()
651+
652+
do_handshake(
653+
client,
654+
(
655+
HandshakeStep.HELLO_REQUEST,
656+
HandshakeStep.CLIENT_HELLO,
657+
),
658+
)
659+
660+
do_io(src=client, dst=server)
661+
server.setcookieparam("🍪🍪🍪".encode("utf-8"))
662+
with pytest.raises(HelloVerifyRequest):
663+
do_handshake(
664+
server,
665+
(
666+
HandshakeStep.SERVER_HELLO,
667+
HandshakeStep.SERVER_HELLO_VERIFY_REQUEST_SENT,
668+
),
669+
)
670+
671+
do_handshake(server, (HandshakeStep.HELLO_REQUEST,))
672+
do_io(src=server, dst=client)
673+
do_handshake(client, (HandshakeStep.CLIENT_HELLO,))
674+
do_io(src=client, dst=server)
675+
server.setcookieparam("🍪🍪🍪".encode("utf-8"))
676+
do_handshake(
677+
server,
678+
(
679+
HandshakeStep.SERVER_HELLO,
680+
HandshakeStep.SERVER_CERTIFICATE,
681+
HandshakeStep.SERVER_KEY_EXCHANGE,
682+
HandshakeStep.CERTIFICATE_REQUEST,
683+
HandshakeStep.SERVER_HELLO_DONE,
684+
),
685+
)
686+
assert client.negotiated_protocol() == server.negotiated_protocol()
687+
688+
do_io(src=server, dst=client)
689+
do_handshake(
690+
client,
691+
(
692+
HandshakeStep.CLIENT_KEY_EXCHANGE,
693+
HandshakeStep.CERTIFICATE_VERIFY,
694+
HandshakeStep.CLIENT_CHANGE_CIPHER_SPEC,
695+
HandshakeStep.CLIENT_FINISHED,
696+
),
697+
)
698+
assert (
699+
client.negotiated_tls_version() == server.negotiated_tls_version()
700+
)
701+
702+
do_io(src=client, dst=server)
703+
do_handshake(
704+
server,
705+
(
706+
HandshakeStep.SERVER_CHANGE_CIPHER_SPEC,
707+
HandshakeStep.SERVER_FINISHED,
708+
HandshakeStep.FLUSH_BUFFERS,
709+
HandshakeStep.HANDSHAKE_WRAPUP,
710+
HandshakeStep.HANDSHAKE_OVER,
711+
),
712+
)
713+
do_io(src=server, dst=client)
714+
do_handshake(client, (HandshakeStep.HANDSHAKE_OVER,))
715+
assert client.cipher() == server.cipher()
716+
717+
secret = b"a very secret message"
718+
719+
amt = client.write(secret)
720+
do_io(src=client, dst=server)
721+
assert server.read(amt) == secret
722+
723+
amt = server.write(secret)
724+
do_io(src=server, dst=client)
725+
assert client.read(amt) == secret

0 commit comments

Comments
 (0)