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:
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.
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:
On Thu, Apr 16, 2020 at 4:55 AM Ander Juaristi <a@juaristi.eus> wrote:
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.
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.
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?
El 15/4/20 a las 21:07, Chris Angelico escribió:
On Thu, Apr 16, 2020 at 4:55 AM Ander Juaristi <a@juaristi.eus> wrote:
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.
Not a Python SSL expert, but have you tried pickling the session object?
Yes, I tried this as well. And no, it's currently not possible to pickle it.
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.
Could be an option. Thanks for the suggestion.
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/DQ3RIE... Code of Conduct: http://python.org/psf/codeofconduct/
On Thu, 16 Apr 2020 05:07:15 +1000 Chris Angelico <rosuav@gmail.com> wrote:
On Thu, Apr 16, 2020 at 4:55 AM Ander Juaristi <a@juaristi.eus> wrote:
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.
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.
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.
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 :-)).
I have a (dirty) patch that partially works :-) But I wanted to gather some feedback from this list before I think of finishing and submitting it.
Regards
Antoine.
On 15 Apr 2020, at 19:56, Ander Juaristi <a@juaristi.eus> wrote:
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.
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
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 _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/55RZJO... Code of Conduct: http://python.org/psf/codeofconduct/
participants (5)
-
Ander Juaristi
-
Andrew Barnert
-
Antoine Pitrou
-
Barry
-
Chris Angelico