summaryrefslogtreecommitdiff
path: root/src/leap/crypto/certs.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/crypto/certs.py')
-rw-r--r--src/leap/crypto/certs.py112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/leap/crypto/certs.py b/src/leap/crypto/certs.py
new file mode 100644
index 00000000..cbb5725a
--- /dev/null
+++ b/src/leap/crypto/certs.py
@@ -0,0 +1,112 @@
+import logging
+import os
+from StringIO import StringIO
+import ssl
+import time
+
+from dateutil.parser import parse
+from OpenSSL import crypto
+
+from leap.util.misc import null_check
+
+logger = logging.getLogger(__name__)
+
+
+class BadCertError(Exception):
+ """
+ raised for malformed certs
+ """
+
+
+class NoCertError(Exception):
+ """
+ raised for cert not found in given path
+ """
+
+
+def get_https_cert_from_domain(domain, port=443):
+ """
+ @param domain: a domain name to get a certificate from.
+ """
+ cert = ssl.get_server_certificate((domain, port))
+ x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
+ return x509
+
+
+def get_cert_from_file(_file):
+ null_check(_file, "pem file")
+ if isinstance(_file, (str, unicode)):
+ if not os.path.isfile(_file):
+ raise NoCertError
+ with open(_file) as f:
+ cert = f.read()
+ else:
+ cert = _file.read()
+ x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
+ return x509
+
+
+def get_pkey_from_file(_file):
+ getkey = lambda f: crypto.load_privatekey(
+ crypto.FILETYPE_PEM, f.read())
+
+ if isinstance(_file, str):
+ with open(_file) as f:
+ key = getkey(f)
+ else:
+ key = getkey(_file)
+ return key
+
+
+def can_load_cert_and_pkey(string):
+ """
+ loads certificate and private key from
+ a buffer
+ """
+ try:
+ f = StringIO(string)
+ cert = get_cert_from_file(f)
+
+ f = StringIO(string)
+ key = get_pkey_from_file(f)
+
+ null_check(cert, 'certificate')
+ null_check(key, 'private key')
+ except Exception as exc:
+ logger.error(type(exc), exc.message)
+ raise BadCertError
+ else:
+ return True
+
+
+def get_cert_fingerprint(domain=None, port=443, filepath=None,
+ hash_type="SHA256", sep=":"):
+ """
+ @param domain: a domain name to get a fingerprint from
+ @type domain: str
+ @param filepath: path to a file containing a PEM file
+ @type filepath: str
+ @param hash_type: the hash function to be used in the fingerprint.
+ must be one of SHA1, SHA224, SHA256, SHA384, SHA512
+ @type hash_type: str
+ @rparam: hex_fpr, a hexadecimal representation of a bytestring
+ containing the fingerprint.
+ @rtype: string
+ """
+ if domain:
+ cert = get_https_cert_from_domain(domain, port=port)
+ if filepath:
+ cert = get_cert_from_file(filepath)
+ hex_fpr = cert.digest(hash_type)
+ return hex_fpr
+
+
+def get_time_boundaries(certfile):
+ cert = get_cert_from_file(certfile)
+ null_check(cert, 'certificate')
+
+ fromts, tots = (cert.get_notBefore(), cert.get_notAfter())
+ from_, to_ = map(
+ lambda ts: time.gmtime(time.mktime(parse(ts).timetuple())),
+ (fromts, tots))
+ return from_, to_