quictls / openssl

TLS/SSL and crypto library with QUIC APIs
https://quictls.github.io/openssl
Apache License 2.0
380 stars 51 forks source link

SSL_process_quic_post_handshake should process multiple session tickets #7

Closed tatsuhiro-t closed 3 years ago

tatsuhiro-t commented 3 years ago

It looks like SSL_process_quic_post_handshake only processes a single session ticket in a single call as demonstrated in a test code. On the other hand, BoringSSL counterpart processes multiple session tickets in a single call.

We might be able to call SSL_process_quic_post_handshake multiple times, but there is an issue: we do not know how many times we should call it. This is because it returns 1 when no data to read is left.

I think it would be very useful if SSL_process_quic_post_handshake can process multiple session tickets just like BoringSSL.

tmshort commented 3 years ago

PRs welcome. :)

tatsuhiro-t commented 3 years ago

Will do after #8 is landed because it includes the code to call SSL_process_quic_post_handshake twice.

nibanks commented 3 years ago

Looks great! Thanks @tatsuhiro-t!

nibanks commented 3 years ago

Some (possibly general) questions on how the following would work:

tmshort commented 3 years ago
  • How do you trigger a NST to be sent on the server side?

Two session tickets are sent immediately after the handshake finishes (i.e. after the Finished message).

@kaduk has/had been working on a mechanism to send SessionTickets on-demand. I don't recall the status of that, which is why I'm tagging him.

  • How (if possible) does the server encode additional information in the NST to be sent?
  • On receipt, how does a server get that encoded information back out of a received NST?

In OpenSSL a SessionTicket is really just an encoded SSL_SESSION object, the server, upon receiving the SessionTicket, decrypts it, and a new SSL_SESSION is attached to the SSL. I added a ticket_app_data field to the SessionTicket in 1.1.1 (see https://github.com/quictls/openssl/commit/df0fed9aab2)

  • How does receiving a NST work on the client?
  • How does the client use a previously receive NST to "set a resumed session"?

My recollection, a SessionTicket can be extracted on the client-side (SSL_SESSION_get0_ticket() - not sure what you can do with it?). The SSL_SESSION may be reused between client connections (by assigning it to a new SSL via SSL_set_session()). I think you can export the session and then reuse it; I believe the openssl s_client app can do that; so details are in there.

nibanks commented 3 years ago

@kaduk has/had been working on a mechanism to send SessionTickets on-demand. I don't recall the status of that, which is why I'm tagging him.

With our QUIC API design we expose the ability for the server app to initiate the sending of a ticket with custom app data. That is then wrapped by custom QUIC data, which is then expected to be sent out into a NST. So, we'd need to make sure that works nicely with the ticket_app_data field and this on-demain session ticket interface.

My recollection, a SessionTicket can be extracted on the client-side (SSL_SESSION_get0_ticket() - not sure what you can do with it?). The SSL_SESSION may be reused between client connections (by assigning it to a new SSL via SSL_set_session()). I think you can export the session and then reuse it; I believe the openssl s_client app can do that; so details are in there.

Again, going back to our QUIC API, on the client side, the app is given the ticket (along with QUIC data) to save (to be used later for resumption) so that it can associate app-specific data to be used when resuming the session. Ideally, this ticket is a serialized binary blob to allow for resumption across different process executions, but it's not an absolute requirement (if we don't get it, then cross-process resumption won't work).

tmshort commented 3 years ago

Again, going back to our QUIC API, on the client side, the app is given the ticket (along with QUIC data) to save (to be used later for resumption) so that it can associate app-specific data to be used when resuming the session. Ideally, this ticket is a serialized binary blob to allow for resumption across different process executions, but it's not an absolute requirement (if we don't get it, then cross-process resumption won't work).

I have https://github.com/openssl/openssl/pull/5932 outstanding upstream that does just that (client-side caching).

Yup, that's what an OpenSSL SessionTicket is. You just have to use the same encrypt/decrypt key across processes.

nibanks commented 3 years ago

I have openssl#5932 outstanding upstream that does just that (client-side caching).

That PR is nearly 3 years old?! Is it going anywhere?

tmshort commented 3 years ago

That PR is nearly 3 years old?! Is it going anywhere?

FIPS has been upstream's priority. I'm updating it now; as it was at risk of being stale.

kaduk commented 3 years ago

@kaduk has/had been working on a mechanism to send SessionTickets on-demand. I don't recall the status of that, which is why I'm tagging him.

https://github.com/openssl/openssl/pull/11416 exists and works okay for non-QUIC TLS usage, but it is incompatible with QUIC. The reason is that, as currently implemented, it attempts to consolidate network writes by waiting to send the NewSessionTicket handshake message until there is TLS application data to send as well; for QUIC, there is never TLS application data. I think that it should be possible to change the implementation to enter the state machine immediately (if possible -- non-QUIC TLS can be in the middle of an application write where it is not safe to enter the state machine) and that would be compatible with QUIC, but I haven't had a chance to test out that theory yet.

kaduk commented 3 years ago

Two session tickets are sent immediately after the handshake finishes (i.e. after the Finished message).

I guess it's also topical to note here that https://github.com/openssl/openssl/pull/5227 added the SSL_CTX_set_num_tickets() family of APIs, that let you configure that "two" to instead be some other number (including zero), which, when combined with send-ticket-on-demand, can give greater flexibility about when tickets are sent and what data is (available to) put into them.

tmshort commented 3 years ago

Completed for 1.1.1.

tmshort commented 3 years ago

Merged to alpha12+quic then cherry-picked into alpha13+quic