TLS: Validate RSA ClientKeyExchange length field
Instead of using implicit length based on the received buffer, validate RSA ClientKeyExchange based on the explicit length field.
This commit is contained in:
parent
46eeedac61
commit
3803bd331d
1 changed files with 13 additions and 5 deletions
|
@ -494,6 +494,14 @@ static int tls_process_client_key_exchange_rsa(
|
||||||
|
|
||||||
encr_len = WPA_GET_BE16(pos);
|
encr_len = WPA_GET_BE16(pos);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
|
if (pos + encr_len > end) {
|
||||||
|
wpa_printf(MSG_DEBUG, "TLSv1: Invalid ClientKeyExchange "
|
||||||
|
"format: encr_len=%u left=%u",
|
||||||
|
encr_len, (unsigned int) (end - pos));
|
||||||
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
|
TLS_ALERT_DECODE_ERROR);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
outbuflen = outlen = end - pos;
|
outbuflen = outlen = end - pos;
|
||||||
out = os_malloc(outlen >= TLS_PRE_MASTER_SECRET_LEN ?
|
out = os_malloc(outlen >= TLS_PRE_MASTER_SECRET_LEN ?
|
||||||
|
@ -523,21 +531,21 @@ static int tls_process_client_key_exchange_rsa(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (crypto_private_key_decrypt_pkcs1_v15(conn->cred->key,
|
if (crypto_private_key_decrypt_pkcs1_v15(conn->cred->key,
|
||||||
pos, end - pos,
|
pos, encr_len,
|
||||||
out, &outlen) < 0) {
|
out, &outlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt "
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt "
|
||||||
"PreMasterSecret (encr_len=%d outlen=%lu)",
|
"PreMasterSecret (encr_len=%u outlen=%lu)",
|
||||||
(int) (end - pos), (unsigned long) outlen);
|
encr_len, (unsigned long) outlen);
|
||||||
use_random = 1;
|
use_random = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outlen != TLS_PRE_MASTER_SECRET_LEN) {
|
if (!use_random && outlen != TLS_PRE_MASTER_SECRET_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Unexpected PreMasterSecret "
|
wpa_printf(MSG_DEBUG, "TLSv1: Unexpected PreMasterSecret "
|
||||||
"length %lu", (unsigned long) outlen);
|
"length %lu", (unsigned long) outlen);
|
||||||
use_random = 1;
|
use_random = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WPA_GET_BE16(out) != conn->client_version) {
|
if (!use_random && WPA_GET_BE16(out) != conn->client_version) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Client version in "
|
wpa_printf(MSG_DEBUG, "TLSv1: Client version in "
|
||||||
"ClientKeyExchange does not match with version in "
|
"ClientKeyExchange does not match with version in "
|
||||||
"ClientHello");
|
"ClientHello");
|
||||||
|
|
Loading…
Reference in a new issue