How to get current cipher in pyOpenSSL for DTLS

2020-04-21 05:21发布

问题:

I need to get a negotiated cipher for DTLS protocol in pyOpenSSL. I was successful in doing that for TCP sockets, but when it comes to datagrams, it's not that obvious. Please provide an example either in C or Python. This is what I've tried so far:

import socket
from OpenSSL import SSL
from OpenSSL._util import (
    ffi as _ffi,
    lib as _lib)


DTLSv1_METHOD = 7
SSL.Context._methods[DTLSv1_METHOD]=getattr(_lib, "DTLSv1_client_method")
ctx = SSL.Context(DTLSv1_METHOD)
ctx.set_cipher_list('AES128-SHA')
ctx.use_certificate_file("path-to-cert.pem")
ctx.use_privatekey_file("path-to-key.pem")
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('dtls-host', 443))
con = SSL.Connection(ctx, s)
con.set_connect_state()
con.connect(('dtls-host', 443))
cc = _lib.SSL_get_current_cipher(con._ssl)
print _ffi.string( _lib.SSL_CIPHER_get_name(cc))

The printed result is (None)

回答1:

The result is None because that is the cipher that has been negotiated for your connection. Or rather, it is None because no cipher has been negotiated for your connection yet. Cipher selection is part of the handshake and the handshake is not done anywhere in this example.

Try con.do_handshake() before calling SSL_get_current_cipher.

Also bear in mind that _-prefixed names are private and you really shouldn't use them if you want your program to keep working with future versions of pyOpenSSL.