18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TLSv1 server - read handshake message 31f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Copyright (c) 2006-2011, 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_server.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_server_i.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct, 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len); 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_change_cipher_spec(struct tlsv1_server *conn, 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ct, const u8 *in_data, 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *in_len); 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_hello(struct tlsv1_server *conn, u8 ct, 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end, *c; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, i, j; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 cipher_suite; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 num_suites; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int compr_null_found; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 ext_type, ext_len; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) { 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ClientHello)", *pos); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ClientHello"); 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length */ 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - ClientHello */ 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello", pos, len); 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ProtocolVersion client_version */ 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_version = WPA_GET_BE16(pos); 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Client version %d.%d", 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_version >> 8, conn->client_version & 0xff); 831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->client_version < TLS_VERSION_1) { 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in " 851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "ClientHello %u.%u", 861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->client_version >> 8, 871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->client_version & 0xff); 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_PROTOCOL_VERSION); 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (TLS_VERSION == TLS_VERSION_1) 951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->rl.tls_version = TLS_VERSION_1; 961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (conn->client_version >= TLS_VERSION_1_2) 981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->rl.tls_version = TLS_VERSION_1_2; 991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 1001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (conn->client_version > TLS_VERSION_1_1) 1011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->rl.tls_version = TLS_VERSION_1_1; 1021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 1031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->rl.tls_version = conn->client_version; 1041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Using TLS v%s", 1051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tls_version_str(conn->rl.tls_version)); 1061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Random random */ 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < TLS_RANDOM_LEN) 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->client_random, pos, TLS_RANDOM_LEN); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RANDOM_LEN; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client_random", 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_random, TLS_RANDOM_LEN); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SessionID session_id */ 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1) 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN) 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client session_id", pos + 1, *pos); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 1 + *pos; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for session resumption */ 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CipherSuite cipher_suites<2..2^16-1> */ 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites = WPA_GET_BE16(pos); 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < num_suites) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client cipher suites", 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, num_suites); 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_suites & 1) 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites /= 2; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher_suite = 0; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; !cipher_suite && i < conn->num_cipher_suites; i++) { 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = pos; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < num_suites; j++) { 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 tmp = WPA_GET_BE16(c); 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c += 2; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cipher_suite && tmp == conn->cipher_suites[i]) { 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher_suite = tmp; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += num_suites * 2; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cipher_suite) { 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: No supported cipher suite " 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available"); 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) { 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for " 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "record layer"); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cipher_suite = cipher_suite; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CompressionMethod compression_methods<1..2^8-1> */ 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1) 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites = *pos++; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < num_suites) 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client compression_methods", 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, num_suites); 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt compr_null_found = 0; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_suites; i++) { 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos++ == TLS_COMPRESSION_NULL) 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt compr_null_found = 1; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!compr_null_found) { 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Client does not accept NULL " 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "compression"); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos == 1) { 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected extra octet in the " 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "end of ClientHello: 0x%02x", *pos); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos >= 2) { 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Extension client_hello_extension_list<0..2^16-1> */ 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_len = WPA_GET_BE16(pos); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: %u bytes of ClientHello " 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extensions", ext_len); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos != ext_len) { 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid ClientHello " 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension list length %u (expected %u)", 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_len, (unsigned int) (end - pos)); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ExtensionType extension_type (0..65535) 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque extension_data<0..2^16-1> 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } Extension; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) { 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid " 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension_type field"); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_type = WPA_GET_BE16(pos); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) { 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid " 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension_data length field"); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_len = WPA_GET_BE16(pos); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < ext_len) { 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid " 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension_data field"); 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: ClientHello Extension " 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "type %u", ext_type); 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello " 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Extension data", pos, ext_len); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ext_type == TLS_EXT_SESSION_TICKET) { 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = os_malloc(ext_len); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket) { 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->session_ticket, pos, 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_len); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len = ext_len; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ext_len; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: ClientHello OK - proceed to " 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ServerHello"); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_HELLO; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdecode_error: 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ClientHello"); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate(struct tlsv1_server *conn, u8 ct, 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, list_len, cert_len, idx; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct x509_certificate *chain = NULL, *last = NULL, *cert; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reason; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message " 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu)", (unsigned long) left); 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message " 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) { 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify_peer) { 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Client did not include " 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Certificate"); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_client_key_exchange(conn, ct, in_data, 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) { 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected Certificate/" 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ClientKeyExchange)", type); 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TLSv1: Received Certificate (certificate_list len %lu)", 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque ASN.1Cert<2^24-1>; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ASN.1Cert certificate_list<1..2^24-1>; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } Certificate; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate " 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(left=%lu)", (unsigned long) left); 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list_len = WPA_GET_BE24(pos); 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) (end - pos) != list_len) { 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list " 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu left=%lu)", 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) list_len, 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (end - pos)); 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = 0; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate_list"); 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert_len = WPA_GET_BE24(pos); 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) (end - pos) < cert_len) { 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate " 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu left=%lu)", 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) cert_len, 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (end - pos)); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)", 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) idx, (unsigned long) cert_len); 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (idx == 0) { 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_public_key_free(conn->client_rsa_key); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_parse_cert(pos, cert_len, 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->client_rsa_key)) { 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the certificate"); 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_BAD_CERTIFICATE); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = x509_certificate_parse(pos, cert_len); 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the certificate"); 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_BAD_CERTIFICATE); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (last == NULL) 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chain = cert; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last->next = cert; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last = cert; 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx++; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += cert_len; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (x509_certificate_chain_validate(conn->cred->trusted_certs, chain, 437c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt &reason, 0) < 0) { 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tls_reason; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain " 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "validation failed (reason=%d)", reason); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (reason) { 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_BAD_CERTIFICATE: 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_BAD_CERTIFICATE; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_UNSUPPORTED_CERTIFICATE: 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_REVOKED: 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_REVOKED; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_EXPIRED: 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_UNKNOWN: 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN; 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_UNKNOWN_CA: 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_UNKNOWN_CA; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_BAD_CERTIFICATE; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_KEY_EXCHANGE; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_key_exchange_rsa( 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tlsv1_server *conn, const u8 *pos, const u8 *end) 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t outlen, outbuflen; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 encr_len; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int use_random = 0; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) { 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr_len = WPA_GET_BE16(pos); 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 4961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (pos + encr_len > end) { 4971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid ClientKeyExchange " 4981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "format: encr_len=%u left=%u", 4991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt encr_len, (unsigned int) (end - pos)); 5001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_DECODE_ERROR); 5021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 5031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbuflen = outlen = end - pos; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out = os_malloc(outlen >= TLS_PRE_MASTER_SECRET_LEN ? 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outlen : TLS_PRE_MASTER_SECRET_LEN); 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out == NULL) { 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ProtocolVersion client_version; 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque random[46]; 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } PreMasterSecret; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * public-key-encrypted PreMasterSecret pre_master_secret; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } EncryptedPreMasterSecret; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: To avoid Bleichenbacher attack, we do not report decryption or 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parsing errors from EncryptedPreMasterSecret processing to the 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * client. Instead, a random pre-master secret is used to force the 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake to fail. 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_private_key_decrypt_pkcs1_v15(conn->cred->key, 5331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos, encr_len, 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out, &outlen) < 0) { 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt " 5361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "PreMasterSecret (encr_len=%u outlen=%lu)", 5371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt encr_len, (unsigned long) outlen); 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt use_random = 1; 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!use_random && outlen != TLS_PRE_MASTER_SECRET_LEN) { 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected PreMasterSecret " 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length %lu", (unsigned long) outlen); 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt use_random = 1; 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!use_random && WPA_GET_BE16(out) != conn->client_version) { 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Client version in " 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ClientKeyExchange does not match with version in " 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ClientHello"); 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt use_random = 1; 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (use_random) { 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Using random premaster secret " 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to avoid revealing information about private key"); 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outlen = TLS_PRE_MASTER_SECRET_LEN; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_get_random(out, outlen)) { 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random " 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data"); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(out); 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tlsv1_server_derive_keys(conn, out, outlen); 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Clear the pre-master secret since it is not needed anymore */ 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(out, 0, outbuflen); 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(out); 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys"); 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_key_exchange_dh_anon( 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tlsv1_server *conn, const u8 *pos, const u8 *end) 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dh_yc; 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 dh_yc_len; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *shared; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t shared_len; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * select (PublicValueEncoding) { 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case implicit: struct { }; 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case explicit: opaque dh_Yc<1..2^16-1>; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } dh_public; 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } ClientDiffieHellmanPublic; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientDiffieHellmanPublic", 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos); 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == pos) { 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Implicit public value encoding " 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not supported"); 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid client public value " 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length"); 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_yc_len = WPA_GET_BE16(pos); 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_yc = pos + 2; 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_yc + dh_yc_len > end) { 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Client public value overflow " 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(length %d)", dh_yc_len); 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH Yc (client's public value)", 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_yc, dh_yc_len); 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->cred == NULL || conn->cred->dh_p == NULL || 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret == NULL) { 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available"); 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared_len = conn->cred->dh_p_len; 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared = os_malloc(shared_len); 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (shared == NULL) { 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Could not allocate memory for " 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "DH"); 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* shared = Yc^secret mod p */ 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_mod_exp(dh_yc, dh_yc_len, conn->dh_secret, 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret_len, 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cred->dh_p, conn->cred->dh_p_len, 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared, &shared_len)) { 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(shared); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: Shared secret from DH key exchange", 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared, shared_len); 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(conn->dh_secret, 0, conn->dh_secret_len); 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->dh_secret); 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret = NULL; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tlsv1_server_derive_keys(conn, shared, shared_len); 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Clear the pre-master secret since it is not needed anymore */ 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(shared, 0, shared_len); 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(shared); 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys"); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct, 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_key_exchange keyx; 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_suite *suite; 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ClientKeyExchange " 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(Left=%lu)", (unsigned long) left); 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ClientKeyExchange " 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) { 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ClientKeyExchange)", type); 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ClientKeyExchange"); 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: ClientKeyExchange", pos, len); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = tls_get_cipher_suite(conn->rl.cipher_suite); 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (suite == NULL) 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyx = TLS_KEY_X_NULL; 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyx = suite->key_exchange; 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keyx == TLS_KEY_X_DH_anon && 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_process_client_key_exchange_dh_anon(conn, pos, end) < 0) 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keyx != TLS_KEY_X_DH_anon && 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_process_client_key_exchange_rsa(conn, pos, end) < 0) 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CERTIFICATE_VERIFY; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate_verify(struct tlsv1_server *conn, u8 ct, 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t hlen, buflen; 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN], *hpos, *buf; 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { SIGN_ALG_RSA, SIGN_ALG_DSA } alg = SIGN_ALG_RSA; 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 slen; 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) { 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify_peer) { 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Client did not include " 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CertificateVerify"); 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_change_cipher_spec(conn, ct, in_data, 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateVerify " 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message (len=%lu)", (unsigned long) left); 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected CertificateVerify " 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message length (len=%lu != left=%lu)", 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY) { 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected CertificateVerify)", type); 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateVerify"); 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Signature signature; 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } CertificateVerify; 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hpos = hash; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 8441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->rl.tls_version == TLS_VERSION_1_2) { 8451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 8461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * RFC 5246, 4.7: 8471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * TLS v1.2 adds explicit indication of the used signature and 8481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * hash algorithms. 8491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 8501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * struct { 8511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * HashAlgorithm hash; 8521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * SignatureAlgorithm signature; 8531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * } SignatureAndHashAlgorithm; 8541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 8551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (end - pos < 2) { 8561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_DECODE_ERROR); 8581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 8591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (pos[0] != TLS_HASH_ALG_SHA256 || 8611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos[1] != TLS_SIGN_ALG_RSA) { 8621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1.2: Unsupported hash(%u)/" 8631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "signature(%u) algorithm", 8641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos[0], pos[1]); 8651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 8681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos += 2; 8701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = SHA256_MAC_LEN; 8721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->verify.sha256_cert == NULL || 8731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_finish(conn->verify.sha256_cert, hpos, &hlen) < 8741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 0) { 8751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_cert = NULL; 8761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 8791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_cert = NULL; 8811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 8821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 8831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alg == SIGN_ALG_RSA) { 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = MD5_MAC_LEN; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.md5_cert == NULL || 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_cert, hpos, &hlen) < 0) 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_cert = NULL; 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_cert, NULL, NULL); 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_cert = NULL; 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hpos += MD5_MAC_LEN; 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_cert, NULL, NULL); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_cert = NULL; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = SHA1_MAC_LEN; 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.sha1_cert == NULL || 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_cert, hpos, &hlen) < 0) { 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_cert = NULL; 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_cert = NULL; 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alg == SIGN_ALG_RSA) 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen += MD5_MAC_LEN; 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 9151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 9171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: CertificateVerify hash", hash, hlen); 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) { 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt slen = WPA_GET_BE16(pos); 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < slen) { 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: Signature", pos, end - pos); 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->client_rsa_key == NULL) { 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No client public key to verify " 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "signature"); 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = end - pos; 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(end - pos); 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_public_key_decrypt_pkcs1(conn->client_rsa_key, 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos, buf, &buflen) < 0) 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt signature"); 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Decrypted Signature", 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, buflen); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 9581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->rl.tls_version >= TLS_VERSION_1_2) { 9591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 9601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * RFC 3447, A.2.4 RSASSA-PKCS1-v1_5 9611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 9621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * DigestInfo ::= SEQUENCE { 9631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * digestAlgorithm DigestAlgorithm, 9641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * digest OCTET STRING 9651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * } 9661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 9671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * SHA-256 OID: sha256WithRSAEncryption ::= {pkcs-1 11} 9681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 9691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * DER encoded DigestInfo for SHA256 per RFC 3447: 9701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 || 9711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * H 9721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 9731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (buflen >= 19 + 32 && 9741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcmp(buf, "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01" 9751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "\x65\x03\x04\x02\x01\x05\x00\x04\x20", 19) == 0) 9761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt { 9771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1.2: DigestAlgorithn = " 9781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "SHA-256"); 9791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memmove(buf, buf + 19, buflen - 19); 9801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt buflen -= 19; 9811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 9821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1.2: Unrecognized " 9831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "DigestInfo"); 9841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(buf); 9851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 9871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 9881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 9911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buflen != hlen || os_memcmp(buf, hash, buflen) != 0) { 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid Signature in " 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CertificateVerify - did not match with calculated " 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash"); 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CHANGE_CIPHER_SPEC; 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_change_cipher_spec(struct tlsv1_server *conn, 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ct, const u8 *in_data, 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *in_len) 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) { 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; " 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 1) { 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec"); 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_CHANGE_CIPHER_SPEC) { 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; " 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received data 0x%x", *pos); 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec"); 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_change_read_cipher(&conn->rl) < 0) { 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher " 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for record layer"); 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = pos + 1 - in_data; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_FINISHED; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_finished(struct tlsv1_server *conn, u8 ct, 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, hlen; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 verify_data[TLS_VERIFY_DATA_LEN]; 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN]; 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; " 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for " 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Finished", 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) left); 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) { 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received " 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "type 0x%x", pos[0]); 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos + 1); 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished " 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu > left=%lu)", 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len != TLS_VERIFY_DATA_LEN) { 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length " 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in Finished: %lu (expected %d)", 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, TLS_VERIFY_DATA_LEN); 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished", 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, TLS_VERIFY_DATA_LEN); 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 11241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->rl.tls_version >= TLS_VERSION_1_2) { 11251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = SHA256_MAC_LEN; 11261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->verify.sha256_client == NULL || 11271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_finish(conn->verify.sha256_client, hash, &hlen) 11281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt < 0) { 11291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 11311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_client = NULL; 11321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 11331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_client = NULL; 11351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 11361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 11371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = MD5_MAC_LEN; 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.md5_client == NULL || 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_client, hash, &hlen) < 0) { 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_client = NULL; 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_client, NULL, NULL); 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_client = NULL; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_client = NULL; 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = SHA1_MAC_LEN; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.sha1_client == NULL || 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_client, hash + MD5_MAC_LEN, 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hlen) < 0) { 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_client = NULL; 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_client = NULL; 11591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = MD5_MAC_LEN + SHA1_MAC_LEN; 11601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 11621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (tls_prf(conn->rl.tls_version, 11661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->master_secret, TLS_MASTER_SECRET_LEN, 11671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "client finished", hash, hlen, 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN)) { 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data"); 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)", 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN); 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) { 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data"); 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received Finished"); 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->use_session_ticket) { 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Abbreviated handshake using session ticket; RFC 4507 */ 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Abbreviated handshake completed " 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "successfully"); 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = ESTABLISHED; 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Full handshake */ 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_CHANGE_CIPHER_SPEC; 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_process_handshake(struct tlsv1_server *conn, u8 ct, 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t *len) 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_ALERT) { 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*len < 2) { 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow"); 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d", 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0], buf[1]); 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 2; 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = FAILED; 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (conn->state) { 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_HELLO: 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_client_hello(conn, ct, buf, len)) 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_CERTIFICATE: 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate(conn, ct, buf, len)) 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_KEY_EXCHANGE: 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_client_key_exchange(conn, ct, buf, len)) 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CERTIFICATE_VERIFY: 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate_verify(conn, ct, buf, len)) 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CHANGE_CIPHER_SPEC: 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_change_cipher_spec(conn, ct, buf, len)) 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_FINISHED: 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_client_finished(conn, ct, buf, len)) 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d " 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "while processing received message", 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state); 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_HANDSHAKE) 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, buf, *len); 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1254