Merge remote-tracking branch 'restricted/pr/584' into baremetal-proposed

* restricted/pr/584: (140 commits)
  Remove superfluous new line in x509.c
  Add comment about X.509 name comparison of buffer with itself
  [Fixup] Add missing PK release call in Cert Verify parsing
  Fix guard controlling whether nested acquire calls are allowed
  Add X.509 CRT test for nested calls for CRT frame / PK acquire
  Don't return threading error on release()-without-acquire() calls
  Don't allow nested CRT acquire()-calls if MBEDTLS_X509_ALWAYS_FLUSH
  Make X.509 CRT cache reference counting unconditional
  Remove memory buffer alloc from i386 test in all.sh
  Don't mention pk_sign() in the context of public-key contexts
  Don't use assertion for failures of mbedtls_x509_crt_x_acquire()
  Fix copy pasta in x509_crt.h
  Reference copy-less versions of X.509 CRT frame/PK getters
  x509_crt.c: Add blank line to increase readability
  [FIXUP] Fix bug in ASN.1 traversal of silently ignored tag
  [FIXUP] Fix typo in declaration of mbedtls_x509_memcasecmp()
  Move signature-info extraction out of MBEDTLS_X509_REMOVE_INFO
  Fix certificate validity checking logic to work with !TIME_DATE
  Simplify X.509 CRT version check in UID parsing
  Remove unused variable warning in on-demand X.509 parsing
  ...
diff --git a/configs/baremetal.h b/configs/baremetal.h
index 175f48a..12fa136 100644
--- a/configs/baremetal.h
+++ b/configs/baremetal.h
@@ -79,6 +79,12 @@
 #define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
 #define MBEDTLS_SSL_DTLS_CONNECTION_ID
 
+/* Compile-time fixed parts of the SSL configuration */
+#define MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET \
+    MBEDTLS_SSL_EXTENDED_MS_ENABLED
+#define MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET \
+    MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED
+
 /* X.509 CRT parsing */
 #define MBEDTLS_X509_USE_C
 #define MBEDTLS_X509_CRT_PARSE_C
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 67cb778..88f4701 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -650,6 +650,13 @@
 #error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
 #endif
 
+#if ( defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) &&            \
+      !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) ) || \
+    ( !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) &&           \
+      defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) )
+#define "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET and MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET must be defined together."
+#endif
+
 #if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
 #error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
 #endif
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 0d4d30a..796b0bb 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -3486,6 +3486,25 @@
 
 /* \} name SECTION: Customisation configuration options */
 
+/**
+ * \name SECTION: Compile-time SSL configuration
+ *
+ * This section allows to fix parts of the SSL configuration
+ * at compile-time. If a field is fixed at compile-time, the
+ * corresponding SSL configuration API `mbedtls_ssl_conf_xxx()`
+ * is removed.
+ *
+ * This can be used on constrained systems to reduce code-size.
+ * \{
+ */
+
+/* ExtendedMasterSecret extension
+ * The following two options must be set/unset simultaneously. */
+//#define MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET MBEDTLS_SSL_EXTENDED_MS_ENABLED
+//#define MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET MBEDTLS_SSL_EXTENDED_MS_ENFORCE_DISABLED
+
+/* \} SECTION: Compile-time SSL configuration */
+
 /* Target and application specific configurations
  *
  * Allow user to override any previous default.
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index eeb03e1..b517089 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1060,10 +1060,14 @@
     unsigned int encrypt_then_mac : 1 ; /*!< negotiate encrypt-then-mac?    */
 #endif
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET)
     unsigned int extended_ms : 1;   /*!< negotiate extended master secret?  */
+#endif /* !MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
     unsigned int enforce_extended_master_secret : 1; /*!< enforce the usage
                                                       *   of extended master
                                                       *   secret            */
+#endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */
 #endif
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
     unsigned int anti_replay : 1;   /*!< detect and prevent replay?         */
@@ -1094,7 +1098,6 @@
 #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
 };
 
-
 struct mbedtls_ssl_context
 {
     const mbedtls_ssl_config *conf; /*!< configuration information          */
@@ -2842,6 +2845,7 @@
 #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET)
 /**
  * \brief           Enable or disable Extended Master Secret negotiation.
  *                  (Default: MBEDTLS_SSL_EXTENDED_MS_ENABLED)
@@ -2850,11 +2854,20 @@
  *                  protocol, and should not cause any interoperability issue
  *                  (used only if the peer supports it too).
  *
+ * \note            On constrained systems, this option can also be
+ *                  fixed at compile-time by defining the constant
+ *                  MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET
+ *                  as MBEDTLS_SSL_EXTENDED_MS_ENABLED or
+ *                  MBEDTLS_SSL_EXTENDED_MS_DISABLED.
+ *
  * \param conf      SSL configuration
- * \param ems       MBEDTLS_SSL_EXTENDED_MS_ENABLED or MBEDTLS_SSL_EXTENDED_MS_DISABLED
+ * \param ems       MBEDTLS_SSL_EXTENDED_MS_ENABLED or
+ *                  MBEDTLS_SSL_EXTENDED_MS_DISABLED
  */
 void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems );
+#endif /* !MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET */
 
+#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
 /**
  * \brief           Enable or disable Extended Master Secret enforcing.
  *                  (Default: MBEDTLS_SSL_EXTENDED_MS_ENFORCE_DISABLED)
@@ -2871,9 +2884,17 @@
  * \param conf      Currently used SSL configuration struct.
  * \param ems_enf   MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED or
  *                  MBEDTLS_SSL_EXTENDED_MS_ENFORCE_DISABLED
+
+ * \note            On constrained systems, this option can also be
+ *                  fixed at compile-time by defining the constant
+ *                  MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET
+ *                  as MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED or
+ *                  MBEDTLS_SSL_EXTENDED_MS_ENFORCE_DISABLED.
+ *
  */
 void mbedtls_ssl_conf_extended_master_secret_enforce( mbedtls_ssl_config *conf,
                                                       char ems_enf );
+#endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
 
 #if defined(MBEDTLS_ARC4_C)
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 3eb37b8..7009c4f 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -321,6 +321,18 @@
 #define MBEDTLS_SSL_TRANSPORT_ELSE                  /* empty: no other branch */
 #endif /* TLS and/or DTLS */
 
+/* Check if the use of the ExtendedMasterSecret extension
+ * is enforced at compile-time. If so, we don't need to
+ * track its status in the handshake parameters. */
+#if defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET)         && \
+    defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET) && \
+    MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET ==                  \
+      MBEDTLS_SSL_EXTENDED_MS_ENABLED                        && \
+    MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET ==          \
+      MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED
+#define MBEDTLS_SSL_EXTENDED_MS_ENFORCED
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -505,7 +517,8 @@
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
     int new_session_ticket;             /*!< use NewSessionTicket?    */
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) &&      \
+    !defined(MBEDTLS_SSL_EXTENDED_MS_ENFORCED)
     int extended_ms;                    /*!< use Extended Master Secret? */
 #endif
 
@@ -523,6 +536,24 @@
 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
 };
 
+/*
+ * Getter functions for fields in mbedtls_ssl_handshake_params which
+ * may be statically implied by the configuration and hence be omitted
+ * from the structure.
+ */
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+static inline int mbedtls_ssl_hs_get_extended_ms(
+    mbedtls_ssl_handshake_params const *params )
+{
+#if !defined(MBEDTLS_SSL_EXTENDED_MS_ENFORCED)
+    return( params->extended_ms );
+#else
+    ((void) params);
+    return( MBEDTLS_SSL_EXTENDED_MS_ENABLED );
+#endif /* MBEDTLS_SSL_EXTENDED_MS_ENFORCED */
+}
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
 typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer;
 
 /*
@@ -1048,4 +1079,34 @@
                              mbedtls_ssl_transform *transform,
                              mbedtls_record *rec );
 
+
+/*
+ * Getter functions for fields in mbedtls_ssl_config which may
+ * be fixed at compile time via one of MBEDTLS_SSL_SSL_CONF_XXX.
+ */
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+static inline unsigned int mbedtls_ssl_conf_get_ems(
+    mbedtls_ssl_config const *conf )
+{
+#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET)
+    return( conf->extended_ms );
+#else
+    ((void) conf);
+    return( MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET );
+#endif /* MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET */
+}
+
+static inline unsigned int mbedtls_ssl_conf_get_ems_enforced(
+    mbedtls_ssl_config const *conf )
+{
+#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
+    return( conf->enforce_extended_master_secret );
+#else
+    ((void) conf);
+    return( MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET );
+#endif /* MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */
+}
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
 #endif /* ssl_internal.h */
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 0a1fce8..0f75b1c 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -590,7 +590,8 @@
 
     *olen = 0;
 
-    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
+    if( mbedtls_ssl_conf_get_ems( ssl->conf ) ==
+          MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
         ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
     {
         return;
@@ -1328,7 +1329,8 @@
                                          const unsigned char *buf,
                                          size_t len )
 {
-    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
+    if( mbedtls_ssl_conf_get_ems( ssl->conf ) ==
+          MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
         ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
         len != 0 )
     {
@@ -1339,9 +1341,6 @@
     }
 
     ((void) buf);
-
-    ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
-
     return( 0 );
 }
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
@@ -1602,6 +1601,9 @@
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
     int renegotiation_info_seen = 0;
 #endif
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    int extended_ms_seen = 0;
+#endif
     int handshake_failure = 0;
     const mbedtls_ssl_ciphersuite_t *suite_info;
 
@@ -1982,6 +1984,7 @@
             {
                 return( ret );
             }
+            extended_ms_seen = 1;
 
             break;
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
@@ -2089,14 +2092,22 @@
      * Check if extended master secret is being enforced
      */
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED &&
-        ssl->conf->enforce_extended_master_secret ==
-        MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED &&
-        ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED )
+    if( mbedtls_ssl_conf_get_ems( ssl->conf ) ==
+        MBEDTLS_SSL_EXTENDED_MS_ENABLED )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Peer not offering extended master "
+        if( extended_ms_seen )
+        {
+#if !defined(MBEDTLS_SSL_EXTENDED_MS_ENFORCED)
+            ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
+#endif /* !MBEDTLS_SSL_EXTENDED_MS_ENFORCED */
+        }
+        else if( mbedtls_ssl_conf_get_ems_enforced( ssl->conf ) ==
+                 MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "Peer not offering extended master "
                                     "secret, while it is enforced") );
-        handshake_failure = 1;
+            handshake_failure = 1;
+        }
     }
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 40f8e06..94b4d73 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -567,12 +567,6 @@
 
     ((void) buf);
 
-    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED &&
-        ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
-    {
-        ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
-    }
-
     return( 0 );
 }
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
@@ -1320,6 +1314,9 @@
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
     int renegotiation_info_seen = 0;
 #endif
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    int extended_ms_seen = 0;
+#endif
     int handshake_failure = 0;
     const int *ciphersuites;
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
@@ -1947,6 +1944,7 @@
                 ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size );
                 if( ret != 0 )
                     return( ret );
+                extended_ms_seen = 1;
                 break;
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
 
@@ -2093,14 +2091,22 @@
      * Check if extended master secret is being enforced
      */
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED &&
-        ssl->conf->enforce_extended_master_secret ==
-        MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED &&
-        ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED )
+    if( mbedtls_ssl_conf_get_ems( ssl->conf ) ==
+          MBEDTLS_SSL_EXTENDED_MS_ENABLED )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Peer not offering extended master "
-                                    "secret, while it is enforced") );
-        handshake_failure = 1;
+        if( extended_ms_seen )
+        {
+#if !defined(MBEDTLS_SSL_EXTENDED_MS_ENFORCED)
+            ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
+#endif /* !MBEDTLS_SSL_EXTENDED_MS_ENFORCED */
+        }
+        else if( mbedtls_ssl_conf_get_ems_enforced( ssl->conf ) ==
+                 MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "Peer not offering extended master "
+                                        "secret, while it is enforced") );
+            handshake_failure = 1;
+        }
     }
 #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
 
@@ -2320,7 +2326,8 @@
 {
     unsigned char *p = buf;
 
-    if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
+    if( mbedtls_ssl_hs_get_extended_ms( ssl->handshake )
+          == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
         ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
     {
         *olen = 0;
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index f1075cb..4c1a5c5 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1273,7 +1273,8 @@
                                                   handshake->pmslen );
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-    if( handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
+    if( mbedtls_ssl_hs_get_extended_ms( handshake )
+          == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
     {
         unsigned char session_hash[48];
         size_t hash_len;
@@ -8621,17 +8622,20 @@
 #endif
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET)
 void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems )
 {
     conf->extended_ms = ems;
 }
-
+#endif /* !MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET */
+#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
 void mbedtls_ssl_conf_extended_master_secret_enforce( mbedtls_ssl_config *conf,
                                                         char ems_enf )
 {
     conf->enforce_extended_master_secret = ems_enf;
 }
-#endif
+#endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */
+#endif /* !MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
 
 #if defined(MBEDTLS_ARC4_C)
 void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 )
@@ -10728,9 +10732,13 @@
 #endif
 
 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET)
     conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
+#endif /* !MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET */
+#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
     conf->enforce_extended_master_secret =
         MBEDTLS_SSL_EXTENDED_MS_ENFORCE_DISABLED;
+#endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */
 #endif
 
 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c
index 3905383..e62341d 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -2594,6 +2594,22 @@
     }
 #endif /* MBEDTLS_PLATFORM_GMTIME_R_ALT */
 
+#if defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET)
+    if( strcmp( "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET */
+
+#if defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
+    if( strcmp( "MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */
+
     /* If the symbol is not found, return an error */
     return( 1 );
 }
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index d859101..9828576 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -245,7 +245,9 @@
 #define USAGE_FALLBACK ""
 #endif
 
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) &&       \
+    !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) && \
+    !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
 #define USAGE_EMS \
     "    extended_ms=0/1     default: (library default: on)\n" \
     "    enforce_extended_master_secret=0/1 default: (library default: off)\n"
@@ -1706,7 +1708,9 @@
         mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
 #endif
 
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) &&       \
+    !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) && \
+    !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
     if( opt.extended_ms != DFL_EXTENDED_MS )
         mbedtls_ssl_conf_extended_master_secret( &conf, opt.extended_ms );
     if( opt.enforce_extended_master_secret != DFL_EXTENDED_MS_ENFORCE )
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 8488bad..8534dc2 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -344,7 +344,9 @@
 #define USAGE_DTLS ""
 #endif
 
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) &&       \
+    !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) && \
+    !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
 #define USAGE_EMS \
     "    extended_ms=0/1     default: (library default: on)\n" \
     "    enforce_extended_master_secret=0/1 default: (library default: off)\n"
@@ -2506,7 +2508,9 @@
         mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
 #endif
 
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) &&       \
+    !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) && \
+    !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
     if( opt.extended_ms != DFL_EXTENDED_MS )
         mbedtls_ssl_conf_extended_master_secret( &conf, opt.extended_ms );
     if( opt.enforce_extended_master_secret != DFL_EXTENDED_MS_ENFORCE )
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 3dd69a5..7bcba24 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -503,6 +503,49 @@
     fi
 }
 
+# Strip off a particular parameter from the command line
+# and return its value.
+# Parameter 1: Command line parameter to strip off
+# ENV I/O: CMD command line to search and modify
+extract_cmdline_argument() {
+    __ARG=$(echo "$CMD" | sed -n "s/^.* $1=\([^ ]*\).*$/\1/p")
+    CMD=$(echo "$CMD" | sed "s/$1=\([^ ]*\)//")
+}
+
+# Check compatibility of the ssl_client2/ssl_server2 command-line
+# with a particular compile-time configurable option.
+# Parameter 1: Command-line argument (e.g. extended_ms)
+# Parameter 2: Corresponding compile-time configuration
+#              (e.g. MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET)
+# ENV I/O: CMD command line to search and modify
+#          SKIP_NEXT set to "YES" on a mismatch
+check_cmdline_param_compat() {
+    __VAL="$( get_config_value_or_default "$2" )"
+    if [ ! -z "$__VAL" ]; then
+        extract_cmdline_argument "$1"
+        if [ ! -z "$__ARG" ] && [ "$__ARG" != "$__VAL" ]; then
+            SKIP_NEXT="YES"
+        fi
+    fi
+}
+
+# Go through all options that can be hardcoded at compile-time and
+# detect whether the command line configures them in a conflicting
+# way. If so, skip the test. Otherwise, remove the corresponding
+# entry.
+# Parameter 1: Command line to inspect
+# Output: Modified command line
+# ENV I/O: SKIP_TEST set to 1 on mismatch.
+check_cmdline_compat() {
+    CMD="$1"
+
+    # ExtendedMasterSecret configuration
+    check_cmdline_param_compat "extended_ms" \
+                               "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET"
+    check_cmdline_param_compat "enforce_extended_master_secret" \
+                               "MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET"
+}
+
 # Usage: run_test name [-p proxy_cmd] srv_cmd cli_cmd cli_exit [option [...]]
 # Options:  -s pattern  pattern that must be present in server output
 #           -c pattern  pattern that must be present in client output
@@ -531,14 +574,6 @@
         SKIP_NEXT="YES"
     fi
 
-    # should we skip?
-    if [ "X$SKIP_NEXT" = "XYES" ]; then
-        SKIP_NEXT="NO"
-        echo "SKIP"
-        SKIPS=$(( $SKIPS + 1 ))
-        return
-    fi
-
     # does this test use a proxy?
     if [ "X$1" = "X-p" ]; then
         PXY_CMD="$2"
@@ -553,6 +588,12 @@
     CLI_EXPECT="$3"
     shift 3
 
+    check_cmdline_compat "$SRV_CMD"
+    SRV_CMD="$CMD"
+
+    check_cmdline_compat "$CLI_CMD"
+    CLI_CMD="$CMD"
+
     # Check if test uses files
     TEST_USES_FILES=$(echo "$SRV_CMD $CLI_CMD" | grep "\.\(key\|crt\|pem\)" )
     if [ ! -z "$TEST_USES_FILES" ]; then
@@ -1836,8 +1877,8 @@
 # Tests for Extended Master Secret extension
 
 run_test    "Extended Master Secret: default (not enforcing)" \
-            "$P_SRV debug_level=3" \
-            "$P_CLI debug_level=3" \
+            "$P_SRV debug_level=3 extended_ms=1 enforce_extended_master_secret=0 " \
+            "$P_CLI debug_level=3 extended_ms=1 enforce_extended_master_secret=0" \
             0 \
             -c "client hello, adding extended_master_secret extension" \
             -s "found extended master secret extension" \
@@ -1847,8 +1888,8 @@
             -s "session hash for extended master secret"
 
 run_test    "Extended Master Secret: both enabled, both enforcing" \
-            "$P_SRV debug_level=3 enforce_extended_master_secret=1" \
-            "$P_CLI debug_level=3 enforce_extended_master_secret=1" \
+            "$P_SRV debug_level=3 extended_ms=1 enforce_extended_master_secret=1" \
+            "$P_CLI debug_level=3 extended_ms=1 enforce_extended_master_secret=1" \
             0 \
             -c "client hello, adding extended_master_secret extension" \
             -s "found extended master secret extension" \
@@ -1858,8 +1899,8 @@
             -s "session hash for extended master secret"
 
 run_test    "Extended Master Secret: both enabled, client enforcing" \
-            "$P_SRV debug_level=3 enforce_extended_master_secret=0" \
-            "$P_CLI debug_level=3 enforce_extended_master_secret=1" \
+            "$P_SRV debug_level=3 extended_ms=1 enforce_extended_master_secret=0" \
+            "$P_CLI debug_level=3 extended_ms=1 enforce_extended_master_secret=1" \
             0 \
             -c "client hello, adding extended_master_secret extension" \
             -s "found extended master secret extension" \
@@ -1869,8 +1910,8 @@
             -s "session hash for extended master secret"
 
 run_test    "Extended Master Secret: both enabled, server enforcing" \
-            "$P_SRV debug_level=3 enforce_extended_master_secret=1" \
-            "$P_CLI debug_level=3 enforce_extended_master_secret=0" \
+            "$P_SRV debug_level=3 extended_ms=1 enforce_extended_master_secret=1" \
+            "$P_CLI debug_level=3 extended_ms=1 enforce_extended_master_secret=0" \
             0 \
             -c "client hello, adding extended_master_secret extension" \
             -s "found extended master secret extension" \
@@ -1880,7 +1921,7 @@
             -s "session hash for extended master secret"
 
 run_test    "Extended Master Secret: client enabled, server disabled, client enforcing" \
-            "$P_SRV debug_level=3 extended_ms=0" \
+            "$P_SRV debug_level=3 extended_ms=0 enforce_extended_master_secret=0" \
             "$P_CLI debug_level=3 extended_ms=1 enforce_extended_master_secret=1" \
             1 \
             -c "client hello, adding extended_master_secret extension" \
@@ -1891,7 +1932,7 @@
 
 run_test    "Extended Master Secret enforced: client disabled, server enabled, server enforcing" \
             "$P_SRV debug_level=3 extended_ms=1 enforce_extended_master_secret=1" \
-            "$P_CLI debug_level=3 extended_ms=0" \
+            "$P_CLI debug_level=3 extended_ms=0 enforce_extended_master_secret=0" \
             1 \
             -C "client hello, adding extended_master_secret extension" \
             -S "found extended master secret extension" \
@@ -1900,8 +1941,8 @@
             -s "Peer not offering extended master secret, while it is enforced"
 
 run_test    "Extended Master Secret: client enabled, server disabled, not enforcing" \
-            "$P_SRV debug_level=3 extended_ms=0" \
-            "$P_CLI debug_level=3 extended_ms=1" \
+            "$P_SRV debug_level=3 extended_ms=0 enforce_extended_master_secret=0" \
+            "$P_CLI debug_level=3 extended_ms=1 enforce_extended_master_secret=0" \
             0 \
             -c "client hello, adding extended_master_secret extension" \
             -s "found extended master secret extension" \
@@ -1911,8 +1952,8 @@
             -S "session hash for extended master secret"
 
 run_test    "Extended Master Secret: client disabled, server enabled, not enforcing" \
-            "$P_SRV debug_level=3 extended_ms=1" \
-            "$P_CLI debug_level=3 extended_ms=0" \
+            "$P_SRV debug_level=3 extended_ms=1 enforce_extended_master_secret=0" \
+            "$P_CLI debug_level=3 extended_ms=0 enforce_extended_master_secret=0" \
             0 \
             -C "client hello, adding extended_master_secret extension" \
             -S "found extended master secret extension" \
@@ -1922,8 +1963,8 @@
             -S "session hash for extended master secret"
 
 run_test    "Extended Master Secret: client disabled, server disabled" \
-            "$P_SRV debug_level=3 extended_ms=0" \
-            "$P_CLI debug_level=3 extended_ms=0" \
+            "$P_SRV debug_level=3 extended_ms=0 enforce_extended_master_secret=0" \
+            "$P_CLI debug_level=3 extended_ms=0 enforce_extended_master_secret=0" \
             0 \
             -C "client hello, adding extended_master_secret extension" \
             -S "found extended master secret extension" \
@@ -1934,8 +1975,8 @@
 
 requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Extended Master Secret: client SSLv3, server enabled" \
-            "$P_SRV debug_level=3 min_version=ssl3" \
-            "$P_CLI debug_level=3 force_version=ssl3" \
+            "$P_SRV debug_level=3 min_version=ssl3 extended_ms=1 enforce_extended_master_secret=0" \
+            "$P_CLI debug_level=3 force_version=ssl3 extended_ms=1  enforce_extended_master_secret=0" \
             0 \
             -C "client hello, adding extended_master_secret extension" \
             -S "found extended master secret extension" \
@@ -1946,8 +1987,8 @@
 
 requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Extended Master Secret: client enabled, server SSLv3" \
-            "$P_SRV debug_level=3 force_version=ssl3" \
-            "$P_CLI debug_level=3 min_version=ssl3" \
+            "$P_SRV debug_level=3 force_version=ssl3 extended_ms=1 enforce_extended_master_secret=0" \
+            "$P_CLI debug_level=3 min_version=ssl3 extended_ms=1  enforce_extended_master_secret=0" \
             0 \
             -c "client hello, adding extended_master_secret extension" \
             -S "found extended master secret extension" \