summaryrefslogtreecommitdiff
path: root/src/leap/crypto/certs.py
blob: ac9bd357eb195472bc87f93dacde6142121b9ea4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import ctypes
import socket

import gnutls.connection
import gnutls.library


def get_https_cert_from_domain(domain):
    """
    @param domain: a domain name to get a certificate from.
    """
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    cred = gnutls.connection.X509Credentials()

    session = gnutls.connection.ClientSession(sock, cred)
    session.connect((domain, 443))
    session.handshake()
    cert = session.peer_certificate
    return cert


def get_https_cert_fingerprint(domain, hash_type="SHA256", sep=":"):
    """
    @param domain: a domain name to get a fingerprint from
    @type domain: 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
    """
    cert = get_https_cert_from_domain(domain)

    _buffer = ctypes.create_string_buffer(64)
    buffer_length = ctypes.c_size_t(64)

    SUPPORTED_DIGEST_FUN = ("SHA1", "SHA224", "SHA256", "SHA384", "SHA512")
    if hash_type in SUPPORTED_DIGEST_FUN:
        digestfunction = getattr(
            gnutls.library.constants,
            "GNUTLS_DIG_%s" % hash_type)
    else:
        # XXX improperlyconfigured or something
        raise Exception("digest function not supported")

    gnutls.library.functions.gnutls_x509_crt_get_fingerprint(
        cert._c_object, digestfunction,
        ctypes.byref(_buffer), ctypes.byref(buffer_length))

    # deinit
    #server_cert._X509Certificate__deinit(server_cert._c_object)
    # needed? is segfaulting

    fpr = ctypes.string_at(_buffer, buffer_length.value)
    hex_fpr = sep.join(u"%02X" % ord(char) for char in fpr)

    return hex_fpr

#if __name__ == "__main__":
    #print get_https_cert_fingerprint('springbok')