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 412b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtstatic unsigned int count_bits(const u8 *val, size_t len) 413b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt{ 414b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt size_t i; 415b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt unsigned int bits; 416b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt u8 tmp; 417b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 418b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt for (i = 0; i < len; i++) { 419b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (val[i]) 420b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 421b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 422b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (i == len) 423b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt return 0; 424b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 425b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt bits = (len - i - 1) * 8; 426b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt tmp = val[i]; 427b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt while (tmp) { 428b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt bits++; 429b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt tmp >>= 1; 430b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 431b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 432b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt return bits; 433b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt} 434b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 435b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tlsv1_process_diffie_hellman(struct tlsv1_client *conn, 437818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt const u8 *buf, size_t len, 438818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tls_key_exchange key_exchange) 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 440818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt const u8 *pos, *end, *server_params, *server_params_end; 441818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 alert; 442b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt unsigned int bits; 443fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt u16 val; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_client_free_dh(conn); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + len; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 452818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt server_params = pos; 453fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt val = WPA_GET_BE16(pos); 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 455fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (val == 0 || val > (size_t) (end - pos)) { 456fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid dh_p length %u", val); 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 459fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt conn->dh_p_len = val; 460b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt bits = count_bits(pos, conn->dh_p_len); 461b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (bits < 768) { 462b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Reject under 768-bit DH prime (insecure; only %u bits)", 463b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt bits); 464b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: Rejected DH prime", 465b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt pos, conn->dh_p_len); 466b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 467b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_p = os_malloc(conn->dh_p_len); 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_p == NULL) 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->dh_p, pos, conn->dh_p_len); 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->dh_p_len; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH p (prime)", 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_p, conn->dh_p_len); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 478fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt val = WPA_GET_BE16(pos); 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 480fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (val == 0 || val > (size_t) (end - pos)) 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 482fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt conn->dh_g_len = val; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_g = os_malloc(conn->dh_g_len); 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_g == NULL) 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->dh_g, pos, conn->dh_g_len); 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->dh_g_len; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH g (generator)", 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_g, conn->dh_g_len); 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_g_len == 1 && conn->dh_g[0] < 2) 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 495fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt val = WPA_GET_BE16(pos); 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 497fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (val == 0 || val > (size_t) (end - pos)) 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 499fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt conn->dh_ys_len = val; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_ys = os_malloc(conn->dh_ys_len); 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_ys == NULL) 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->dh_ys, pos, conn->dh_ys_len); 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->dh_ys_len; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)", 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_ys, conn->dh_ys_len); 507818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt server_params_end = pos; 508818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 509818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (key_exchange == TLS_KEY_X_DHE_RSA) { 510818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN]; 511818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt int hlen; 512818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 513818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conn->rl.tls_version == TLS_VERSION_1_2) { 514818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TLSV12 515818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt /* 516818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * RFC 5246, 4.7: 517818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * TLS v1.2 adds explicit indication of the used 518818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * signature and hash algorithms. 519818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * 520818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * struct { 521818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * HashAlgorithm hash; 522818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * SignatureAlgorithm signature; 523818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * } SignatureAndHashAlgorithm; 524818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt */ 525818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (end - pos < 2) 526818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt goto fail; 527818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (pos[0] != TLS_HASH_ALG_SHA256 || 528818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos[1] != TLS_SIGN_ALG_RSA) { 529818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1.2: Unsupported hash(%u)/signature(%u) algorithm", 530818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos[0], pos[1]); 531818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt goto fail; 532818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 533818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos += 2; 534818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 535818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hlen = tlsv12_key_x_server_params_hash( 536818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->rl.tls_version, conn->client_random, 537818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->server_random, server_params, 538818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt server_params_end - server_params, hash); 539818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#else /* CONFIG_TLSV12 */ 540818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt goto fail; 541818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TLSV12 */ 542818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } else { 543818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hlen = tls_key_x_server_params_hash( 544818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->rl.tls_version, conn->client_random, 545818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->server_random, server_params, 546818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt server_params_end - server_params, hash); 547818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 548818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 549818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (hlen < 0) 550818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt goto fail; 551818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ServerKeyExchange hash", 552818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hash, hlen); 553818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 554818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (tls_verify_signature(conn->rl.tls_version, 555818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->server_rsa_key, 556818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hash, hlen, pos, end - pos, 557818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt &alert) < 0) 558818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt goto fail; 559818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Processing DH params failed"); 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_client_free_dh(conn); 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct, 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_suite *suite; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerKeyExchange " 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(Left=%lu)", (unsigned long) left); 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerKeyExchange " 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_certificate_request(conn, ct, in_data, 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_server_hello_done(conn, ct, in_data, 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE) { 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ServerKeyExchange/" 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CertificateRequest/ServerHelloDone)", type); 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ServerKeyExchange"); 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) { 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not allowed " 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "with the selected cipher suite"); 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: ServerKeyExchange", pos, len); 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = tls_get_cipher_suite(conn->rl.cipher_suite); 638818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (suite && (suite->key_exchange == TLS_KEY_X_DH_anon || 639818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt suite->key_exchange == TLS_KEY_X_DHE_RSA)) { 640818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (tlsv1_process_diffie_hellman(conn, pos, len, 641818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt suite->key_exchange) < 0) { 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: UnexpectedServerKeyExchange"); 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_CERTIFICATE_REQUEST; 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct, 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateRequest " 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(left=%lu)", (unsigned long) left); 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in CertificateRequest " 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_server_hello_done(conn, ct, in_data, 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) { 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected CertificateRequest/" 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ServerHelloDone)", type); 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateRequest"); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->certificate_requested = 1; 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_HELLO_DONE; 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct, 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerHelloDone " 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(left=%lu)", (unsigned long) left); 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerHelloDone " 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) { 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ServerHelloDone)", type); 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHelloDone"); 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_KEY_EXCHANGE; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_change_cipher_spec(struct tlsv1_client *conn, 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ct, const u8 *in_data, 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *in_len) 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) { 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; " 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->use_session_ticket) { 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Server may have " 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "rejected SessionTicket"); 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->use_session_ticket = 0; 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Notify upper layers that SessionTicket failed */ 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = conn->session_ticket_cb( 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx, NULL, 0, NULL, 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL); 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket " 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "callback indicated failure"); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_HANDSHAKE_FAILURE); 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_CERTIFICATE; 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_certificate(conn, ct, in_data, 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 1) { 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec"); 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_CHANGE_CIPHER_SPEC) { 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; " 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received data 0x%x", *pos); 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec"); 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_change_read_cipher(&conn->rl) < 0) { 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher " 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for record layer"); 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = pos + 1 - in_data; 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_FINISHED; 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_finished(struct tlsv1_client *conn, u8 ct, 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, hlen; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 verify_data[TLS_VERIFY_DATA_LEN]; 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN]; 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; " 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for " 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Finished", 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) left); 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) { 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received " 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "type 0x%x", pos[0]); 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos + 1); 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished " 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu > left=%lu)", 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len != TLS_VERIFY_DATA_LEN) { 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length " 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in Finished: %lu (expected %d)", 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, TLS_VERIFY_DATA_LEN); 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished", 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, TLS_VERIFY_DATA_LEN); 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 9151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->rl.tls_version >= TLS_VERSION_1_2) { 9161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = SHA256_MAC_LEN; 9171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->verify.sha256_server == NULL || 9181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_finish(conn->verify.sha256_server, hash, &hlen) 9191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt < 0) { 9201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 9221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_server = NULL; 9231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 9241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_server = NULL; 9261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 9271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 9281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = MD5_MAC_LEN; 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.md5_server == NULL || 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) { 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_server = NULL; 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_server, NULL, NULL); 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_server = NULL; 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = SHA1_MAC_LEN; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.sha1_server == NULL || 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN, 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hlen) < 0) { 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 9501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = MD5_MAC_LEN + SHA1_MAC_LEN; 9511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 9531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (tls_prf(conn->rl.tls_version, 9571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->master_secret, TLS_MASTER_SECRET_LEN, 9581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "server finished", hash, hlen, 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN)) { 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data"); 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)", 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN); 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (os_memcmp_const(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) { 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data"); 970818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 971818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received Finished"); 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = (conn->session_resumed || conn->use_session_ticket) ? 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CHANGE_CIPHER_SPEC : ACK_FINISHED; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_application_data(struct tlsv1_client *conn, u8 ct, 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len, 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **out_data, size_t *out_len) 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) { 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Application Data; " 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: Application Data included in Handshake", 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, left); 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_data = os_malloc(left); 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*out_data) { 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(*out_data, pos, left); 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = left; 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_client_process_handshake(struct tlsv1_client *conn, u8 ct, 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t *len, 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **out_data, size_t *out_len) 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_ALERT) { 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*len < 2) { 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow"); 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d", 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0], buf[1]); 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 2; 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = FAILED; 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_HANDSHAKE && *len >= 4 && 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] == TLS_HANDSHAKE_TYPE_HELLO_REQUEST) { 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t hr_len = WPA_GET_BE24(buf + 1); 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hr_len > *len - 4) { 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: HelloRequest underflow"); 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Ignored HelloRequest"); 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 4 + hr_len; 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (conn->state) { 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_HELLO: 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_hello(conn, ct, buf, len)) 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_CERTIFICATE: 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate(conn, ct, buf, len)) 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_KEY_EXCHANGE: 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_key_exchange(conn, ct, buf, len)) 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_CERTIFICATE_REQUEST: 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate_request(conn, ct, buf, len)) 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_HELLO_DONE: 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_hello_done(conn, ct, buf, len)) 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_CHANGE_CIPHER_SPEC: 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_change_cipher_spec(conn, ct, buf, len)) 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_FINISHED: 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_finished(conn, ct, buf, len)) 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case ACK_FINISHED: 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data && 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_process_application_data(conn, ct, buf, len, out_data, 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_len)) 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d " 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "while processing received message", 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state); 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_HANDSHAKE) 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, buf, *len); 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1096