Created
October 10, 2013 13:44
-
-
Save sigmunau/6918558 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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