commit 52450289ff2613f7e0e6b736a45254c35cf37ade
parent 889ac782c11409cd15060617bf615e0c83e12a6d
Author: ThomasV <thomasv@gitorious>
Date: Fri, 19 Sep 2014 10:18:33 +0200
we must check host name if cert is signed by CA
Diffstat:
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/lib/interface.py b/lib/interface.py
@@ -119,6 +119,31 @@ class TcpInterface(threading.Thread):
queue.put((self, {'method':method, 'params':params, 'result':result, 'id':_id}))
+ def check_host_name(self, peercert, name):
+ """Simple certificate/host name checker. Returns True if the
+ certificate matches, False otherwise. Does not support
+ wildcards."""
+ # Check that the peer has supplied a certificate.
+ # None/{} is not acceptable.
+ if not peercert:
+ return False
+ if peercert.has_key("subjectAltName"):
+ for typ, val in peercert["subjectAltName"]:
+ if typ == "DNS" and val == name:
+ return True
+ else:
+ # Only check the subject DN if there is no subject alternative
+ # name.
+ cn = None
+ for attr, val in peercert["subject"]:
+ # Use most-specific (last) commonName attribute.
+ if attr == "commonName":
+ cn = val
+ if cn is not None:
+ return cn == name
+ return False
+
+
def get_simple_socket(self):
try:
l = socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM)
@@ -149,10 +174,11 @@ class TcpInterface(threading.Thread):
try:
ca_certs = os.path.join(self.config.path, 'ca', 'ca-bundle.crt')
s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3, cert_reqs=ssl.CERT_REQUIRED, ca_certs=ca_certs, do_handshake_on_connect=True)
- print_error("SSL with ca:", self.host)
- return s
except ssl.SSLError, e:
- pass
+ s = None
+ if s and self.check_host_name(s.getpeercert(), self.host):
+ print_error("SSL certificate signed by CA:", self.host)
+ return s
# get server certificate.
# Do not use ssl.get_server_certificate because it does not work with proxy