diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-06-23 13:24:48 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-07-07 07:37:13 +0000 |
commit | 9fbea5e8c41d0d27c0e64923ce22bca0f62b110d (patch) | |
tree | b3667ac1c1a77c49c3026eb7507d7149724e5875 | |
parent | 038c6263f10ba413274318055e12ee57cb6bced8 (diff) | |
download | gnutls-9fbea5e8c41d0d27c0e64923ce22bca0f62b110d.tar.gz |
handshake: simplified signature algorithm list generation
Similarly to ciphersuites, that also utilizes a cache of signature algorithms
on the priority structure which is used to quickly generate the signature
algorithm list.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r-- | lib/algorithms.h | 3 | ||||
-rw-r--r-- | lib/algorithms/sign.c | 10 | ||||
-rw-r--r-- | lib/auth/cert.c | 9 | ||||
-rw-r--r-- | lib/ext/signature.c | 59 | ||||
-rw-r--r-- | lib/ext/signature.h | 3 | ||||
-rw-r--r-- | lib/gnutls_int.h | 12 | ||||
-rw-r--r-- | lib/priority.c | 26 |
7 files changed, 56 insertions, 66 deletions
diff --git a/lib/algorithms.h b/lib/algorithms.h index 4a4f504ced..52d7b2569b 100644 --- a/lib/algorithms.h +++ b/lib/algorithms.h @@ -33,6 +33,9 @@ #define IS_EC(x) (((x)==GNUTLS_PK_ECDSA)||((x)==GNUTLS_PK_ECDHX)) +#define TLS_SIGN_AID_UNKNOWN {255, 255} +#define HAVE_UNKNOWN_SIGAID(aid) ((aid)->sign_algorithm == 255 && (aid)->hash_algorithm == 255) + /* Functions for version handling. */ const version_entry_st *version_to_entry(gnutls_protocol_t c); const version_entry_st *_gnutls_version_lowest(gnutls_session_t session); diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c index b64221bcfb..e0fa1ac5b2 100644 --- a/lib/algorithms/sign.c +++ b/lib/algorithms/sign.c @@ -29,9 +29,6 @@ /* signature algorithms; */ -#define TLS_SIGN_AID_UNKNOWN {255, 255} -static const sign_algorithm_st unknown_tls_aid = TLS_SIGN_AID_UNKNOWN; - /* Signature algorithms may be listed twice with a different PK algorithm, * e.g., RSA-PSS-SHA256 can be generated by GNUTLS_PK_RSA or GNUTLS_PK_RSA_PSS. */ @@ -378,8 +375,7 @@ _gnutls_tls_aid_to_sign(const sign_algorithm_st * aid) { gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN; - if (aid->hash_algorithm == unknown_tls_aid.hash_algorithm && - aid->sign_algorithm == unknown_tls_aid.sign_algorithm) + if (HAVE_UNKNOWN_SIGAID(aid)) return ret; GNUTLS_SIGN_LOOP( @@ -404,9 +400,7 @@ const sign_algorithm_st *_gnutls_sign_to_tls_aid(gnutls_sign_algorithm_t GNUTLS_SIGN_ALG_LOOP(ret = &p->aid); - if (ret != NULL && - ret->hash_algorithm == unknown_tls_aid.hash_algorithm && - ret->sign_algorithm == unknown_tls_aid.sign_algorithm) + if (ret != NULL && HAVE_UNKNOWN_SIGAID(ret)) return NULL; return ret; diff --git a/lib/auth/cert.c b/lib/auth/cert.c index 8b26330f5d..f099c52678 100644 --- a/lib/auth/cert.c +++ b/lib/auth/cert.c @@ -1169,19 +1169,12 @@ _gnutls_gen_cert_server_cert_req(gnutls_session_t session, return gnutls_assert_val(ret); if (_gnutls_version_has_selectable_sighash(ver)) { - uint8_t p[MAX_SIGN_ALGO_SIZE]; - ret = - _gnutls_sign_algorithm_write_params(session, p, - MAX_SIGN_ALGO_SIZE); + _gnutls_sign_algorithm_write_params(session, data); if (ret < 0) { gnutls_assert(); return ret; } - - ret = _gnutls_buffer_append_data(data, p, ret); - if (ret < 0) - return gnutls_assert_val(ret); } if (session->security_parameters.cert_type == GNUTLS_CRT_X509 && diff --git a/lib/ext/signature.c b/lib/ext/signature.c index dd99f2e5fa..7a899c8af4 100644 --- a/lib/ext/signature.c +++ b/lib/ext/signature.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2002-2016 Free Software Foundation, Inc. - * Copyright (C) 2015-2016 Red Hat, Inc. + * Copyright (C) 2015-2017 Red Hat, Inc. * * Author: Nikos Mavrogiannopoulos * @@ -73,48 +73,40 @@ typedef struct { */ int _gnutls_sign_algorithm_write_params(gnutls_session_t session, - uint8_t * data, size_t max_data_size) + gnutls_buffer_st * extdata) { - uint8_t *p = data, *len_p; - unsigned int len, i, j; + uint8_t *p; + unsigned int len, i; const sign_algorithm_st *aid; + uint8_t buffer[MAX_ALGOS*2]; - if (max_data_size < - (session->internals.priorities.sign_algo.algorithms * 2) + 2) { - gnutls_assert(); - return GNUTLS_E_SHORT_MEMORY_BUFFER; - } - + p = buffer; len = 0; - len_p = p; - - p += 2; - for (i = j = 0; - j < session->internals.priorities.sign_algo.algorithms; - i += 2, j++) { - aid = - _gnutls_sign_to_tls_aid(session->internals. - priorities.sign_algo. - priority[j]); + for (i=0;i<session->internals.priorities.sigalg.size;i++) { + aid = &session->internals.priorities.sigalg.entry[i]->aid; - if (aid == NULL) + if (HAVE_UNKNOWN_SIGAID(aid)) continue; _gnutls_handshake_log ("EXT[%p]: sent signature algo (%d.%d) %s\n", session, aid->hash_algorithm, aid->sign_algorithm, - gnutls_sign_get_name(session->internals.priorities. - sign_algo.priority[j])); + session->internals.priorities.sigalg.entry[i]->name); + + len += 2; + if (unlikely(len >= sizeof(buffer))) { + len -= 2; + break; + } + *p = aid->hash_algorithm; p++; *p = aid->sign_algorithm; p++; - len += 2; } - _gnutls_write_uint16(len, len_p); - return len + 2; + return _gnutls_buffer_append_data_prefix(extdata, 16, buffer, len); } @@ -239,16 +231,9 @@ _gnutls_signature_algorithm_send_params(gnutls_session_t session, /* this function sends the client extension data */ if (session->security_parameters.entity == GNUTLS_CLIENT && _gnutls_version_has_selectable_sighash(ver)) { - if (session->internals.priorities.sign_algo.algorithms > 0) { - uint8_t p[MAX_SIGN_ALGO_SIZE]; - + if (session->internals.priorities.sigalg.size > 0) { ret = - _gnutls_sign_algorithm_write_params(session, p, - sizeof(p)); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _gnutls_buffer_append_data(extdata, p, ret); + _gnutls_sign_algorithm_write_params(session, extdata); if (ret < 0) return gnutls_assert_val(ret); @@ -336,9 +321,9 @@ _gnutls_session_sign_algo_enabled(gnutls_session_t session, return 0; } - for (i = 0; i < session->internals.priorities.sign_algo.algorithms; + for (i = 0; i < session->internals.priorities.sigalg.size; i++) { - if (session->internals.priorities.sign_algo.priority[i] == + if (session->internals.priorities.sigalg.entry[i]->id == sig) { return 0; /* ok */ } diff --git a/lib/ext/signature.h b/lib/ext/signature.h index 5e59cb3f4f..fe1c1ee1c9 100644 --- a/lib/ext/signature.h +++ b/lib/ext/signature.h @@ -36,8 +36,7 @@ int _gnutls_sign_algorithm_parse_data(gnutls_session_t session, const uint8_t * data, size_t data_size); int _gnutls_sign_algorithm_write_params(gnutls_session_t session, - uint8_t * data, - size_t max_data_size); + gnutls_buffer_st * extdata); int _gnutls_session_sign_algo_enabled(gnutls_session_t session, gnutls_sign_algorithm_t sig); diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 7af4d1e2e6..462126bb06 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -514,8 +514,6 @@ typedef struct { * structures also - see SRP). */ -#define MAX_SIGN_ALGO_SIZE (2 + MAX_ALGOS * 2) - #define MAX_VERIFY_DATA_SIZE 36 /* in SSL 3.0, 12 in TLS 1.0 */ /* auth_info_t structures now MAY contain malloced @@ -650,11 +648,15 @@ typedef struct ciphersuite_list_st { unsigned int size; } ciphersuite_list_st; +typedef struct sign_algo_list_st { + const struct gnutls_sign_entry_st *entry[MAX_ALGOS]; + unsigned int size; +} sign_algo_list_st; + /* For the external api */ struct gnutls_priority_st { priority_st protocol; priority_st cert_type; - priority_st sign_algo; priority_st supported_ecc; /* The following are not necessary to be stored in @@ -663,6 +665,10 @@ struct gnutls_priority_st { priority_st _cipher; priority_st _mac; priority_st _kx; + priority_st _sign_algo; + + /* the supported signature algorithms */ + sign_algo_list_st sigalg; /* the supported ciphersuites */ ciphersuite_list_st cs; diff --git a/lib/priority.c b/lib/priority.c index bc6f4eb842..dcdb46aad0 100644 --- a/lib/priority.c +++ b/lib/priority.c @@ -720,7 +720,7 @@ int check_level(const char *level, gnutls_priority_t priority_cache, func(&priority_cache->_cipher, *pgroups[i].cipher_list); func(&priority_cache->_kx, *pgroups[i].kx_list); func(&priority_cache->_mac, *pgroups[i].mac_list); - func(&priority_cache->sign_algo, *pgroups[i].sign_list); + func(&priority_cache->_sign_algo, *pgroups[i].sign_list); func(&priority_cache->supported_ecc, *pgroups[i].ecc_list); if (pgroups[i].profile != 0) { @@ -1110,6 +1110,7 @@ static void set_ciphersuite_list(gnutls_priority_t priority_cache) { unsigned i, j, z; const gnutls_cipher_suite_entry_st *ce; + const gnutls_sign_entry_st *se; priority_cache->cs.size = 0; @@ -1127,7 +1128,16 @@ static void set_ciphersuite_list(gnutls_priority_t priority_cache) } } } - _gnutls_debug_log("added %d ciphersuites into priority list\n", priority_cache->cs.size); + + for (i = 0; i < priority_cache->_sign_algo.algorithms; i++) { + se = _gnutls_sign_to_entry(priority_cache->_sign_algo.priority[i]); + if (se != NULL && priority_cache->sigalg.size < sizeof(priority_cache->sigalg.entry)/sizeof(priority_cache->sigalg.entry[0])) { + priority_cache->sigalg.entry[priority_cache->sigalg.size++] = se; + } + } + + _gnutls_debug_log("added %d ciphersuites and %d sig algos into priority list\n", + priority_cache->cs.size, priority_cache->sigalg.size); } /** @@ -1272,7 +1282,7 @@ gnutls_priority_init(gnutls_priority_t * priority_cache, protocol_priority); _set_priority(&(*priority_cache)->cert_type, cert_type_priority_default); - _set_priority(&(*priority_cache)->sign_algo, + _set_priority(&(*priority_cache)->_sign_algo, sign_priority_default); _set_priority(&(*priority_cache)->supported_ecc, supported_ecc_normal); @@ -1382,7 +1392,7 @@ gnutls_priority_init(gnutls_priority_t * priority_cache, (&broken_list[i][1], "SIGN-ALL", 8) == 0) { bulk_fn(&(*priority_cache)-> - sign_algo, + _sign_algo, sign_priority_default); } else { if ((algo = @@ -1390,7 +1400,7 @@ gnutls_priority_init(gnutls_priority_t * priority_cache, (&broken_list[i][6])) != GNUTLS_SIGN_UNKNOWN) fn(&(*priority_cache)-> - sign_algo, algo); + _sign_algo, algo); else goto error; } @@ -1697,11 +1707,11 @@ int gnutls_priority_sign_list(gnutls_priority_t pcache, const unsigned int **list) { - if (pcache->sign_algo.algorithms == 0) + if (pcache->_sign_algo.algorithms == 0) return 0; - *list = pcache->sign_algo.priority; - return pcache->sign_algo.algorithms; + *list = pcache->_sign_algo.priority; + return pcache->_sign_algo.algorithms; } /** |