Skip to content

Commit fc8e4ee

Browse files
authored
testcases/online: gentle refactoring (#144)
Signed-off-by: William Woodruff <[email protected]>
1 parent d4ef0d2 commit fc8e4ee

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

limbo/testcases/online.py

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,35 @@
3232
]
3333

3434

35+
def _peer_chain(*, host: str, port: int = 443, cafile: str = certifi.where()) -> list[Certificate]:
36+
"""
37+
Returns the peer certificate and intermediate chain for a given TLS connection
38+
on `(host, post)`.
39+
"""
40+
ctx = SSL.Context(method=SSL.TLS_METHOD)
41+
ctx.load_verify_locations(cafile=cafile)
42+
43+
conn = SSL.Connection(ctx, socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM))
44+
conn.set_tlsext_host_name(host.encode())
45+
conn.connect((host, port))
46+
conn.do_handshake()
47+
48+
chain = conn.get_verified_chain()
49+
assert chain is not None
50+
51+
return [Certificate(c.to_cryptography()) for c in chain]
52+
53+
3554
def compile() -> None:
3655
# NOTE: Uses `ASSETS_DIR_RW` instead of `ASSETS_PATH` since the latter
3756
# is a read-only API for package resources.
3857
online_assets = ASSETS_DIR_RW / "online"
3958
online_assets.mkdir(exist_ok=True)
4059

41-
for site in _TOPSITES:
42-
logger.info(f"generating online testcase for {site}")
43-
44-
ctx = SSL.Context(method=SSL.TLS_METHOD)
45-
ctx.load_verify_locations(cafile=certifi.where())
46-
47-
conn = SSL.Connection(ctx, socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM))
48-
conn.set_tlsext_host_name(site.encode())
49-
conn.connect((site, 443))
50-
conn.do_handshake()
60+
for host in _TOPSITES:
61+
logger.info(f"generating online testcase for {host}")
5162

52-
peer_chain = [Certificate(c.to_cryptography()) for c in (conn.get_verified_chain() or [])]
63+
peer_chain = _peer_chain(host=host)
5364

5465
# NOTE: We use the peer certificate's own state to produce our expected
5566
# validation time. This would be incorrect in a normal path validation operation,
@@ -61,25 +72,25 @@ def compile() -> None:
6172
) + timedelta(seconds=1)
6273

6374
builder = (
64-
Builder(id=f"online::{site}", description=f"A valid chain for `{site}`.")
75+
Builder(id=f"online::{host}", description=f"A valid chain for `{host}`.")
6576
.server_validation()
6677
.peer_certificate(peer_cert)
6778
.untrusted_intermediates(*peer_chain[1:-1])
6879
.trusted_certs(*peer_chain[-1:])
69-
.expected_peer_name(PeerName(kind="DNS", value=site))
80+
.expected_peer_name(PeerName(kind="DNS", value=host))
7081
.validation_time(peer_cert_validation_time)
7182
.succeeds()
7283
)
7384

7485
testcase = builder.build()
75-
path = online_assets / f"{site}.limbo.json"
76-
path.write_text(testcase.json(indent=2))
86+
path = online_assets / f"{host}.limbo.json"
87+
path.write_text(testcase.model_dump_json(indent=2))
7788

7889

7990
def register_testcases() -> None:
8091
online_assets = ASSETS_PATH / "online"
8192
for tc_path in online_assets.iterdir():
82-
testcase = Testcase.parse_raw(tc_path.read_text())
93+
testcase = Testcase.model_validate_json(tc_path.read_text())
8394

8495
print(f"loading pre-generated testcase: {testcase.id}")
8596

0 commit comments

Comments
 (0)