diff options
Diffstat (limited to 'contrib/hostapd/eap_tls_common.c')
-rw-r--r-- | contrib/hostapd/eap_tls_common.c | 64 |
1 files changed, 41 insertions, 23 deletions
diff --git a/contrib/hostapd/eap_tls_common.c b/contrib/hostapd/eap_tls_common.c index d573064..2a089d4 100644 --- a/contrib/hostapd/eap_tls_common.c +++ b/contrib/hostapd/eap_tls_common.c @@ -1,6 +1,6 @@ /* * hostapd / EAP-TLS/PEAP/TTLS common functions - * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi> + * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -12,10 +12,7 @@ * See README and COPYING for more details. */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <netinet/in.h> +#include "includes.h" #include "hostapd.h" #include "common.h" @@ -71,31 +68,42 @@ u8 * eap_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, char *label, size_t len) { struct tls_keys keys; - u8 *random; - u8 *out; + u8 *rnd = NULL, *out; - if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys)) - return NULL; out = malloc(len); - random = malloc(keys.client_random_len + keys.server_random_len); - if (out == NULL || random == NULL) { - free(out); - free(random); + if (out == NULL) return NULL; - } - memcpy(random, keys.client_random, keys.client_random_len); - memcpy(random + keys.client_random_len, keys.server_random, + + if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) == + 0) + return out; + + if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys)) + goto fail; + + if (keys.client_random == NULL || keys.server_random == NULL || + keys.master_key == NULL) + goto fail; + + rnd = malloc(keys.client_random_len + keys.server_random_len); + if (rnd == NULL) + goto fail; + memcpy(rnd, keys.client_random, keys.client_random_len); + memcpy(rnd + keys.client_random_len, keys.server_random, keys.server_random_len); if (tls_prf(keys.master_key, keys.master_key_len, - label, random, keys.client_random_len + - keys.server_random_len, out, len)) { - free(random); - free(out); - return NULL; - } - free(random); + label, rnd, keys.client_random_len + + keys.server_random_len, out, len)) + goto fail; + + free(rnd); return out; + +fail: + free(out); + free(rnd); + return NULL; } @@ -105,6 +113,16 @@ int eap_tls_data_reassemble(struct eap_sm *sm, struct eap_ssl_data *data, u8 *buf; if (data->tls_in_left > *in_len || data->tls_in) { + if (data->tls_in_len + *in_len > 65536) { + /* Limit length to avoid rogue peers from causing large + * memory allocations. */ + free(data->tls_in); + data->tls_in = NULL; + data->tls_in_len = 0; + wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size" + " over 64 kB)"); + return -1; + } buf = realloc(data->tls_in, data->tls_in_len + *in_len); if (buf == NULL) { free(data->tls_in); |