Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work around openssl's weird SSL_shutdown semantics by calling SSL_read during shutdown #536

Open
njsmith opened this issue May 19, 2018 · 1 comment
Labels
design discussion polish TLS Relevant to our TLS/SSL implementation

Comments

@njsmith
Copy link
Member

njsmith commented May 19, 2018

So apparently openssl's SSL_shutdown semantics are even more convoluted than I realized:

https://bugs.python.org/issue30437#msg317028
openssl/openssl#6262 (comment)

There are two issues, which interact:

When SSL_shutdown is called a second time to read from the socket looking for a close_notify from the peer, it actually errors out if it sees something that isn't close_notify. Which of course can happen, because the other side could be doing anything, we don't know. And when this happens, the error reported is "syscall error", which makes no sense but at least explains this (also) Apparently the recommendation in this case is to call SSL_read to drain the socket of actual data / other control messages, until it reports EOF (and then you know you got a close_notify).

In TLS 1.3, session tickets are sent from the server to the client as control mesages right after the handshake completes. This means that if a client connects, sends some data, and then disconnects without calling SSL_read, they never get the session tickets. If you then try to do a full clean shutdown, this means you will trigger the SSL_shutdown issue, and need to call SSL_read to clear it, so it's relevant to the above.

But, it also means that you kind of want to call SSL_read always, because reading session tickets is important – it lets you save a round-trip on your next handshake. ...maybe this should be a separate issue? I'm still confused and don't anticipate dealing with any of this immediately so I'm going to leave it here for now. Anyway, what this means is that maybe before shutting down your TLS connection you always want to call SSL_read a few times, just while there's data to process, so you don't miss reading session tickets. And fixing the full-SSL_shutdown case as described above won't actually help with this, because in normal usage we only ever call SSL_shutdown once.

But annoyingly, we can't do this automatically, or at all really, because of the requirement to only read the data that's already arrived, without blocking. The Stream interface doesn't have a receive_some_nowait method, and that's what SSLStream would need to call.

@njsmith
Copy link
Member Author

njsmith commented May 23, 2018

It looks like this makes the problem less severe, but I haven't dug into the details: openssl/openssl#6340

@oremanj oremanj added the TLS Relevant to our TLS/SSL implementation label May 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design discussion polish TLS Relevant to our TLS/SSL implementation
Projects
None yet
Development

No branches or pull requests

2 participants