Hi everyone, I was recently messing around with secure connection establishment and tried to implement optimistic DANE/TLSA verification to avoid having to go through my browser-provided list of several hundred Certificate Authorities, which I assume will get quite a bit longer in the near future due to regulation in the European Union (Context).
Armed with a satisfying solution for DNSSEC (another topic…) and seeing support for DANE has already made its way into OpenSSL (e.g. have a look at SSL_CTX_dane_enable(3ssl)), I was looking to use this functionality in cpython.
This is where I hit a roadblock:
The OpenSSL functionality mentioned above is currently not exposed in the _ssl
module, which (as far as I can tell) rules out usage of this functionality during the handshake validation routine. At the same time, there does not seem to exist a functionality to acquire the peer’s certificate chain in order to manually verify the peer after the handshake. (Note that SSLObject.getpeercert
is insufficient for this, since TLSA records can reference CAs.)
Hence some proposals of mine, for which I am seeking feedback in the form of additions, opinions, alternatives/workarounds and all kinds of helpful comments
I tried ordering them from least to most invasive to the documented stdlib
:
Proposal 1
Declare functions in the _ssl
module corresponding to the following OpenSSL functions:
- SSL_CTX_dane_enable
- SSL_dane_enable
- SSL_dane_tlsa_add
By corresponding
I do not mean that there should be one function in python for every function in C, rather the functionality of enabling DANE verification and adding acceptable records should be exposed.
This would allow external python modules to wrap an SSLContext and add TLSA verification.
Since the documented stdlib
is not touched, the impact on users should be minimal.
Proposal 2
Add the functionality directly to the ssl
module, ideally exposed on the SSLContext passed to the various stdlib functions establishing secure TLS connections.
This is a bit more invasive, and likely requires the new functionality to be properly documented (which it probably should be anyway), but does not break backwards compatibility with existing python scripts, since functionality is only added, not removed.
That said, modules (and code in general) relying on this addition without a fallback will be backwards-incompatible with current versions of cpython
, but this seems unavoidable.
Looking forward to any comments . Thanks for reading!