summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/algorithms/ciphersuites.c21
-rw-r--r--lib/gnutls_int.h1
-rw-r--r--lib/handshake.c9
-rw-r--r--lib/priority.c4
-rw-r--r--lib/priority_options.gperf1
5 files changed, 35 insertions, 1 deletions
diff --git a/lib/algorithms/ciphersuites.c b/lib/algorithms/ciphersuites.c
index 02023ce2a9..ac1fdf9f41 100644
--- a/lib/algorithms/ciphersuites.c
+++ b/lib/algorithms/ciphersuites.c
@@ -1405,6 +1405,14 @@ const char *gnutls_cipher_suite_info(size_t idx,
continue; \
}
+#define CIPHER_CHECK(algo) \
+ if (session->internals.priorities->force_etm && !have_etm) { \
+ const cipher_entry_st *_cipher; \
+ _cipher = cipher_to_entry(algo); \
+ if (_cipher == NULL || _gnutls_cipher_type(_cipher) == CIPHER_BLOCK) \
+ continue; \
+ }
+
#define KX_SRP_CHECKS(kx, action) \
if (kx == GNUTLS_KX_SRP_RSA || kx == GNUTLS_KX_SRP_DSS) { \
if (!_gnutls_get_cred(session, GNUTLS_CRD_SRP)) { \
@@ -1450,11 +1458,20 @@ _gnutls_figure_common_ciphersuite(gnutls_session_t session,
gnutls_credentials_type_t cred_type = GNUTLS_CRD_CERTIFICATE; /* default for TLS1.3 */
unsigned int no_cert_found = 0;
const gnutls_group_entry_st *sgroup = NULL;
+ gnutls_ext_priv_data_t epriv;
+ unsigned have_etm = 0;
if (version == NULL) {
return gnutls_assert_val(GNUTLS_E_NO_CIPHER_SUITES);
}
+ /* we figure whether etm is negotiated by checking the raw extension data
+ * because we only set (security_params) EtM to true only after the ciphersuite is
+ * negotiated. */
+ ret = _gnutls_hello_ext_get_priv(session, GNUTLS_EXTENSION_ETM, &epriv);
+ if (ret >= 0 && ((intptr_t)epriv) != 0)
+ have_etm = 1;
+
/* If we didn't receive the supported_groups extension, then
* we should assume that SECP256R1 is supported; that is required
* by RFC4492, probably to allow SSLv2 hellos negotiate elliptic curve
@@ -1474,6 +1491,8 @@ _gnutls_figure_common_ciphersuite(gnutls_session_t session,
kx = peer_clist->entry[i]->kx_algorithm;
+ CIPHER_CHECK(peer_clist->entry[i]->block_algorithm);
+
if (!version->tls13_sem)
cred_type = _gnutls_map_kx_get_cred(kx, 1);
@@ -1510,6 +1529,8 @@ _gnutls_figure_common_ciphersuite(gnutls_session_t session,
for (j = 0; j < session->internals.priorities->cs.size; j++) {
VERSION_CHECK(session->internals.priorities->cs.entry[j]);
+ CIPHER_CHECK(session->internals.priorities->cs.entry[j]->block_algorithm);
+
for (i = 0; i < peer_clist->size; i++) {
_gnutls_debug_log("checking %.2x.%.2x (%s) for compatibility\n",
(unsigned)peer_clist->entry[i]->id[0],
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 320c394d18..0db05af163 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -900,6 +900,7 @@ struct gnutls_priority_st {
bool no_tickets;
bool have_cbc;
bool have_psk;
+ bool force_etm;
unsigned int additional_verify_flags;
/* TLS_FALLBACK_SCSV */
diff --git a/lib/handshake.c b/lib/handshake.c
index 30e229f3d0..278769e2f8 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -1825,7 +1825,6 @@ read_server_hello(gnutls_session_t session,
*/
if (!vers->tls13_sem &&
client_check_if_resuming(session, session_id, session_id_len) == 0) {
-
ret =
_gnutls_parse_hello_extensions(session, GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO,
GNUTLS_EXT_MANDATORY,
@@ -1878,6 +1877,14 @@ read_server_hello(gnutls_session_t session,
if (ret < 0)
return gnutls_assert_val(ret);
+ /* check if EtM is required */
+ if (!vers->tls13_sem && session->internals.priorities->force_etm && !session->security_parameters.etm) {
+ const cipher_entry_st *cipher = cipher_to_entry(session->security_parameters.cs->block_algorithm);
+ if (_gnutls_cipher_type(cipher) == CIPHER_BLOCK)
+ return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
+ }
+
+
ret =
_gnutls_parse_hello_extensions(session,
ext_parse_flag,
diff --git a/lib/priority.c b/lib/priority.c
index 1ebd6b4695..a749678580 100644
--- a/lib/priority.c
+++ b/lib/priority.c
@@ -809,6 +809,10 @@ static void enable_no_etm(gnutls_priority_t c)
{
c->_no_etm = 1;
}
+static void enable_force_etm(gnutls_priority_t c)
+{
+ c->force_etm = 1;
+}
static void enable_no_tickets(gnutls_priority_t c)
{
c->no_tickets = 1;
diff --git a/lib/priority_options.gperf b/lib/priority_options.gperf
index 44968d4327..a955ec85e6 100644
--- a/lib/priority_options.gperf
+++ b/lib/priority_options.gperf
@@ -10,6 +10,7 @@ DUMBFW, enable_dumbfw
NO_EXTENSIONS, enable_no_extensions
NO_TICKETS, enable_no_tickets
NO_ETM, enable_no_etm
+FORCE_ETM, enable_force_etm
NO_SESSION_HASH, enable_no_ext_master_secret
STATELESS_COMPRESSION, dummy_func
VERIFY_ALLOW_BROKEN, enable_verify_allow_broken