mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-01-29 08:14:02 -05:00
TLS: Do not enforce in-place processing in tlsv1_record_send()
In preparation for record layer format changes, modify tlsv1_record_send() to use separate buffers for payload and the output message.
This commit is contained in:
parent
85b7187ffc
commit
3bff59f857
@ -227,10 +227,8 @@ int tlsv1_client_encrypt(struct tlsv1_client *conn,
|
|||||||
wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
|
wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
|
||||||
in_data, in_len);
|
in_data, in_len);
|
||||||
|
|
||||||
os_memcpy(out_data + TLS_RECORD_HEADER_LEN, in_data, in_len);
|
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
|
||||||
out_data, out_len, in_len, &rlen) < 0) {
|
out_data, out_len, in_data, in_len, &rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
||||||
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* TLSv1 client - write handshake message
|
* TLSv1 client - write handshake message
|
||||||
* Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@ -116,7 +116,8 @@ u8 * tls_send_client_hello(struct tlsv1_client *conn, size_t *out_len)
|
|||||||
tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
|
tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
||||||
rhdr, end - rhdr, pos - hs_start, out_len) < 0) {
|
rhdr, end - rhdr, hs_start, pos - hs_start,
|
||||||
|
out_len) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record");
|
||||||
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
@ -192,7 +193,8 @@ static int tls_write_client_certificate(struct tlsv1_client *conn,
|
|||||||
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
||||||
rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
|
rhdr, end - rhdr, hs_start, pos - hs_start,
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
||||||
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
@ -413,7 +415,8 @@ static int tls_write_client_key_exchange(struct tlsv1_client *conn,
|
|||||||
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
||||||
rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
|
rhdr, end - rhdr, hs_start, pos - hs_start,
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
||||||
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
@ -534,7 +537,8 @@ static int tls_write_client_certificate_verify(struct tlsv1_client *conn,
|
|||||||
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
||||||
rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
|
rhdr, end - rhdr, hs_start, pos - hs_start,
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
||||||
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
@ -553,17 +557,16 @@ static int tls_write_client_certificate_verify(struct tlsv1_client *conn,
|
|||||||
static int tls_write_client_change_cipher_spec(struct tlsv1_client *conn,
|
static int tls_write_client_change_cipher_spec(struct tlsv1_client *conn,
|
||||||
u8 **msgpos, u8 *end)
|
u8 **msgpos, u8 *end)
|
||||||
{
|
{
|
||||||
u8 *pos, *rhdr;
|
|
||||||
size_t rlen;
|
size_t rlen;
|
||||||
|
u8 payload[1];
|
||||||
pos = *msgpos;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec");
|
wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec");
|
||||||
rhdr = pos;
|
|
||||||
pos += TLS_RECORD_HEADER_LEN;
|
payload[0] = TLS_CHANGE_CIPHER_SPEC;
|
||||||
*pos = TLS_CHANGE_CIPHER_SPEC;
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC,
|
||||||
rhdr, end - rhdr, 1, &rlen) < 0) {
|
*msgpos, end - *msgpos, payload, sizeof(payload),
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
||||||
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
@ -578,7 +581,7 @@ static int tls_write_client_change_cipher_spec(struct tlsv1_client *conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*msgpos = rhdr + rlen;
|
*msgpos += rlen;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -587,13 +590,11 @@ static int tls_write_client_change_cipher_spec(struct tlsv1_client *conn,
|
|||||||
static int tls_write_client_finished(struct tlsv1_client *conn,
|
static int tls_write_client_finished(struct tlsv1_client *conn,
|
||||||
u8 **msgpos, u8 *end)
|
u8 **msgpos, u8 *end)
|
||||||
{
|
{
|
||||||
u8 *pos, *rhdr, *hs_start, *hs_length;
|
u8 *pos, *hs_start;
|
||||||
size_t rlen, hlen;
|
size_t rlen, hlen;
|
||||||
u8 verify_data[TLS_VERIFY_DATA_LEN];
|
u8 verify_data[1 + 3 + TLS_VERIFY_DATA_LEN];
|
||||||
u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
|
u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
|
||||||
|
|
||||||
pos = *msgpos;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Send Finished");
|
wpa_printf(MSG_DEBUG, "TLSv1: Send Finished");
|
||||||
|
|
||||||
/* Encrypted Handshake Message: Finished */
|
/* Encrypted Handshake Message: Finished */
|
||||||
@ -622,40 +623,35 @@ static int tls_write_client_finished(struct tlsv1_client *conn,
|
|||||||
|
|
||||||
if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
|
if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
|
||||||
"client finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
|
"client finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
|
||||||
verify_data, TLS_VERIFY_DATA_LEN)) {
|
verify_data + 1 + 3, TLS_VERIFY_DATA_LEN)) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data");
|
||||||
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)",
|
wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)",
|
||||||
verify_data, TLS_VERIFY_DATA_LEN);
|
verify_data + 1 + 3, TLS_VERIFY_DATA_LEN);
|
||||||
|
|
||||||
rhdr = pos;
|
|
||||||
pos += TLS_RECORD_HEADER_LEN;
|
|
||||||
/* Handshake */
|
/* Handshake */
|
||||||
hs_start = pos;
|
pos = hs_start = verify_data;
|
||||||
/* HandshakeType msg_type */
|
/* HandshakeType msg_type */
|
||||||
*pos++ = TLS_HANDSHAKE_TYPE_FINISHED;
|
*pos++ = TLS_HANDSHAKE_TYPE_FINISHED;
|
||||||
/* uint24 length (to be filled) */
|
/* uint24 length */
|
||||||
hs_length = pos;
|
WPA_PUT_BE24(pos, TLS_VERIFY_DATA_LEN);
|
||||||
pos += 3;
|
pos += 3;
|
||||||
os_memcpy(pos, verify_data, TLS_VERIFY_DATA_LEN);
|
pos += TLS_VERIFY_DATA_LEN; /* verify_data already in place */
|
||||||
pos += TLS_VERIFY_DATA_LEN;
|
|
||||||
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
|
||||||
tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
|
tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
||||||
rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
|
*msgpos, end - *msgpos, hs_start, pos - hs_start,
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
||||||
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = rhdr + rlen;
|
*msgpos += rlen;
|
||||||
|
|
||||||
*msgpos = pos;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -138,10 +138,10 @@ int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl)
|
|||||||
* tlsv1_record_send - TLS record layer: Send a message
|
* tlsv1_record_send - TLS record layer: Send a message
|
||||||
* @rl: Pointer to TLS record layer data
|
* @rl: Pointer to TLS record layer data
|
||||||
* @content_type: Content type (TLS_CONTENT_TYPE_*)
|
* @content_type: Content type (TLS_CONTENT_TYPE_*)
|
||||||
* @buf: Buffer to send (with TLS_RECORD_HEADER_LEN octets reserved in the
|
* @buf: Buffer for the generated TLS message (needs to have extra space for
|
||||||
* beginning for record layer to fill in; payload filled in after this and
|
* header and HMAC)
|
||||||
* extra space in the end for HMAC).
|
|
||||||
* @buf_size: Maximum buf size
|
* @buf_size: Maximum buf size
|
||||||
|
* @payload: Payload to be sent
|
||||||
* @payload_len: Length of the payload
|
* @payload_len: Length of the payload
|
||||||
* @out_len: Buffer for returning the used buf length
|
* @out_len: Buffer for returning the used buf length
|
||||||
* Returns: 0 on success, -1 on failure
|
* Returns: 0 on success, -1 on failure
|
||||||
@ -150,13 +150,17 @@ int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl)
|
|||||||
* the data using the current write cipher.
|
* the data using the current write cipher.
|
||||||
*/
|
*/
|
||||||
int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
|
int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
|
||||||
size_t buf_size, size_t payload_len, size_t *out_len)
|
size_t buf_size, const u8 *payload, size_t payload_len,
|
||||||
|
size_t *out_len)
|
||||||
{
|
{
|
||||||
u8 *pos, *ct_start, *length, *payload;
|
u8 *pos, *ct_start, *length, *cpayload;
|
||||||
struct crypto_hash *hmac;
|
struct crypto_hash *hmac;
|
||||||
size_t clen;
|
size_t clen;
|
||||||
|
|
||||||
pos = buf;
|
pos = buf;
|
||||||
|
if (pos + TLS_RECORD_HEADER_LEN > buf + buf_size)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* ContentType type */
|
/* ContentType type */
|
||||||
ct_start = pos;
|
ct_start = pos;
|
||||||
*pos++ = content_type;
|
*pos++ = content_type;
|
||||||
@ -168,11 +172,23 @@ int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
|
|||||||
WPA_PUT_BE16(length, payload_len);
|
WPA_PUT_BE16(length, payload_len);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
|
|
||||||
/* opaque fragment[TLSPlaintext.length] */
|
cpayload = pos;
|
||||||
payload = pos;
|
|
||||||
|
/*
|
||||||
|
* opaque fragment[TLSPlaintext.length]
|
||||||
|
* (opaque content[TLSCompressed.length] in GenericBlockCipher)
|
||||||
|
*/
|
||||||
|
if (pos + payload_len > buf + buf_size)
|
||||||
|
return -1;
|
||||||
|
os_memmove(pos, payload, payload_len);
|
||||||
pos += payload_len;
|
pos += payload_len;
|
||||||
|
|
||||||
if (rl->write_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
|
if (rl->write_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
|
||||||
|
/*
|
||||||
|
* MAC calculated over seq_num + TLSCompressed.type +
|
||||||
|
* TLSCompressed.version + TLSCompressed.length +
|
||||||
|
* TLSCompressed.fragment
|
||||||
|
*/
|
||||||
hmac = crypto_hash_init(rl->hash_alg, rl->write_mac_secret,
|
hmac = crypto_hash_init(rl->hash_alg, rl->write_mac_secret,
|
||||||
rl->hash_size);
|
rl->hash_size);
|
||||||
if (hmac == NULL) {
|
if (hmac == NULL) {
|
||||||
@ -182,7 +198,8 @@ int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
|
|||||||
}
|
}
|
||||||
crypto_hash_update(hmac, rl->write_seq_num, TLS_SEQ_NUM_LEN);
|
crypto_hash_update(hmac, rl->write_seq_num, TLS_SEQ_NUM_LEN);
|
||||||
/* type + version + length + fragment */
|
/* type + version + length + fragment */
|
||||||
crypto_hash_update(hmac, ct_start, pos - ct_start);
|
crypto_hash_update(hmac, ct_start, TLS_RECORD_HEADER_LEN);
|
||||||
|
crypto_hash_update(hmac, payload, payload_len);
|
||||||
clen = buf + buf_size - pos;
|
clen = buf + buf_size - pos;
|
||||||
if (clen < rl->hash_size) {
|
if (clen < rl->hash_size) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Not "
|
wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Not "
|
||||||
@ -200,7 +217,7 @@ int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
|
|||||||
pos, clen);
|
pos, clen);
|
||||||
pos += clen;
|
pos += clen;
|
||||||
if (rl->iv_size) {
|
if (rl->iv_size) {
|
||||||
size_t len = pos - payload;
|
size_t len = pos - cpayload;
|
||||||
size_t pad;
|
size_t pad;
|
||||||
pad = (len + 1) % rl->iv_size;
|
pad = (len + 1) % rl->iv_size;
|
||||||
if (pad)
|
if (pad)
|
||||||
@ -214,8 +231,8 @@ int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
|
|||||||
pos += pad + 1;
|
pos += pad + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crypto_cipher_encrypt(rl->write_cbc, payload,
|
if (crypto_cipher_encrypt(rl->write_cbc, cpayload,
|
||||||
payload, pos - payload) < 0)
|
cpayload, pos - cpayload) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,8 @@ int tlsv1_record_set_cipher_suite(struct tlsv1_record_layer *rl,
|
|||||||
int tlsv1_record_change_write_cipher(struct tlsv1_record_layer *rl);
|
int tlsv1_record_change_write_cipher(struct tlsv1_record_layer *rl);
|
||||||
int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl);
|
int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl);
|
||||||
int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
|
int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
|
||||||
size_t buf_size, size_t payload_len, size_t *out_len);
|
size_t buf_size, const u8 *payload, size_t payload_len,
|
||||||
|
size_t *out_len);
|
||||||
int tlsv1_record_receive(struct tlsv1_record_layer *rl,
|
int tlsv1_record_receive(struct tlsv1_record_layer *rl,
|
||||||
const u8 *in_data, size_t in_len,
|
const u8 *in_data, size_t in_len,
|
||||||
u8 *out_data, size_t *out_len, u8 *alert);
|
u8 *out_data, size_t *out_len, u8 *alert);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* TLSv1 server (RFC 2246)
|
* TLSv1 server (RFC 2246)
|
||||||
* Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@ -201,10 +201,8 @@ int tlsv1_server_encrypt(struct tlsv1_server *conn,
|
|||||||
wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
|
wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
|
||||||
in_data, in_len);
|
in_data, in_len);
|
||||||
|
|
||||||
os_memcpy(out_data + TLS_RECORD_HEADER_LEN, in_data, in_len);
|
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
|
||||||
out_data, out_len, in_len, &rlen) < 0) {
|
out_data, out_len, in_data, in_len, &rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
||||||
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* TLSv1 server - write handshake message
|
* TLSv1 server - write handshake message
|
||||||
* Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@ -143,7 +143,8 @@ static int tls_write_server_hello(struct tlsv1_server *conn,
|
|||||||
tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
|
tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
||||||
rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
|
rhdr, end - rhdr, hs_start, pos - hs_start,
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record");
|
||||||
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
@ -227,7 +228,8 @@ static int tls_write_server_certificate(struct tlsv1_server *conn,
|
|||||||
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
||||||
rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
|
rhdr, end - rhdr, hs_start, pos - hs_start,
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
||||||
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
@ -418,7 +420,8 @@ static int tls_write_server_key_exchange(struct tlsv1_server *conn,
|
|||||||
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
||||||
rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
|
rhdr, end - rhdr, hs_start, pos - hs_start,
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
||||||
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
@ -483,7 +486,8 @@ static int tls_write_server_certificate_request(struct tlsv1_server *conn,
|
|||||||
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
||||||
rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
|
rhdr, end - rhdr, hs_start, pos - hs_start,
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
||||||
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
@ -502,40 +506,35 @@ static int tls_write_server_certificate_request(struct tlsv1_server *conn,
|
|||||||
static int tls_write_server_hello_done(struct tlsv1_server *conn,
|
static int tls_write_server_hello_done(struct tlsv1_server *conn,
|
||||||
u8 **msgpos, u8 *end)
|
u8 **msgpos, u8 *end)
|
||||||
{
|
{
|
||||||
u8 *pos, *rhdr, *hs_start, *hs_length;
|
u8 *pos;
|
||||||
size_t rlen;
|
size_t rlen;
|
||||||
|
u8 payload[4];
|
||||||
pos = *msgpos;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Send ServerHelloDone");
|
wpa_printf(MSG_DEBUG, "TLSv1: Send ServerHelloDone");
|
||||||
rhdr = pos;
|
|
||||||
pos += TLS_RECORD_HEADER_LEN;
|
|
||||||
|
|
||||||
/* opaque fragment[TLSPlaintext.length] */
|
/* opaque fragment[TLSPlaintext.length] */
|
||||||
|
|
||||||
/* Handshake */
|
/* Handshake */
|
||||||
hs_start = pos;
|
pos = payload;
|
||||||
/* HandshakeType msg_type */
|
/* HandshakeType msg_type */
|
||||||
*pos++ = TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE;
|
*pos++ = TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE;
|
||||||
/* uint24 length (to be filled) */
|
/* uint24 length */
|
||||||
hs_length = pos;
|
WPA_PUT_BE24(pos, 0);
|
||||||
pos += 3;
|
pos += 3;
|
||||||
/* body - ServerHelloDone (empty) */
|
/* body - ServerHelloDone (empty) */
|
||||||
|
|
||||||
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
||||||
rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
|
*msgpos, end - *msgpos, payload, pos - payload,
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
|
||||||
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pos = rhdr + rlen;
|
|
||||||
|
|
||||||
tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
|
tls_verify_hash_add(&conn->verify, payload, pos - payload);
|
||||||
|
|
||||||
*msgpos = pos;
|
*msgpos += rlen;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -544,17 +543,16 @@ static int tls_write_server_hello_done(struct tlsv1_server *conn,
|
|||||||
static int tls_write_server_change_cipher_spec(struct tlsv1_server *conn,
|
static int tls_write_server_change_cipher_spec(struct tlsv1_server *conn,
|
||||||
u8 **msgpos, u8 *end)
|
u8 **msgpos, u8 *end)
|
||||||
{
|
{
|
||||||
u8 *pos, *rhdr;
|
|
||||||
size_t rlen;
|
size_t rlen;
|
||||||
|
u8 payload[1];
|
||||||
pos = *msgpos;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec");
|
wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec");
|
||||||
rhdr = pos;
|
|
||||||
pos += TLS_RECORD_HEADER_LEN;
|
payload[0] = TLS_CHANGE_CIPHER_SPEC;
|
||||||
*pos = TLS_CHANGE_CIPHER_SPEC;
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC,
|
||||||
rhdr, end - rhdr, 1, &rlen) < 0) {
|
*msgpos, end - *msgpos, payload, sizeof(payload),
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
||||||
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
@ -569,7 +567,7 @@ static int tls_write_server_change_cipher_spec(struct tlsv1_server *conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*msgpos = rhdr + rlen;
|
*msgpos += rlen;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -578,9 +576,9 @@ static int tls_write_server_change_cipher_spec(struct tlsv1_server *conn,
|
|||||||
static int tls_write_server_finished(struct tlsv1_server *conn,
|
static int tls_write_server_finished(struct tlsv1_server *conn,
|
||||||
u8 **msgpos, u8 *end)
|
u8 **msgpos, u8 *end)
|
||||||
{
|
{
|
||||||
u8 *pos, *rhdr, *hs_start, *hs_length;
|
u8 *pos, *hs_start;
|
||||||
size_t rlen, hlen;
|
size_t rlen, hlen;
|
||||||
u8 verify_data[TLS_VERIFY_DATA_LEN];
|
u8 verify_data[1 + 3 + TLS_VERIFY_DATA_LEN];
|
||||||
u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
|
u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
|
||||||
|
|
||||||
pos = *msgpos;
|
pos = *msgpos;
|
||||||
@ -613,40 +611,35 @@ static int tls_write_server_finished(struct tlsv1_server *conn,
|
|||||||
|
|
||||||
if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
|
if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
|
||||||
"server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
|
"server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
|
||||||
verify_data, TLS_VERIFY_DATA_LEN)) {
|
verify_data + 1 + 3, TLS_VERIFY_DATA_LEN)) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data");
|
||||||
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
|
wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
|
||||||
verify_data, TLS_VERIFY_DATA_LEN);
|
verify_data + 1 + 3, TLS_VERIFY_DATA_LEN);
|
||||||
|
|
||||||
rhdr = pos;
|
|
||||||
pos += TLS_RECORD_HEADER_LEN;
|
|
||||||
/* Handshake */
|
/* Handshake */
|
||||||
hs_start = pos;
|
pos = hs_start = verify_data;
|
||||||
/* HandshakeType msg_type */
|
/* HandshakeType msg_type */
|
||||||
*pos++ = TLS_HANDSHAKE_TYPE_FINISHED;
|
*pos++ = TLS_HANDSHAKE_TYPE_FINISHED;
|
||||||
/* uint24 length (to be filled) */
|
/* uint24 length */
|
||||||
hs_length = pos;
|
WPA_PUT_BE24(pos, TLS_VERIFY_DATA_LEN);
|
||||||
pos += 3;
|
pos += 3;
|
||||||
os_memcpy(pos, verify_data, TLS_VERIFY_DATA_LEN);
|
|
||||||
pos += TLS_VERIFY_DATA_LEN;
|
pos += TLS_VERIFY_DATA_LEN;
|
||||||
WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
|
||||||
tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
|
tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
|
||||||
|
|
||||||
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
|
||||||
rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
|
*msgpos, end - *msgpos, hs_start, pos - hs_start,
|
||||||
|
&rlen) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
|
||||||
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
||||||
TLS_ALERT_INTERNAL_ERROR);
|
TLS_ALERT_INTERNAL_ERROR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = rhdr + rlen;
|
*msgpos += rlen;
|
||||||
|
|
||||||
*msgpos = pos;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user