[PATCH 01 of 11] SSL: disabled saving tickets to session cache
Maxim Dounin
mdounin at mdounin.ru
Tue Sep 27 20:14:23 UTC 2022
Hello!
On Mon, Sep 26, 2022 at 02:11:17PM +0400, Sergey Kandaurov wrote:
> > On 17 Sep 2022, at 00:58, Maxim Dounin <mdounin at mdounin.ru> wrote:
> >
> > On Thu, Sep 15, 2022 at 09:36:31AM +0400, Sergey Kandaurov wrote:
> >
> >>> On 26 Aug 2022, at 07:01, Maxim Dounin <mdounin at mdounin.ru> wrote:
> >>>
> >>> # HG changeset patch
> >>> # User Maxim Dounin <mdounin at mdounin.ru>
> >>> # Date 1661481945 -10800
> >>> # Fri Aug 26 05:45:45 2022 +0300
> >>> # Node ID 2cd8fbeb4edc5a99b725585edc02a16a8a0c503e
> >>> # Parent 069a4813e8d6d7ec662d282a10f5f7062ebd817f
> >>> SSL: disabled saving tickets to session cache.
> >>>
> >>> OpenSSL for TLSv1.3 tries to save tickets into session cache "because some
> >>> applications just want to know about the creation of a session". To avoid
> >>> trashing session cache with useless data, we do not save such sessions now.
> >>>
> >>
> >> For the record, BoringSSL doesn't seem to call new_session_cb for TLSv1.3
> >> at all, so there is no way to resume sessions with SSL_OP_NO_TICKET set.
> >> In contrary, OpenSSL emits stateful tickets in this case, which contain
> >> dummy session id used then as a session cache lookup key on server
> >> (much like session ids in TLSv1.2)
> >>
> >> OTOH, without SSL_OP_NO_TICKET set, OpenSSL emits self-containing tickets
> >> with enough info to resume session, so nothing to lookup in session cache.
> >> The latter makes impractical storing something in session cache, except
> >> to use the callback for things like tracking "the creation of a session".
> >> Namely, OpenSSL puts session (i.e. something that SSL_get_session returns)
> >> and supplementary info to session ticket message as the ticket value.
> >
> > It looks like you are trying to introduce "stateful tickets" and
> > "self-containing tickets" terms, which is somewhat confusing
> > unless carefully explained. OpenSSL itself tries to use terms
> > "stateful tickets" and "stateless tickets", with the similar
> > drawbacks.
>
> Indeed, OpenSSL SSL_OP_NO_TICKET documentation is what I refer to.
> While OpenSSL terms may look odd, they are useful to describe the
> difference (and tricks) in TLSv1.3 session resumption with and
> without SSL_OP_NO_TICKET, as implemented to OpenSSL specifically.
Sure. The problem is that OpenSSL's SSL_OP_NO_TICKET
documentation is far from perfect, and I would rather avoid using
it for anything but explanation of how SSL_OP_NO_TICKET works with
TLSv1.3.
> > A better explanation would be to follow generic term "session
> > ticket", as originally introduced in RFC 4507 for TLS session
> > resumption without server-side state.
> >
> > In these terms (as always used before introduction of TLSv1.3 and
> > currently used in many places, including nginx own documentation
> > and the source code) there are two basic mechanisms to resume
> > sessions: server-side session cache and session tickets (used to
> > resume sessions without server-side state).
> >
> > Without SSL_OP_NO_TICKET set, OpenSSL uses tickets as long as
> > supported by the client.
> >
> > With SSL_OP_NO_TICKET set, OpenSSL does not use tickets, and uses
> > server-side session cache instead (if configured).
> >
> > The only difference between TLSv1.3 and previous protocols is how
> > session ids are sent to the client if server-side session cache is
> > used. In case of SSL and TLS up to and including TLSv1.2, session
> > ids are sent in the dedicated fields of the ServerHello and
> > ClientHello handshake messages. In case of TLSv1.3, dedicated
> > fields were removed, so session ids are sent in the
> > NewSessionTicket messages ("a database lookup key" in terms of RFC
> > 8446).
> >
> >> With these thoughts in mind, I think log could be clarified to emphasize:
> >> - it's not tickets that are stored in cache
> >> - with SSL_OP_NO_TICKET set TLSv1.3 session are still saved to lookup by id.
> >
> > Hope it is clear enough now.
>
> What I'd like to clarify is the difference between session and (session)
> ticket applied to session cache. Ticket is a container used to envelope
> session state (essentially, a session) and send in the NewSessionTicket
> message "to resume sessions and avoid keeping per-client session state",
> as seen in RFC 8446, 4.6.1 (and somewhat similar in 4507/5077).
>
> struct {
> uint32 ticket_lifetime;
> uint32 ticket_age_add;
> opaque ticket_nonce<0..255>;
> opaque ticket<1..2^16-1>;
> Extension extensions<0..2^16-2>;
> } NewSessionTicket;
>
> So it looks inappropriate to say that tickets are saved in cache.
> OTOH, "ticket" can be seen a correct wording if speaking in terms
> of NewSessionTicket ticket field, or in contrast to "session id"
> synthesized by OpenSSL for the SSL_OP_NO_TICKET case in TLSv1.3.
> In that sense, I'm fine with using "ticket" (not to say changing
> "ticket" to "session" or "session state" brings a tautology).
> However this looks not so important to spend more time on this,
> I'm fine with either case.
Sure, it would be more correct to say something like "OpenSSL
tries to save sessions into session cache while using tickets for
stateless session resumption" (mostly borrowed from
SSL_OP_NO_TICKET documentation in OpenSSL 1.0.2[1]). I've used
"tickets" instead of "sessions using tickets for stateless session
resumption", as it's clearly shorter and only slightly less correct.
[1] https://www.openssl.org/docs/man1.0.2/man3/SSL_set_options.html
Updated with the above wording for clarity (still with the same
summary line though, for simplicity):
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1664290542 -10800
# Tue Sep 27 17:55:42 2022 +0300
# Node ID e6b5a2aa0dd91a7f497014359e19458c78f480b3
# Parent a423e314c22fe99fe9faf28f033c266426993105
SSL: disabled saving tickets to session cache.
OpenSSL tries to save TLSv1.3 sessions into session cache even when using
tickets for stateless session resumption, "because some applications just
want to know about the creation of a session". To avoid trashing session
cache with useless data, we do not save such sessions now.
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -3818,6 +3818,23 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_
ngx_ssl_session_cache_t *cache;
u_char buf[NGX_SSL_MAX_SESSION_SIZE];
+#ifdef TLS1_3_VERSION
+
+ /*
+ * OpenSSL tries to save TLSv1.3 sessions into session cache
+ * even when using tickets for stateless session resumption,
+ * "because some applications just want to know about the creation
+ * of a session"; do not cache such sessions
+ */
+
+ if (SSL_version(ssl_conn) == TLS1_3_VERSION
+ && (SSL_get_options(ssl_conn) & SSL_OP_NO_TICKET) == 0)
+ {
+ return 0;
+ }
+
+#endif
+
len = i2d_SSL_SESSION(sess, NULL);
/* do not cache too big session */
--
Maxim Dounin
http://mdounin.ru/
More information about the nginx-devel
mailing list