Commit 5b162fb2 authored by Stephane Bortzmeyer's avatar Stephane Bortzmeyer
Browse files

Refactoring of hostname canonicalisation. Closes #20

parent 8ebd73a2
......@@ -74,9 +74,18 @@ def usage(msg=None):
print("See the for more details.", file=sys.stderr)
def is_valid_hostname(name):
name = str(name.encode('idna').lower())
name = canonicalize(name)
def canonicalize(hostname):
result = hostname.lower()
# TODO handle properly the case where it fails with UnicodeError
# (two consecutive dots for instance) to get a custom exception
result = result.encode('idna').decode()
if result[len(result)-1] == '.':
result = result[:-1]
return result
def is_valid_ip_address(addr):
baddr = netaddr.IPAddress(addr)
......@@ -125,15 +134,11 @@ def validate_hostname(hostname, cert):
# Complete specification is in RFC 6125. It is long and
# complicated and I'm not sure we do it perfectly.
is_addr = is_valid_ip_address(hostname)
hostname = hostname.lower()
hostname = hostname.encode('idna').decode()
hostname = canonicalize(hostname)
for alt_name in get_certificate_san(cert).split(", "):
if alt_name.startswith("DNS:") and not is_addr:
(start, base) = alt_name.split("DNS:")
base = base.lower()
# We assume the certificate contains only
# A-labels. Otherwise, we would need to: "base =
# str(base.encode('idna'))"
base = canonicalize(base)
found = match_hostname(hostname, base)
if found:
return True
......@@ -152,7 +157,7 @@ def validate_hostname(hostname, cert):
pass # Ignore unknown alternative name types. May be
# accept URI alternative names for DoH,
# According to RFC 6125, we MUST NOT try the Common Name before the Subject Alternative Names.
cn = cert.get_subject().commonName.lower()
cn = canonicalize(cert.get_subject().commonName)
found = match_hostname(hostname, cn)
if found:
return True
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment