Do not allow dropping Extended Master Secret extension on renegotiaton
authorTomas Mraz <tmraz@fedoraproject.org>
Thu, 4 Jun 2020 09:40:29 +0000 (11:40 +0200)
committerTomas Mraz <tmraz@fedoraproject.org>
Thu, 11 Jun 2020 07:07:28 +0000 (09:07 +0200)
Abort renegotiation if server receives client hello with Extended Master
Secret extension dropped in comparison to the initial session.

Fixes #9754

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12099)

CHANGES
include/openssl/ssl3.h
ssl/statem/extensions.c

diff --git a/CHANGES b/CHANGES
index 8b2fd3f8bdd79a216988d473fb6ac49379d732e7..ae0d23252606aa5c41be1fd55de17cf7a74fcc2a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,10 @@
 
  Changes between 1.1.1g and 1.1.1h [xx XXX xxxx]
 
+  *) Handshake now fails if Extended Master Secret extension is dropped
+     on renegotiation.
+     [Tomas Mraz]
+
   *) The Oracle Developer Studio compiler will start reporting deprecated APIs
 
  Changes between 1.1.1f and 1.1.1g [21 Apr 2020]
index 8d01fcc487651f535db5f5da5d6c8c4e4f0e3580..407db0b5f0aba0492f15730e95c75d8f1539264e 100644 (file)
@@ -292,6 +292,9 @@ extern "C" {
 
 # define TLS1_FLAGS_STATELESS                    0x0800
 
+/* Set if extended master secret extension required on renegotiation */
+# define TLS1_FLAGS_REQUIRED_EXTMS               0x1000
+
 # define SSL3_MT_HELLO_REQUEST                   0
 # define SSL3_MT_CLIENT_HELLO                    1
 # define SSL3_MT_SERVER_HELLO                    2
index 4ef8b417b8207f9d549d342a2b065bde1c9e5c9b..c785ab785d38020adb72d9bd1b484d393e70c4b1 100644 (file)
@@ -1168,14 +1168,26 @@ static int init_etm(SSL *s, unsigned int context)
 
 static int init_ems(SSL *s, unsigned int context)
 {
-    if (!s->server)
+    if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) {
         s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
+        s->s3->flags |= TLS1_FLAGS_REQUIRED_EXTMS;
+    }
 
     return 1;
 }
 
 static int final_ems(SSL *s, unsigned int context, int sent)
 {
+    /*
+     * Check extended master secret extension is not dropped on
+     * renegotiation.
+     */
+    if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS)
+        && (s->s3->flags & TLS1_FLAGS_REQUIRED_EXTMS)) {
+        SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_FINAL_EMS,
+                 SSL_R_INCONSISTENT_EXTMS);
+        return 0;
+    }
     if (!s->server && s->hit) {
         /*
          * Check extended master secret extension is consistent with