Skip to content

Instantly share code, notes, and snippets.

@sigmunau
Created October 10, 2013 13:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sigmunau/6918558 to your computer and use it in GitHub Desktop.
Save sigmunau/6918558 to your computer and use it in GitHub Desktop.
def match_ip_address(cert, ip_address):
"""Verify that *cert* (in decoded format as returned by
SSLSocket.getpeercert()) matches the *ip_address*. According to RFC 6125
section 3.1.3.2.
CertificateError is raised on failure. On success, the function
returns nothing.
"""
if not cert:
raise ValueError("empty or no certificate")
ipaddresses = []
san = cert.get('subjectAltName', ())
for key, value in san:
if key == 'IP':
if _ipaddress_match(value, ip_address):
return
ipaddresses.append(value)
if not ipaddresses:
# The subject is only checked when there is no ip address entry
# in subjectAltName
# XXX possibly this shouldn't be used at all
for sub in cert.get('subject', ()):
for key, value in sub:
# XXX according to RFC 2818, the most specific Common Name
# must be used.
if key == 'commonName':
if _ipaddress_match(value, hostname):
return
ipaddresses.append(value)
if len(ipaddresses) > 1:
raise CertificateError("ip address %r "
"doesn't match either of %s"
% (hostname, ', '.join(map(repr, ipaddresses))))
elif len(ipaddresses) == 1:
raise CertificateError("ip address %r "
"doesn't match %r"
% (hostname, ipaddresses[0]))
else:
raise CertificateError("no appropriate commonName or "
"subjectAltName fields were found")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment