summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-06-23 13:24:48 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-07-07 07:37:13 +0000
commit9fbea5e8c41d0d27c0e64923ce22bca0f62b110d (patch)
treeb3667ac1c1a77c49c3026eb7507d7149724e5875
parent038c6263f10ba413274318055e12ee57cb6bced8 (diff)
downloadgnutls-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.h3
-rw-r--r--lib/algorithms/sign.c10
-rw-r--r--lib/auth/cert.c9
-rw-r--r--lib/ext/signature.c59
-rw-r--r--lib/ext/signature.h3
-rw-r--r--lib/gnutls_int.h12
-rw-r--r--lib/priority.c26
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;
}
/**