1 """This is a temporary hack to fix an SSL bug in Python versions before 3.2.
2 It is used automatically when you download an HTTPS URL using a Fetcher.
3
4 Copyright: Python Software Foundation
5 License: MIT License
6 Downloaded from: http://pypi.python.org/pypi/backports.ssl_match_hostname/"""
7
8
9
10 import re
11
14
16 """@type dn: str"""
17 pats = []
18 for frag in dn.split(r'.'):
19 if frag == '*':
20
21
22 pats.append('[^.]+')
23 else:
24
25 frag = re.escape(frag)
26 pats.append(frag.replace(r'\*', '[^.]*'))
27 return re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
28
30 """Verify that *cert* (in decoded format as returned by
31 SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 rules
32 are mostly followed, but IP addresses are not accepted for *hostname*.
33
34 CertificateError is raised on failure. On success, the function
35 returns nothing.
36 @type hostname: str"""
37 if not cert:
38 raise ValueError("empty or no certificate")
39 dnsnames = []
40 san = cert.get('subjectAltName', ())
41 for key, value in san:
42 if key == 'DNS':
43 if _dnsname_to_pat(value).match(hostname):
44 return
45 dnsnames.append(value)
46 if not san:
47
48 for sub in cert.get('subject', ()):
49 for key, value in sub:
50
51
52 if key == 'commonName':
53 if _dnsname_to_pat(value).match(hostname):
54 return
55 dnsnames.append(value)
56 if len(dnsnames) > 1:
57 raise CertificateError("hostname %r "
58 "doesn't match either of %s"
59 % (hostname, ', '.join(map(repr, dnsnames))))
60 elif len(dnsnames) == 1:
61 raise CertificateError("hostname %r "
62 "doesn't match %r"
63 % (hostname, dnsnames[0]))
64 else:
65 raise CertificateError("no appropriate commonName or "
66 "subjectAltName fields were found")
67