
Hi list, I haven't seen this being discussed, but TL;DR I just want to propose to extend the ssl module so that TLS session state can be serialized to disk. I see a similar issue was being discussed here [0], but cannot tell why it (apparently) didn't get into. The link to the patch is broken. TLS session resumption is currently supported, but only within the same process. To the best of my knowledge, there is no way to save the TLS session to a file to resume the TLS session later on. Please tell me how this is done if I'm wrong. # # open a TLS connection # with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock: with context.wrap_socket(sock, server_hostname=hostname) \ as ssock: ssock.connect((hostname, 443)) ssl_session = ssock.session # get TLS session # # later on, open a new connection resuming session # with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock: with context.wrap_socket(sock, server_hostname=hostname, session=ssl_session) as ssock: ssock.connect((hostname, 443)) print("-- TLS session %s resumed --" % ("WAS" if ssock.session_reused else "WAS NOT") However TLS sessions live for hours, if not days, and hence it may make sense to persist them to disk for later retrieval. I think this is a real world use case though I have not any numbers to back this up. The values currently exposed by SSLSession (id, time, timeout) are not enough to resume a TLS session. There are a number of parameters that need to be stored to resume a TLS session at a later time, some of which are not currently retrievable from python's ssl module. For instance, the master secret. I'm not a fan of exposing the master secret directly with a getter as that could be and will definitely be misused by someone in spite of the bright red warnings, leading to disaster. What OpenSSL currently does, as do other implementations, is to allow the SSL_SESSION object to be serialized, with i2d_SSL_SESSION(). This function will return a DER-encoded ASN.1 object containing all the needed state to resume the TLS session. I do believe exposing this object from the ssl module (as an opaque bytes object) would be a useful compromise with very little chance of misuse. One possible incarnation of this idea would be add two new methods to SSLSession, to_der(), and from_der(): class SSLSession: def to_der(): """ Returns OpenSSL's DER-encoded SSL_SESSION object """ @staticmethod def from_der(der_bytes): """ Creates a new SSLSession object from the given DER-encoded SSL_SESSION object """ If this has already been discussed (likely), what are the reasons it was rejected? Thanks! [0] https://bugs.python.org/issue19500

On Thu, Apr 16, 2020 at 4:55 AM Ander Juaristi <a@juaristi.eus> wrote:
Not a Python SSL expert, but have you tried pickling the session object? If that doesn't work, then I would say that adding pickle support (using the semantics you describe) would be the cleanest way to do this. ChrisA

On Apr 15, 2020, at 12:11, Chris Angelico <rosuav@gmail.com> wrote:
I think this avoids the problem of “how do we effectively tell people that this could be dangerous if the pickles are stored somewhere accessible (or, worse, write-accessible)”, because it becomes just a specific case of the general danger the pickle module already warns about?

On Thu, 16 Apr 2020 05:07:15 +1000 Chris Angelico <rosuav@gmail.com> wrote:
Not sure pickling is the right answer here. The problem is, if someone is pickling an arbitrary application object, and that object happens to have a TLS session somewhere as an attribute (perhaps indirectly), the TLS session's secrets will be persisted without the developer noticing. Forcing serialization to go through an explicit step (such as the to_der() method that's been proposed) sounds much better to ensure that serialization of secrets only happens deliberately, not accidentally. Ander: personally, I would be +1 on the proposed improvement, but someone needs to submit a PR (and of course it has to be reviewed then :-)). Regards Antoine.

You might want to read this analysis of TLS session tickets in TLS 1.2. https://blog.filippo.io/we-need-to-talk-about-session-tickets/ Tl;dr its not considered secure. Barry

On Thu, Apr 16, 2020 at 4:55 AM Ander Juaristi <a@juaristi.eus> wrote:
Not a Python SSL expert, but have you tried pickling the session object? If that doesn't work, then I would say that adding pickle support (using the semantics you describe) would be the cleanest way to do this. ChrisA

On Apr 15, 2020, at 12:11, Chris Angelico <rosuav@gmail.com> wrote:
I think this avoids the problem of “how do we effectively tell people that this could be dangerous if the pickles are stored somewhere accessible (or, worse, write-accessible)”, because it becomes just a specific case of the general danger the pickle module already warns about?

On Thu, 16 Apr 2020 05:07:15 +1000 Chris Angelico <rosuav@gmail.com> wrote:
Not sure pickling is the right answer here. The problem is, if someone is pickling an arbitrary application object, and that object happens to have a TLS session somewhere as an attribute (perhaps indirectly), the TLS session's secrets will be persisted without the developer noticing. Forcing serialization to go through an explicit step (such as the to_der() method that's been proposed) sounds much better to ensure that serialization of secrets only happens deliberately, not accidentally. Ander: personally, I would be +1 on the proposed improvement, but someone needs to submit a PR (and of course it has to be reviewed then :-)). Regards Antoine.

You might want to read this analysis of TLS session tickets in TLS 1.2. https://blog.filippo.io/we-need-to-talk-about-session-tickets/ Tl;dr its not considered secure. Barry
participants (5)
-
Ander Juaristi
-
Andrew Barnert
-
Antoine Pitrou
-
Barry
-
Chris Angelico