Core Question
Core Question
A chain can be perfectly trusted and still be the wrong certificate for the connection you're making. What decides whether a certificate is allowed to speak for the hostname you asked for?
Outcome
Outcome
By the end of this session, the learner should be able to:
- explain why exact matches are checked before any wildcard match
- state precisely which label a wildcard is allowed to cover
- explain why
*.example.comdoes not matcha.b.example.com - explain why
*.example.comdoes not matchexample.comitself - explain why
w*.example.comis always rejected as a wildcard
Read Order
Read Order
- Read
HostnameVerdictandHostnameMatch - Read
matches_exact() - Read
matches_wildcard() - Read
match_hostname() - Run
examples/tls/session_05_walkthrough.py
Read It Like Code
Read It Like Code
HostnameMatch(
verdict,
matched_san,
)Fields That Matter
Fields That Matter
| Field | Why it matters |
|---|---|
verdict | One of MATCHED_EXACT, MATCHED_WILDCARD, NO_MATCH. Which branch fired, not just whether it matched. |
matched_san | The specific SAN entry that won, or None on NO_MATCH. Lets you point at *which* name in the certificate was responsible. |
Decision Flow
Decision Flow
any san: hostname == san (case-insensitive) -> MatchedExact any san: san is "*.<suffix>" and hostname is -> MatchedWildcard exactly one non-empty, dot-free label + <suffix> otherwise -> NoMatch
Reading Lens
Reading Lens
The important move in this session is to stop thinking of wildcard matching as "does the string end with the right suffix" and start asking:
- what is left over after the suffix is stripped off — and does that leftover contain a dot?
- is the exact-match loop checked before or after the wildcard loop, and does that order ever change the outcome?
- is
sanrequired to literally start with*., or wouldw*.example.comalso qualify as a wildcard?
Toy Model Boundary
Toy Model Boundary
Real certificate validation also falls back to the deprecated Common Name field when SAN is absent (this code never does — SANs are the only input match_hostname() accepts), and real clients apply public-suffix-list rules to stop wildcards like *.co.uk from being treated as safe. Neither exists here: match_hostname() is pure string comparison against whatever san_names tuple it's handed, with RFC 6125's leftmost-label rule as the only constraint on wildcards.
Code Landmarks
Code Landmarks
matches_exact()
return hostname.lower() == san.lower()
Case-insensitivity is the entire rule. No suffix logic, no labels — just a lowered string comparison.
matches_wildcard()
if not san.startswith("*."):
return FalseThe wildcard marker must be exactly *. at the start of the SAN. w*.example.com fails this check immediately — it never even reaches the label logic, so it's rejected regardless of what hostname you test it against.
wildcard_suffix = san[1:] # keeps the leading dot, e.g. ".example.com"
if not hostname.endswith(wildcard_suffix):
return False
remaining = hostname[: -len(wildcard_suffix)]
return len(remaining) > 0 and "." not in remainingremaining is whatever the wildcard would have to stand for. Two conditions gate it: it must be non-empty (so the wildcard can't match "nothing," which is what would let *.example.com match example.com), and it must contain no dot (so the wildcard can't silently swallow an extra label, which is what would let *.example.com match a.b.example.com).
match_hostname()
for san in san_names:
if matches_exact(hostname, san):
return HostnameMatch(HostnameVerdict.MATCHED_EXACT, san)
for san in san_names:
if matches_wildcard(hostname, san):
return HostnameMatch(HostnameVerdict.MATCHED_WILDCARD, san)Two full passes over san_names. Every SAN is checked for an exact match before any SAN is checked for a wildcard match — so if a certificate happens to list both www.example.com and *.example.com, the exact entry wins even if it appears later in the tuple.
Failure Questions
Failure Questions
Use the source file to answer these:
- If
san_namescontains*.example.comat index 0 andwww.example.comat index 1, and the hostname iswww.example.com, which verdict wins, and why does the two-loop structure ofmatch_hostname()guarantee that regardless of tuple order? - Why does
matches_wildcard("a.b.example.com", "*.example.com")returnFalse— walk through whatremainingevaluates to. - Why does
matches_wildcard("example.com", "*.example.com")returnFalse— what doesremainingequal, and which of the two guard conditions rejects it? matches_wildcard()checkssan.startswith("*.")before computingwildcard_suffix. What would go wrong ifw*.example.comwere allowed to reach theremainingcomputation?- Does
match_hostname()ever lowercasesan_namesbefore comparison, or is that done per-call inside each helper? What would break if a caller comparedsan_namesdirectly without going throughmatches_exact/matches_wildcard?
Walkthrough
Walkthrough
Run this:
PYTHONPATH=src python3 examples/tls/session_05_walkthrough.py
The walkthrough checks an exact match, a case-insensitive exact match, a valid wildcard match, a wildcard that fails because it would have to span two labels, a wildcard that fails against the bare domain, a partial-label wildcard that's rejected outright, and a hostname with no owning SAN at all.
Done When
Done When
The learner can say all of the following without looking at notes:
- "Exact matches are checked in a full pass before any wildcard is checked, not interleaved."
- "A wildcard covers exactly one non-empty label and nothing more — not zero labels, not two."
- "
w*.example.comis rejected before label logic even runs, because the SAN doesn't start with*.." - "This is string matching against a SAN list — there's no CN fallback and no public-suffix awareness here."
References
References
- RFC 6125 Section 6.4.3 (wildcard certificate matching rules)
Continue