summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2018-07-27 11:58:38 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2018-07-27 14:13:35 +0200
commitcb702bd6bc44959760c5a9c837506b0e85e3cd78 (patch)
tree3f953890f0451174b193a107a43b51793503db3e
parentaf86011e4dac677da991c9585ebeb0f1da528cc3 (diff)
downloadgnutls-cb702bd6bc44959760c5a9c837506b0e85e3cd78.tar.gz
ext/key_share: check the validity of server key shares
That is, when generating the public key based on the server's key share, ensure that the algorithms match completely with the key shares the client initially sent. This was detected by the updated traces for TLS1.3 fuzzying. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/crypto-backend.h1
-rw-r--r--lib/ext/key_share.c10
2 files changed, 11 insertions, 0 deletions
diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h
index e410af03e3..ff8f39616e 100644
--- a/lib/crypto-backend.h
+++ b/lib/crypto-backend.h
@@ -194,6 +194,7 @@ typedef struct {
unsigned int pkflags; /* gnutls_pk_flag_t */
unsigned int qbits; /* GNUTLS_PK_DH */
gnutls_ecc_curve_t curve; /* GNUTLS_PK_EC, GNUTLS_PK_ED25519, GNUTLS_PK_GOST* */
+ gnutls_group_t dh_group; /* GNUTLS_PK_DH - used by ext/key_share */
gnutls_gost_paramset_t gost_params; /* GNUTLS_PK_GOST_* */
gnutls_datum_t raw_pub; /* used by x25519 */
gnutls_datum_t raw_priv;
diff --git a/lib/ext/key_share.c b/lib/ext/key_share.c
index 98bb729131..c5b104f9ac 100644
--- a/lib/ext/key_share.c
+++ b/lib/ext/key_share.c
@@ -153,6 +153,7 @@ static int client_gen_key_share(gnutls_session_t session, const gnutls_group_ent
return gnutls_assert_val(ret);
session->key.kshare.dh_params.algo = group->pk;
+ session->key.kshare.dh_params.dh_group = group->id; /* no curve in FFDH, we write the group */
session->key.kshare.dh_params.qbits = *group->q_bits;
session->key.kshare.dh_params.params_nr = 3; /* empty q */
@@ -400,6 +401,9 @@ client_use_key_share(gnutls_session_t session, const gnutls_group_entry_st *grou
gnutls_pk_params_init(&pub);
+ if (session->key.kshare.ecdh_params.algo != group->pk || session->key.kshare.ecdh_params.curve != curve->id)
+ return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
+
if (curve->size*2+1 != data_size)
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
@@ -428,6 +432,9 @@ client_use_key_share(gnutls_session_t session, const gnutls_group_entry_st *grou
curve = _gnutls_ecc_curve_get_params(group->curve);
+ if (session->key.kshare.ecdhx_params.algo != group->pk || session->key.kshare.ecdhx_params.curve != curve->id)
+ return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
+
if (curve->size != data_size)
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
@@ -453,6 +460,9 @@ client_use_key_share(gnutls_session_t session, const gnutls_group_entry_st *grou
} else if (group->pk == GNUTLS_PK_DH) {
gnutls_pk_params_st pub;
+ if (session->key.kshare.dh_params.algo != group->pk || session->key.kshare.dh_params.dh_group != group->id)
+ return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
+
if (data_size != group->prime->size)
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);