From 76874379d35d854b433243dbd6c6e8ff6a051da0 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 23 Nov 2014 17:48:34 +0200 Subject: [PATCH] TLS client: Check DH parameters using a local variable Use a temporary, local variable to check the DH parameters received from the server before assigning the length to the struct tlsv1_client variables. This will hopefully make it easier for static analyzers to figure out that there is bounds checking for the value. (CID 72699) Signed-off-by: Jouni Malinen --- src/tls/tlsv1_client_read.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/tls/tlsv1_client_read.c b/src/tls/tlsv1_client_read.c index 101e0cb1a..9ce968037 100644 --- a/src/tls/tlsv1_client_read.c +++ b/src/tls/tlsv1_client_read.c @@ -440,6 +440,7 @@ static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn, const u8 *pos, *end, *server_params, *server_params_end; u8 alert; unsigned int bits; + u16 val; tlsv1_client_free_dh(conn); @@ -449,13 +450,13 @@ static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn, if (end - pos < 3) goto fail; server_params = pos; - conn->dh_p_len = WPA_GET_BE16(pos); + val = WPA_GET_BE16(pos); pos += 2; - if (conn->dh_p_len == 0 || conn->dh_p_len > (size_t) (end - pos)) { - wpa_printf(MSG_DEBUG, "TLSv1: Invalid dh_p length %lu", - (unsigned long) conn->dh_p_len); + if (val == 0 || val > (size_t) (end - pos)) { + wpa_printf(MSG_DEBUG, "TLSv1: Invalid dh_p length %u", val); goto fail; } + conn->dh_p_len = val; bits = count_bits(pos, conn->dh_p_len); if (bits < 768) { wpa_printf(MSG_INFO, "TLSv1: Reject under 768-bit DH prime (insecure; only %u bits)", @@ -474,10 +475,11 @@ static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn, if (end - pos < 3) goto fail; - conn->dh_g_len = WPA_GET_BE16(pos); + val = WPA_GET_BE16(pos); pos += 2; - if (conn->dh_g_len == 0 || conn->dh_g_len > (size_t) (end - pos)) + if (val == 0 || val > (size_t) (end - pos)) goto fail; + conn->dh_g_len = val; conn->dh_g = os_malloc(conn->dh_g_len); if (conn->dh_g == NULL) goto fail; @@ -490,10 +492,11 @@ static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn, if (end - pos < 3) goto fail; - conn->dh_ys_len = WPA_GET_BE16(pos); + val = WPA_GET_BE16(pos); pos += 2; - if (conn->dh_ys_len == 0 || conn->dh_ys_len > (size_t) (end - pos)) + if (val == 0 || val > (size_t) (end - pos)) goto fail; + conn->dh_ys_len = val; conn->dh_ys = os_malloc(conn->dh_ys_len); if (conn->dh_ys == NULL) goto fail;