Open ctz opened 2 months ago
I was looking at adding Ubuntu 24.04 to the CI matrix now that runner images are available (see https://github.com/rustls/rustls-openssl-compat/pull/20 for some discussion) and noticed the runner.rs
nginx
test fails on 24.40 with Nginx 1.24.0 because the /ssl-was-reused
endpoint always returns .
.
Here are some notes on the root cause - the TL;DR (and why I'm commenting here) is that I believe we need to implement the session ticket callback functionality to make 1.24.0 have working session resumption.
Reproducing locally it's pretty obvious why the resumption test is failing as nginx 1.24.0 logs this at startup:
2024/06/11 14:24:46 [warn] 2922744#2922744: nginx was built with Session Tickets support, however, now it is linked dynamically to an OpenSSL library which has no tlsext support, therefore Session Tickets are not available
That in turn seems to be emitted in ngx_event_openssl.c
when SSL_CTX_set_tlsext_ticket_key_cb
fails. Both that function (deprecated) and the replacement SSL_CTX_set_tlsext_ticket_key_evp_cb
are #define
's that expand to calls to SSL_CTX_callback_ctrl
with cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
.
In both cases the callback has the signature:
int (*cb)(SSL *s, unsigned char key_name[16],
unsigned char iv[EVP_MAX_IV_LENGTH],
EVP_CIPHER_CTX *ctx, EVP_MAC_CTX *hctx, int enc))
We have some experience implementing cmd
's off of the SSL_CTX_callback_ctrl
entry point (presently just SslCtrl::SetTlsExtServerNameCallback
) but this callback also needs initialized EVP_CIPHER_CTX
and EVP_MAC_CTX
arguments. Should these be modeled similar to EVP_PKEY
?
I think this issue is mostly about client-side session caching, so probably shouldn't have much bearing on nginx.
I wonder what happens if we accept the SSL_CTX_set_tlsext_ticket_key_cb
but never call the callback?
To get this fully working we'd need to implement the rustls ProducesTickets
trait in terms of calling the callback, then using the returned cipher and mac keys to implement the RFC5077 "recommended" construction which AIUI the openssl API is tightly coupled to.
I think this issue is mostly about client-side session caching, so probably shouldn't have much bearing on nginx.
Oops yes, you're right :-) I will pull the relevant comments into a new issue.
I wonder what happens if we accept the SSL_CTX_set_tlsext_ticket_key_cb but never call the callback?
I actually went down this rabbit hole a bit yesterday. I think it's workable after re-reading the SSL_CTX_set_tlsext_ticket_key_cb
man page (and fixing some broken english in it...) and the nginx callback. It feels like the correct route is to use our own fully-fledged ticketer instead of trying to do it the OpenSSL way.
I tried this and I expected this to Just Work but found that for some reason the ticketer I constructed with the provider and stuck in the server config was always failing to decrypt the ticket curl
was giving back. I took a pcap and also added some logging and the issued ticket ciphertext exactly matched the to-be-decrypted ciphertext read back from the client. It looked like the unseal-in-place operation was producing an opaque Unspecified
error. I'm not sure what the root issue is.
I'm going to finish up the config surface and then I will return to this rabbit hole. Theories+advice welcome!
I will pull the relevant comments into a new issue.
At the moment client-side session caching only respects
SSL_CTX_sess_set_cache_size
, but not the cache mode, callbacks,SSL_get_session
etc.Meaningfully implementing
SSL_get_session
would mean rustls client sessions would need to become serialisable -- they currently are not.