Using Python to find out what cipher a SSL server is using

September 30, 2008

I have a new-found interest in finding out what ciphers various SSL servers around here are using in some easy and convenient way. Doing this in Perl is easy (there's an example here), but I prefer Python. I'd normally use pyOpenSSL, my favorite Python OpenSSL module, but unfortunately it doesn't (currently) have an interface to the necessary 'get the connection's cipher' OpenSSL routine, and there's no visible substitute for it.

(While the .get_cipher_list() method of Connection objects looks tempting, I discovered through some experimentation that it doesn't return anything like the list of ciphers that are common between the server and the client.)

However, all is not lost; it turns out that the commonly available M2Crypto module does have enough functionality to do this. In fact, it's pretty easy, and so here is sample code to do it (omitting error checking, as usual):

from M2Crypto import SSL
def printcipher(host, port):
    ctx = SSL.Context('tlsv1')
    s = SSL.Connection(ctx)

    # No, really, all I care is that you successfully
    # negotiated SSL, especially as some of your checks
    # are broken.
    s.postConnectionCheck = None
    s.connect((host, port))

    # The space at the end is [sic]
    if s.get_state() == "SSLOK ":
        c = s.get_cipher()
        cp = c.name()
        print "Cipher %s, %d bits" % (cp, len(c))
        if cp.startswith("DHE-") or cp.startswith("EDH-"):
            print "forward secrecy: yes"
        else:
            print "forward secrecy: probably not"
    s.close()

This code works for protocols that start SSL/TLS immediately on connection, such as https or imaps. Extension to protocols that have a plaintext conversation and then start TLS (such as ESTMP with STARTTLS) is left as an exercise for the sufficiently interested.

I believe but am not sure that there is no point in asking for anything except TLS v1; the OpenSSL ciphers(1) manpage suggests that SSLv3 and TLSv1 have the same set of ciphers. (Presumably this is TLS v1.0.)

(Note that M2Crypto is pretty under-documented; reading the source is not so much recommended as required. Fortunately it comes with a large set of examples.)

Written on 30 September 2008.
« SSL/TLS and forward secrecy
The consequences of your SSL certificate getting compromised »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Tue Sep 30 00:41:06 2008
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.