5
from OpenSSL import SSL
6
from OpenSSL.crypto import load_certificate, FILETYPE_PEM
8
from twisted.internet.ssl import CertificateOptions
11
__all__ = ["VerifyingContextFactory", "get_ca_certs"]
14
class VerifyingContextFactory(CertificateOptions):
16
A SSL context factory to pass to C{connectSSL} to check for hostname
20
def __init__(self, host, caCerts=None):
22
caCerts = get_global_ca_certs()
23
CertificateOptions.__init__(self, verify=True, caCerts=caCerts)
26
def _dnsname_match(self, dn, host):
28
for frag in dn.split(r"."):
32
frag = re.escape(frag)
33
pats.append(frag.replace(r"\*", "[^.]*"))
35
rx = re.compile(r"\A" + r"\.".join(pats) + r"\Z", re.IGNORECASE)
36
return bool(rx.match(host))
38
def verify_callback(self, connection, x509, errno, depth, preverifyOK):
39
# Only check depth == 0 on chained certificates.
42
if getattr(x509, "get_extension", None) is not None:
43
for index in range(x509.get_extension_count()):
44
extension = x509.get_extension(index)
45
if extension.get_short_name() != "subjectAltName":
48
for element in data.split(", "):
49
key, value = element.split(":")
52
if self._dnsname_match(value, self.host):
57
commonName = x509.get_subject().commonName
58
if commonName is None:
60
if not self._dnsname_match(commonName, self.host):
66
def _makeContext(self):
67
context = CertificateOptions._makeContext(self)
69
SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
74
def get_ca_certs(files="/etc/ssl/certs/*.pem"):
75
"""Retrieve a list of CAs pointed by C{files}."""
76
certificateAuthorityMap = {}
77
for certFileName in glob(files):
78
# There might be some dead symlinks in there, so let's make sure it's
80
if not os.path.exists(certFileName):
82
certFile = open(certFileName)
83
data = certFile.read()
85
x509 = load_certificate(FILETYPE_PEM, data)
86
digest = x509.digest("sha1")
87
# Now, de-duplicate in case the same cert has multiple names.
88
certificateAuthorityMap[digest] = x509
89
return certificateAuthorityMap.values()
95
def get_global_ca_certs():
96
"""Retrieve a singleton of CA certificates."""
99
_ca_certs = get_ca_certs()