Do not allow dropping Extended Master Secret extension on renegotiaton

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/12045)
diff --git a/CHANGES.md b/CHANGES.md
index ca60b9c..24fb86f 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -23,6 +23,11 @@
 
 ### Changes between 1.1.1 and 3.0 [xx XXX xxxx]
 
+ * Handshake now fails if Extended Master Secret extension is dropped
+   on renegotiation.
+
+   *Tomas Mraz*
+
  * Dropped interactive mode from the 'openssl' program.  From now on,
    the `openssl` command without arguments is equivalent to `openssl
    help`.
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index 664ad23..9fc6b3a 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -297,6 +297,9 @@
 
 # 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
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 3c02348..9086348 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -1169,13 +1169,26 @@
 
 static int init_ems(SSL *s, unsigned int context)
 {
-    s->s3.flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
+    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