|
@@ -1,6 +1,6 @@
|
|
|
/*
|
|
|
* 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
|
|
|
* 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);
|
|
|
|
|
|
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");
|
|
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
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);
|
|
|
|
|
|
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");
|
|
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
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);
|
|
|
|
|
|
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");
|
|
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
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);
|
|
|
|
|
|
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");
|
|
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
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,
|
|
|
u8 **msgpos, u8 *end)
|
|
|
{
|
|
|
- u8 *pos, *rhdr, *hs_start, *hs_length;
|
|
|
+ u8 *pos;
|
|
|
size_t rlen;
|
|
|
-
|
|
|
- pos = *msgpos;
|
|
|
+ u8 payload[4];
|
|
|
|
|
|
wpa_printf(MSG_DEBUG, "TLSv1: Send ServerHelloDone");
|
|
|
- rhdr = pos;
|
|
|
- pos += TLS_RECORD_HEADER_LEN;
|
|
|
|
|
|
/* opaque fragment[TLSPlaintext.length] */
|
|
|
|
|
|
/* Handshake */
|
|
|
- hs_start = pos;
|
|
|
+ pos = payload;
|
|
|
/* HandshakeType msg_type */
|
|
|
*pos++ = TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE;
|
|
|
- /* uint24 length (to be filled) */
|
|
|
- hs_length = pos;
|
|
|
+ /* uint24 length */
|
|
|
+ WPA_PUT_BE24(pos, 0);
|
|
|
pos += 3;
|
|
|
/* body - ServerHelloDone (empty) */
|
|
|
|
|
|
- WPA_PUT_BE24(hs_length, pos - hs_length - 3);
|
|
|
-
|
|
|
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");
|
|
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
TLS_ALERT_INTERNAL_ERROR);
|
|
|
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;
|
|
|
}
|
|
@@ -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,
|
|
|
u8 **msgpos, u8 *end)
|
|
|
{
|
|
|
- u8 *pos, *rhdr;
|
|
|
size_t rlen;
|
|
|
-
|
|
|
- pos = *msgpos;
|
|
|
+ u8 payload[1];
|
|
|
|
|
|
wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec");
|
|
|
- rhdr = pos;
|
|
|
- pos += TLS_RECORD_HEADER_LEN;
|
|
|
- *pos = TLS_CHANGE_CIPHER_SPEC;
|
|
|
+
|
|
|
+ payload[0] = TLS_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");
|
|
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
TLS_ALERT_INTERNAL_ERROR);
|
|
@@ -569,7 +567,7 @@ static int tls_write_server_change_cipher_spec(struct tlsv1_server *conn,
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- *msgpos = rhdr + rlen;
|
|
|
+ *msgpos += rlen;
|
|
|
|
|
|
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,
|
|
|
u8 **msgpos, u8 *end)
|
|
|
{
|
|
|
- u8 *pos, *rhdr, *hs_start, *hs_length;
|
|
|
+ u8 *pos, *hs_start;
|
|
|
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];
|
|
|
|
|
|
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,
|
|
|
"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");
|
|
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
TLS_ALERT_INTERNAL_ERROR);
|
|
|
return -1;
|
|
|
}
|
|
|
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 */
|
|
|
- hs_start = pos;
|
|
|
+ pos = hs_start = verify_data;
|
|
|
/* HandshakeType msg_type */
|
|
|
*pos++ = TLS_HANDSHAKE_TYPE_FINISHED;
|
|
|
- /* uint24 length (to be filled) */
|
|
|
- hs_length = pos;
|
|
|
+ /* uint24 length */
|
|
|
+ WPA_PUT_BE24(pos, TLS_VERIFY_DATA_LEN);
|
|
|
pos += 3;
|
|
|
- os_memcpy(pos, verify_data, 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);
|
|
|
|
|
|
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");
|
|
|
tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
|
|
|
TLS_ALERT_INTERNAL_ERROR);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- pos = rhdr + rlen;
|
|
|
-
|
|
|
- *msgpos = pos;
|
|
|
+ *msgpos += rlen;
|
|
|
|
|
|
return 0;
|
|
|
}
|