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;
 }