diff options
-rw-r--r-- | lib/algorithms.h | 1 | ||||
-rw-r--r-- | lib/algorithms/ciphers.c | 13 | ||||
-rw-r--r-- | lib/ext/etm.c | 5 | ||||
-rw-r--r-- | lib/gnutls_int.h | 1 | ||||
-rw-r--r-- | lib/gnutls_priority.c | 22 |
5 files changed, 36 insertions, 6 deletions
diff --git a/lib/algorithms.h b/lib/algorithms.h index 1ac4001255..1fe9d4d006 100644 --- a/lib/algorithms.h +++ b/lib/algorithms.h @@ -183,6 +183,7 @@ const gnutls_cipher_suite_entry_st *ciphersuite_to_entry(const uint8_t suite[2]) /* Functions for ciphers. */ const cipher_entry_st *cipher_to_entry(gnutls_cipher_algorithm_t c); +const cipher_entry_st *cipher_name_to_entry(const char *name); inline static cipher_type_t _gnutls_cipher_type(const cipher_entry_st * e) { diff --git a/lib/algorithms/ciphers.c b/lib/algorithms/ciphers.c index 725a1c9ce5..c49f755ddc 100644 --- a/lib/algorithms/ciphers.c +++ b/lib/algorithms/ciphers.c @@ -211,6 +211,19 @@ const cipher_entry_st *cipher_to_entry(gnutls_cipher_algorithm_t c) return NULL; } +const cipher_entry_st * cipher_name_to_entry(const char *name) +{ + GNUTLS_CIPHER_LOOP( + if (strcasecmp(p->name, name) == 0) { + if (p->id == GNUTLS_CIPHER_NULL || _gnutls_cipher_exists(p->id)) + return p; + break; + } + ); + + return NULL; +} + /** * gnutls_cipher_get_block_size: * @algorithm: is an encryption algorithm diff --git a/lib/ext/etm.c b/lib/ext/etm.c index f3a90ee1a9..d77db63eb1 100644 --- a/lib/ext/etm.c +++ b/lib/ext/etm.c @@ -99,7 +99,10 @@ _gnutls_ext_etm_send_params(gnutls_session_t session, /* this function sends the client extension data */ if (session->security_parameters.entity == GNUTLS_CLIENT) { - return GNUTLS_E_INT_RET_0; + if (session->internals.priorities.have_cbc != 0) + return GNUTLS_E_INT_RET_0; + else + return 0; } else { /* server side */ const cipher_entry_st *c; int ret; diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index dd1155a6d3..59cc99fe2b 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -666,6 +666,7 @@ struct gnutls_priority_st { bool allow_wrong_pms; bool no_tickets; bool no_etm; + bool have_cbc; /* Whether stateless compression will be used */ bool stateless_compression; unsigned int additional_verify_flags; diff --git a/lib/gnutls_priority.c b/lib/gnutls_priority.c index 515d237441..06e6cf4991 100644 --- a/lib/gnutls_priority.c +++ b/lib/gnutls_priority.c @@ -667,6 +667,8 @@ int check_level(const char *level, gnutls_priority_t priority_cache, bulk_rmadd_func *func; unsigned profile = 0; unsigned i; + int j; + const cipher_entry_st *centry; if (add) func = _add_priority; @@ -692,6 +694,15 @@ int check_level(const char *level, gnutls_priority_t priority_cache, } SET_LEVEL(pgroups[i].sec_param); /* set DH params level */ priority_cache->no_tickets = pgroups[i].no_tickets; + if (priority_cache->have_cbc == 0) { + for (j=0;(*pgroups[i].cipher_list)[j]!=0;j++) { + centry = cipher_to_entry((*pgroups[i].cipher_list)[j]); + if (centry != NULL && centry->type == CIPHER_BLOCK) { + priority_cache->have_cbc = 1; + break; + } + } + } return 1; } } @@ -1048,6 +1059,7 @@ gnutls_priority_init(gnutls_priority_t * priority_cache, rmadd_func *fn; bulk_rmadd_func *bulk_fn; bulk_rmadd_func *bulk_given_fn; + const cipher_entry_st *centry; if (err_pos) *err_pos = priorities; @@ -1120,11 +1132,11 @@ gnutls_priority_init(gnutls_priority_t * priority_cache, gnutls_mac_get_id(&broken_list[i][1])) != GNUTLS_MAC_UNKNOWN) fn(&(*priority_cache)->mac, algo); - else if ((algo = - gnutls_cipher_get_id(&broken_list[i][1])) - != GNUTLS_CIPHER_UNKNOWN) - fn(&(*priority_cache)->cipher, algo); - else if ((algo = + else if ((centry = cipher_name_to_entry(&broken_list[i][1])) != NULL) { + fn(&(*priority_cache)->cipher, centry->id); + if (centry->type == CIPHER_BLOCK) + (*priority_cache)->have_cbc = 1; + } else if ((algo = gnutls_kx_get_id(&broken_list[i][1])) != GNUTLS_KX_UNKNOWN) fn(&(*priority_cache)->kx, algo); |