diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/algorithms/ciphersuites.c | 21 | ||||
-rw-r--r-- | lib/gnutls_int.h | 1 | ||||
-rw-r--r-- | lib/handshake.c | 9 | ||||
-rw-r--r-- | lib/priority.c | 4 | ||||
-rw-r--r-- | lib/priority_options.gperf | 1 |
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 |