tlsv1_client_read.c revision 818ea489ef32dcdc7c098d8a336d6e1dd8996112
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TLSv1 client - read handshake message 3818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/md5.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha1.h" 141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "crypto/sha256.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/tls.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "x509v3.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_common.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_record.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_client.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_client_i.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct, 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len); 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct, 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len); 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct, 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len); 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_hello(struct tlsv1_client *conn, u8 ct, 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, i; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 cipher_suite; 361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u16 tls_version; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_HANDSHAKE_TYPE_SERVER_HELLO) { 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ServerHello)", *pos); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHello"); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length */ 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - ServerHello */ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ServerHello", pos, len); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ProtocolVersion server_version */ 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tls_version = WPA_GET_BE16(pos); 791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!tls_version_ok(tls_version)) { 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in " 811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "ServerHello %u.%u", pos[0], pos[1]); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_PROTOCOL_VERSION); 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Using TLS v%s", 891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tls_version_str(tls_version)); 901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->rl.tls_version = tls_version; 911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Random random */ 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < TLS_RANDOM_LEN) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->server_random, pos, TLS_RANDOM_LEN); 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RANDOM_LEN; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: server_random", 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->server_random, TLS_RANDOM_LEN); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SessionID session_id */ 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1) 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN) 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_id_len && conn->session_id_len == *pos && 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conn->session_id, pos + 1, conn->session_id_len) == 0) { 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 1 + conn->session_id_len; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Resuming old session"); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_resumed = 1; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_id_len = *pos; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->session_id, pos, conn->session_id_len); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->session_id_len; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id", 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_id, conn->session_id_len); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CipherSuite cipher_suite */ 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher_suite = WPA_GET_BE16(pos); 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < conn->num_cipher_suites; i++) { 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cipher_suite == conn->cipher_suites[i]) 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i == conn->num_cipher_suites) { 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected " 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cipher suite 0x%04x", cipher_suite); 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_resumed && cipher_suite != conn->prev_cipher_suite) { 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Server selected a different " 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cipher suite for a resumed connection (0x%04x != " 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "0x%04x)", cipher_suite, conn->prev_cipher_suite); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) { 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for " 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "record layer"); 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->prev_cipher_suite = cipher_suite; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CompressionMethod compression_method */ 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1) 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_COMPRESSION_NULL) { 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected " 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "compression 0x%02x", *pos); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end != pos) { 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: ServerHello extensions */ 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: Unexpected extra data in the " 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "end of ServerHello", pos, end - pos); 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket_included && conn->session_ticket_cb) { 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: include SessionTicket extension if one was included in 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ServerHello */ 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = conn->session_ticket_cb( 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx, NULL, 0, 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_random, conn->server_random, 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->master_secret); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback " 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "indicated failure"); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_HANDSHAKE_FAILURE); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->use_session_ticket = !!res; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((conn->session_resumed || conn->use_session_ticket) && 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_derive_keys(conn, NULL, 0)) { 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys"); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = (conn->session_resumed || conn->use_session_ticket) ? 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SERVER_CHANGE_CIPHER_SPEC : SERVER_CERTIFICATE; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdecode_error: 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ServerHello"); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate(struct tlsv1_client *conn, u8 ct, 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, list_len, cert_len, idx; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct x509_certificate *chain = NULL, *last = NULL, *cert; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reason; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message " 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu)", (unsigned long) left); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message " 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE) 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_server_key_exchange(conn, ct, in_data, 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_certificate_request(conn, ct, in_data, 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_server_hello_done(conn, ct, in_data, 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) { 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected Certificate/" 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ServerKeyExchange/CertificateRequest/" 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ServerHelloDone)", type); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TLSv1: Received Certificate (certificate_list len %lu)", 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque ASN.1Cert<2^24-1>; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ASN.1Cert certificate_list<1..2^24-1>; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } Certificate; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate " 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(left=%lu)", (unsigned long) left); 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list_len = WPA_GET_BE24(pos); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) (end - pos) != list_len) { 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list " 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu left=%lu)", 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) list_len, 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (end - pos)); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = 0; 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate_list"); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert_len = WPA_GET_BE24(pos); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) (end - pos) < cert_len) { 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate " 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu left=%lu)", 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) cert_len, 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (end - pos)); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)", 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) idx, (unsigned long) cert_len); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (idx == 0) { 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_public_key_free(conn->server_rsa_key); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_parse_cert(pos, cert_len, 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->server_rsa_key)) { 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the certificate"); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_BAD_CERTIFICATE); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = x509_certificate_parse(pos, cert_len); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the certificate"); 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_BAD_CERTIFICATE); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (last == NULL) 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chain = cert; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last->next = cert; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last = cert; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx++; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += cert_len; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->cred && 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_validate(conn->cred->trusted_certs, chain, 369c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt &reason, conn->disable_time_checks) 370c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt < 0) { 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tls_reason; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain " 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "validation failed (reason=%d)", reason); 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (reason) { 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_BAD_CERTIFICATE: 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_BAD_CERTIFICATE; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_UNSUPPORTED_CERTIFICATE: 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_REVOKED: 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_REVOKED; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_EXPIRED: 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_UNKNOWN: 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_UNKNOWN_CA: 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_UNKNOWN_CA; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_BAD_CERTIFICATE; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason); 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_KEY_EXCHANGE; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tlsv1_process_diffie_hellman(struct tlsv1_client *conn, 413818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt const u8 *buf, size_t len, 414818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tls_key_exchange key_exchange) 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 416818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt const u8 *pos, *end, *server_params, *server_params_end; 417818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 alert; 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_client_free_dh(conn); 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + len; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 426818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt server_params = pos; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_p_len = WPA_GET_BE16(pos); 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_p_len == 0 || end - pos < (int) conn->dh_p_len) { 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid dh_p length %lu", 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) conn->dh_p_len); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_p = os_malloc(conn->dh_p_len); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_p == NULL) 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->dh_p, pos, conn->dh_p_len); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->dh_p_len; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH p (prime)", 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_p, conn->dh_p_len); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_g_len = WPA_GET_BE16(pos); 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_g_len == 0 || end - pos < (int) conn->dh_g_len) 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_g = os_malloc(conn->dh_g_len); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_g == NULL) 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->dh_g, pos, conn->dh_g_len); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->dh_g_len; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH g (generator)", 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_g, conn->dh_g_len); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_g_len == 1 && conn->dh_g[0] < 2) 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_ys_len = WPA_GET_BE16(pos); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_ys_len == 0 || end - pos < (int) conn->dh_ys_len) 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_ys = os_malloc(conn->dh_ys_len); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_ys == NULL) 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->dh_ys, pos, conn->dh_ys_len); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->dh_ys_len; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)", 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_ys, conn->dh_ys_len); 471818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt server_params_end = pos; 472818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 473818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (key_exchange == TLS_KEY_X_DHE_RSA) { 474818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN]; 475818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt int hlen; 476818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 477818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->rl.tls_version == TLS_VERSION_1_2) { 478818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TLSV12 479818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt /* 480818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * RFC 5246, 4.7: 481818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * TLS v1.2 adds explicit indication of the used 482818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * signature and hash algorithms. 483818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 484818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * struct { 485818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * HashAlgorithm hash; 486818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * SignatureAlgorithm signature; 487818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * } SignatureAndHashAlgorithm; 488818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt */ 489818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (end - pos < 2) 490818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt goto fail; 491818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (pos[0] != TLS_HASH_ALG_SHA256 || 492818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos[1] != TLS_SIGN_ALG_RSA) { 493818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1.2: Unsupported hash(%u)/signature(%u) algorithm", 494818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos[0], pos[1]); 495818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt goto fail; 496818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 497818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos += 2; 498818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 499818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hlen = tlsv12_key_x_server_params_hash( 500818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->rl.tls_version, conn->client_random, 501818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->server_random, server_params, 502818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt server_params_end - server_params, hash); 503818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#else /* CONFIG_TLSV12 */ 504818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt goto fail; 505818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TLSV12 */ 506818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } else { 507818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hlen = tls_key_x_server_params_hash( 508818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->rl.tls_version, conn->client_random, 509818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->server_random, server_params, 510818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt server_params_end - server_params, hash); 511818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 512818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 513818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (hlen < 0) 514818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt goto fail; 515818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ServerKeyExchange hash", 516818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hash, hlen); 517818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 518818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (tls_verify_signature(conn->rl.tls_version, 519818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->server_rsa_key, 520818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hash, hlen, pos, end - pos, 521818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt &alert) < 0) 522818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt goto fail; 523818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Processing DH params failed"); 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_client_free_dh(conn); 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct, 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_suite *suite; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerKeyExchange " 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(Left=%lu)", (unsigned long) left); 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerKeyExchange " 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_certificate_request(conn, ct, in_data, 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_server_hello_done(conn, ct, in_data, 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE) { 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ServerKeyExchange/" 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CertificateRequest/ServerHelloDone)", type); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ServerKeyExchange"); 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) { 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not allowed " 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "with the selected cipher suite"); 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: ServerKeyExchange", pos, len); 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = tls_get_cipher_suite(conn->rl.cipher_suite); 602818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (suite && (suite->key_exchange == TLS_KEY_X_DH_anon || 603818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt suite->key_exchange == TLS_KEY_X_DHE_RSA)) { 604818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (tlsv1_process_diffie_hellman(conn, pos, len, 605818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt suite->key_exchange) < 0) { 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: UnexpectedServerKeyExchange"); 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_CERTIFICATE_REQUEST; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct, 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateRequest " 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(left=%lu)", (unsigned long) left); 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in CertificateRequest " 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_server_hello_done(conn, ct, in_data, 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) { 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected CertificateRequest/" 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ServerHelloDone)", type); 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateRequest"); 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->certificate_requested = 1; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_HELLO_DONE; 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct, 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerHelloDone " 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(left=%lu)", (unsigned long) left); 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerHelloDone " 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) { 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ServerHelloDone)", type); 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHelloDone"); 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_KEY_EXCHANGE; 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_change_cipher_spec(struct tlsv1_client *conn, 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ct, const u8 *in_data, 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *in_len) 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) { 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; " 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->use_session_ticket) { 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Server may have " 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "rejected SessionTicket"); 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->use_session_ticket = 0; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Notify upper layers that SessionTicket failed */ 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = conn->session_ticket_cb( 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx, NULL, 0, NULL, 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL); 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket " 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "callback indicated failure"); 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_HANDSHAKE_FAILURE); 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_CERTIFICATE; 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_certificate(conn, ct, in_data, 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 1) { 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec"); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_CHANGE_CIPHER_SPEC) { 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; " 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received data 0x%x", *pos); 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec"); 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_change_read_cipher(&conn->rl) < 0) { 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher " 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for record layer"); 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = pos + 1 - in_data; 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_FINISHED; 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_finished(struct tlsv1_client *conn, u8 ct, 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, hlen; 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 verify_data[TLS_VERIFY_DATA_LEN]; 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN]; 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; " 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for " 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Finished", 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) left); 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) { 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received " 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "type 0x%x", pos[0]); 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos + 1); 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished " 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu > left=%lu)", 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len != TLS_VERIFY_DATA_LEN) { 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length " 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in Finished: %lu (expected %d)", 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, TLS_VERIFY_DATA_LEN); 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished", 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, TLS_VERIFY_DATA_LEN); 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 8791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->rl.tls_version >= TLS_VERSION_1_2) { 8801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = SHA256_MAC_LEN; 8811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->verify.sha256_server == NULL || 8821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_finish(conn->verify.sha256_server, hash, &hlen) 8831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt < 0) { 8841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_server = NULL; 8871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 8881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_server = NULL; 8901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 8911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 8921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = MD5_MAC_LEN; 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.md5_server == NULL || 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) { 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_server = NULL; 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_server, NULL, NULL); 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_server = NULL; 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = SHA1_MAC_LEN; 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.sha1_server == NULL || 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN, 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hlen) < 0) { 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 9141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = MD5_MAC_LEN + SHA1_MAC_LEN; 9151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 9171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (tls_prf(conn->rl.tls_version, 9211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->master_secret, TLS_MASTER_SECRET_LEN, 9221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "server finished", hash, hlen, 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN)) { 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data"); 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)", 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN); 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) { 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data"); 934818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 935818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received Finished"); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = (conn->session_resumed || conn->use_session_ticket) ? 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CHANGE_CIPHER_SPEC : ACK_FINISHED; 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_application_data(struct tlsv1_client *conn, u8 ct, 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len, 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **out_data, size_t *out_len) 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) { 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Application Data; " 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: Application Data included in Handshake", 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, left); 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_data = os_malloc(left); 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*out_data) { 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(*out_data, pos, left); 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = left; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_client_process_handshake(struct tlsv1_client *conn, u8 ct, 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t *len, 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **out_data, size_t *out_len) 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_ALERT) { 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*len < 2) { 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow"); 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d", 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0], buf[1]); 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 2; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = FAILED; 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_HANDSHAKE && *len >= 4 && 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] == TLS_HANDSHAKE_TYPE_HELLO_REQUEST) { 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t hr_len = WPA_GET_BE24(buf + 1); 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hr_len > *len - 4) { 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: HelloRequest underflow"); 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Ignored HelloRequest"); 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 4 + hr_len; 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (conn->state) { 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_HELLO: 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_hello(conn, ct, buf, len)) 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_CERTIFICATE: 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate(conn, ct, buf, len)) 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_KEY_EXCHANGE: 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_key_exchange(conn, ct, buf, len)) 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_CERTIFICATE_REQUEST: 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate_request(conn, ct, buf, len)) 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_HELLO_DONE: 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_hello_done(conn, ct, buf, len)) 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_CHANGE_CIPHER_SPEC: 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_change_cipher_spec(conn, ct, buf, len)) 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_FINISHED: 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_finished(conn, ct, buf, len)) 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case ACK_FINISHED: 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data && 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_process_application_data(conn, ct, buf, len, out_data, 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_len)) 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d " 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "while processing received message", 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state); 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_HANDSHAKE) 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, buf, *len); 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1060