Align TLS 1.2 and 1.3 server session validity checks.
Having that logic in two different places is a nuisance when we go to
add new checks like resumption stuff. Along the way, this adds missing
tests for the ClientHello cipher/session consistency check. (We'll
eventually get it for free once the cipher/resumption change is
unblocked, but get this working in the meantime.)
This also fixes a bug where the session validity checks happened in the
wrong order relative to whether tickets_supported or renew_ticket was
looked at. Fix that by lifting that logic closer to the handshake.
Change-Id: I3f4b59cfe01064f9125277dc5834e62a36e64aae
Reviewed-on: https://boringssl-review.googlesource.com/12230
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/ssl_session.c b/ssl/ssl_session.c
index 9f61a5d..faf155c 100644
--- a/ssl/ssl_session.c
+++ b/ssl/ssl_session.c
@@ -633,6 +633,18 @@
return session->timeout > (long)now.tv_sec - session->time;
}
+int ssl_session_is_resumable(const SSL *ssl, const SSL_SESSION *session) {
+ return ssl_session_is_context_valid(ssl, session) &&
+ /* The session must not be expired. */
+ ssl_session_is_time_valid(ssl, session) &&
+ /* Only resume if the session's version matches the negotiated
+ * version. */
+ ssl->version == session->ssl_version &&
+ /* Only resume if the session's cipher is still valid under the
+ * current configuration. */
+ ssl_is_valid_cipher(ssl, session->cipher);
+}
+
/* ssl_lookup_session looks up |session_id| in the session cache and sets
* |*out_session| to an |SSL_SESSION| object if found. The caller takes
* ownership of the result. */
@@ -693,15 +705,8 @@
}
}
- if (session == NULL) {
- return ssl_session_success;
- }
-
- if (!ssl_session_is_context_valid(ssl, session)) {
- /* The client did not offer a suitable ticket or session ID. */
- SSL_SESSION_free(session);
- session = NULL;
- } else if (!ssl_session_is_time_valid(ssl, session)) {
+ if (session != NULL &&
+ !ssl_session_is_time_valid(ssl, session)) {
/* The session was from the cache, so remove it. */
SSL_CTX_remove_session(ssl->initial_ctx, session);
SSL_SESSION_free(session);
@@ -713,8 +718,8 @@
}
enum ssl_session_result_t ssl_get_prev_session(
- SSL *ssl, SSL_SESSION **out_session, int *out_send_ticket,
- const struct ssl_early_callback_ctx *ctx) {
+ SSL *ssl, SSL_SESSION **out_session, int *out_tickets_supported,
+ int *out_renew_ticket, const struct ssl_early_callback_ctx *ctx) {
/* This is used only by servers. */
assert(ssl->server);
SSL_SESSION *session = NULL;
@@ -743,11 +748,8 @@
}
*out_session = session;
- if (session != NULL) {
- *out_send_ticket = renew_ticket;
- } else {
- *out_send_ticket = tickets_supported;
- }
+ *out_tickets_supported = tickets_supported;
+ *out_renew_ticket = renew_ticket;
return ssl_session_success;
}