|
@@ -271,7 +271,8 @@ int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
|
|
* @out_len: Set to maximum out_data length by caller; used to return the
|
|
* @out_len: Set to maximum out_data length by caller; used to return the
|
|
* length of the used data
|
|
* length of the used data
|
|
* @alert: Buffer for returning an alert value on failure
|
|
* @alert: Buffer for returning an alert value on failure
|
|
- * Returns: 0 on success, -1 on failure
|
|
+ * Returns: Number of bytes used from in_data on success, 0 if record was not
|
|
|
|
+ * complete (more data needed), or -1 on failure
|
|
*
|
|
*
|
|
* This function decrypts the received message, verifies HMAC and TLS record
|
|
* This function decrypts the received message, verifies HMAC and TLS record
|
|
* layer header.
|
|
* layer header.
|
|
@@ -285,30 +286,21 @@ int tlsv1_record_receive(struct tlsv1_record_layer *rl,
|
|
struct crypto_hash *hmac;
|
|
struct crypto_hash *hmac;
|
|
u8 len[2], hash[100];
|
|
u8 len[2], hash[100];
|
|
int force_mac_error = 0;
|
|
int force_mac_error = 0;
|
|
-
|
|
+ u8 ct;
|
|
- wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Received",
|
|
|
|
- in_data, in_len);
|
|
|
|
|
|
|
|
if (in_len < TLS_RECORD_HEADER_LEN) {
|
|
if (in_len < TLS_RECORD_HEADER_LEN) {
|
|
- wpa_printf(MSG_DEBUG, "TLSv1: Too short record (in_len=%lu)",
|
|
+ wpa_printf(MSG_DEBUG, "TLSv1: Too short record (in_len=%lu) - "
|
|
|
|
+ "need more data",
|
|
(unsigned long) in_len);
|
|
(unsigned long) in_len);
|
|
- *alert = TLS_ALERT_DECODE_ERROR;
|
|
+ wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Received",
|
|
- return -1;
|
|
+ in_data, in_len);
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ ct = in_data[0];
|
|
|
|
+ rlen = WPA_GET_BE16(in_data + 3);
|
|
wpa_printf(MSG_DEBUG, "TLSv1: Received content type %d version %d.%d "
|
|
wpa_printf(MSG_DEBUG, "TLSv1: Received content type %d version %d.%d "
|
|
- "length %d", in_data[0], in_data[1], in_data[2],
|
|
+ "length %d", ct, in_data[1], in_data[2], (int) rlen);
|
|
- WPA_GET_BE16(in_data + 3));
|
|
|
|
-
|
|
|
|
- if (in_data[0] != TLS_CONTENT_TYPE_HANDSHAKE &&
|
|
|
|
- in_data[0] != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC &&
|
|
|
|
- in_data[0] != TLS_CONTENT_TYPE_ALERT &&
|
|
|
|
- in_data[0] != TLS_CONTENT_TYPE_APPLICATION_DATA) {
|
|
|
|
- wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type 0x%x",
|
|
|
|
- in_data[0]);
|
|
|
|
- *alert = TLS_ALERT_UNEXPECTED_MESSAGE;
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
|
|
* TLS v1.0 and v1.1 RFCs were not exactly clear on the use of the
|
|
* TLS v1.0 and v1.1 RFCs were not exactly clear on the use of the
|
|
@@ -322,8 +314,6 @@ int tlsv1_record_receive(struct tlsv1_record_layer *rl,
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
- rlen = WPA_GET_BE16(in_data + 3);
|
|
|
|
-
|
|
|
|
|
|
|
|
if (TLS_RECORD_HEADER_LEN + rlen > 18432) {
|
|
if (TLS_RECORD_HEADER_LEN + rlen > 18432) {
|
|
wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
|
|
wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
|
|
@@ -339,7 +329,19 @@ int tlsv1_record_receive(struct tlsv1_record_layer *rl,
|
|
wpa_printf(MSG_DEBUG, "TLSv1: Not all record data included "
|
|
wpa_printf(MSG_DEBUG, "TLSv1: Not all record data included "
|
|
"(rlen=%lu > in_len=%lu)",
|
|
"(rlen=%lu > in_len=%lu)",
|
|
(unsigned long) rlen, (unsigned long) in_len);
|
|
(unsigned long) rlen, (unsigned long) in_len);
|
|
- *alert = TLS_ALERT_DECODE_ERROR;
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Received",
|
|
|
|
+ in_data, rlen);
|
|
|
|
+
|
|
|
|
+ if (ct != TLS_CONTENT_TYPE_HANDSHAKE &&
|
|
|
|
+ ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC &&
|
|
|
|
+ ct != TLS_CONTENT_TYPE_ALERT &&
|
|
|
|
+ ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
|
|
|
|
+ wpa_printf(MSG_DEBUG, "TLSv1: Ignore record with unknown "
|
|
|
|
+ "content type 0x%x", ct);
|
|
|
|
+ *alert = TLS_ALERT_UNEXPECTED_MESSAGE;
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -417,13 +419,13 @@ int tlsv1_record_receive(struct tlsv1_record_layer *rl,
|
|
}
|
|
}
|
|
|
|
|
|
plen -= padlen + 1;
|
|
plen -= padlen + 1;
|
|
|
|
+
|
|
|
|
+ wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Record Layer - "
|
|
|
|
+ "Decrypted data with IV and padding "
|
|
|
|
+ "removed", out_data, plen);
|
|
}
|
|
}
|
|
|
|
|
|
check_mac:
|
|
check_mac:
|
|
- wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Record Layer - Decrypted "
|
|
|
|
- "data with IV and padding removed",
|
|
|
|
- out_data, plen);
|
|
|
|
-
|
|
|
|
if (plen < rl->hash_size) {
|
|
if (plen < rl->hash_size) {
|
|
wpa_printf(MSG_DEBUG, "TLSv1: Too short record; no "
|
|
wpa_printf(MSG_DEBUG, "TLSv1: Too short record; no "
|
|
"hash value");
|
|
"hash value");
|
|
@@ -481,5 +483,5 @@ int tlsv1_record_receive(struct tlsv1_record_layer *rl,
|
|
|
|
|
|
inc_byte_array(rl->read_seq_num, TLS_SEQ_NUM_LEN);
|
|
inc_byte_array(rl->read_seq_num, TLS_SEQ_NUM_LEN);
|
|
|
|
|
|
- return 0;
|
|
+ return TLS_RECORD_HEADER_LEN + rlen;
|
|
}
|
|
}
|