Do not resume a session if the negotiated protocol version does not match
authorDavid Benjamin <davidben@chromium.org>
Thu, 20 Nov 2014 15:22:40 +0000 (16:22 +0100)
committerEmilia Kasper <emilia@openssl.org>
Thu, 20 Nov 2014 15:31:42 +0000 (16:31 +0100)
the session's version (server).

See also BoringSSL's commit bdf5e72f50e25f0e45e825c156168766d8442dde.

Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
(cherry picked from commit 9e189b9dc10786c755919e6792e923c584c918a1)

CHANGES
ssl/s3_srvr.c

diff --git a/CHANGES b/CHANGES
index 204262c022c7cdbdd7630d114388ce80f3b6c3d7..c3bb94052d764e57b52b6fac2614f6677d86f2c4 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,12 @@
 
  Changes between 1.0.1j and 1.0.1k [xx XXX xxxx]
 
+   *) Do not resume sessions on the server if the negotiated protocol
+      version does not match the session's version. Resuming with a different
+      version, while not strictly forbidden by the RFC, is of questionable
+      sanity and breaks all known clients.
+      [David Benjamin, Emilia Käsper]
+
    *) Tighten handling of the ChangeCipherSpec (CCS) message: reject
       early CCS messages during renegotiation. (Note that because
       renegotiation is encrypted, this early CCS was not exploitable.)
index e71089840242e11a8c3cd6ab41db8e61f46e284b..59ff27138145ba777b2a8d7c7547858170e3f348 100644 (file)
@@ -1051,7 +1051,16 @@ int ssl3_get_client_hello(SSL *s)
        else
                {
                i=ssl_get_prev_session(s, p, j, d + n);
-               if (i == 1)
+               /*
+                * Only resume if the session's version matches the negotiated
+                * version.
+                * RFC 5246 does not provide much useful advice on resumption
+                * with a different protocol version. It doesn't forbid it but
+                * the sanity of such behaviour would be questionable.
+                * In practice, clients do not accept a version mismatch and
+                * will abort the handshake with an error.
+                */
+               if (i == 1 && s->version == s->session->ssl_version)
                        { /* previous session */
                        s->hit=1;
                        }