tlsv1_server_read.c revision 8d520ff1dc2da35cdca849e982051b86468016d8
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TLSv1 server - read handshake message 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify 68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation. 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license. 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details. 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/md5.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha1.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/tls.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "x509v3.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_common.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_record.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_server.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_server_i.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct, 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len); 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_change_cipher_spec(struct tlsv1_server *conn, 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ct, const u8 *in_data, 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *in_len); 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_hello(struct tlsv1_server *conn, u8 ct, 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end, *c; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, i, j; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 cipher_suite; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 num_suites; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int compr_null_found; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 ext_type, ext_len; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) { 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ClientHello)", *pos); 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ClientHello"); 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length */ 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - ClientHello */ 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello", pos, len); 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ProtocolVersion client_version */ 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_version = WPA_GET_BE16(pos); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Client version %d.%d", 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_version >> 8, conn->client_version & 0xff); 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->client_version < TLS_VERSION) { 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in " 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ClientHello"); 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_PROTOCOL_VERSION); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Random random */ 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < TLS_RANDOM_LEN) 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->client_random, pos, TLS_RANDOM_LEN); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RANDOM_LEN; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client_random", 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_random, TLS_RANDOM_LEN); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SessionID session_id */ 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1) 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN) 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client session_id", pos + 1, *pos); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 1 + *pos; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for session resumption */ 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CipherSuite cipher_suites<2..2^16-1> */ 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites = WPA_GET_BE16(pos); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < num_suites) 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client cipher suites", 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, num_suites); 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_suites & 1) 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites /= 2; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher_suite = 0; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; !cipher_suite && i < conn->num_cipher_suites; i++) { 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = pos; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < num_suites; j++) { 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 tmp = WPA_GET_BE16(c); 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c += 2; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cipher_suite && tmp == conn->cipher_suites[i]) { 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher_suite = tmp; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += num_suites * 2; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cipher_suite) { 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: No supported cipher suite " 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available"); 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) { 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for " 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "record layer"); 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cipher_suite = cipher_suite; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CompressionMethod compression_methods<1..2^8-1> */ 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1) 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites = *pos++; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < num_suites) 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client compression_methods", 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, num_suites); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt compr_null_found = 0; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_suites; i++) { 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos++ == TLS_COMPRESSION_NULL) 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt compr_null_found = 1; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!compr_null_found) { 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Client does not accept NULL " 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "compression"); 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos == 1) { 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected extra octet in the " 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "end of ClientHello: 0x%02x", *pos); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos >= 2) { 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Extension client_hello_extension_list<0..2^16-1> */ 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_len = WPA_GET_BE16(pos); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: %u bytes of ClientHello " 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extensions", ext_len); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos != ext_len) { 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid ClientHello " 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension list length %u (expected %u)", 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_len, (unsigned int) (end - pos)); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ExtensionType extension_type (0..65535) 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque extension_data<0..2^16-1> 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } Extension; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) { 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid " 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension_type field"); 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_type = WPA_GET_BE16(pos); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) { 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid " 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension_data length field"); 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_len = WPA_GET_BE16(pos); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < ext_len) { 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid " 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension_data field"); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: ClientHello Extension " 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "type %u", ext_type); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello " 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Extension data", pos, ext_len); 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ext_type == TLS_EXT_SESSION_TICKET) { 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = os_malloc(ext_len); 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket) { 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->session_ticket, pos, 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_len); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len = ext_len; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ext_len; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: ClientHello OK - proceed to " 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ServerHello"); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_HELLO; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdecode_error: 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ClientHello"); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate(struct tlsv1_server *conn, u8 ct, 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, list_len, cert_len, idx; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct x509_certificate *chain = NULL, *last = NULL, *cert; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reason; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message " 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu)", (unsigned long) left); 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message " 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) { 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify_peer) { 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Client did not include " 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Certificate"); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_client_key_exchange(conn, ct, in_data, 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) { 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected Certificate/" 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ClientKeyExchange)", type); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TLSv1: Received Certificate (certificate_list len %lu)", 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque ASN.1Cert<2^24-1>; 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ASN.1Cert certificate_list<1..2^24-1>; 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } Certificate; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate " 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(left=%lu)", (unsigned long) left); 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list_len = WPA_GET_BE24(pos); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) (end - pos) != list_len) { 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list " 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu left=%lu)", 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) list_len, 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (end - pos)); 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = 0; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate_list"); 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert_len = WPA_GET_BE24(pos); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) (end - pos) < cert_len) { 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate " 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu left=%lu)", 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) cert_len, 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (end - pos)); 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)", 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) idx, (unsigned long) cert_len); 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (idx == 0) { 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_public_key_free(conn->client_rsa_key); 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_parse_cert(pos, cert_len, 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->client_rsa_key)) { 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the certificate"); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_BAD_CERTIFICATE); 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = x509_certificate_parse(pos, cert_len); 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the certificate"); 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_BAD_CERTIFICATE); 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (last == NULL) 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chain = cert; 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last->next = cert; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last = cert; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx++; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += cert_len; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (x509_certificate_chain_validate(conn->cred->trusted_certs, chain, 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &reason) < 0) { 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tls_reason; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain " 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "validation failed (reason=%d)", reason); 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (reason) { 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_BAD_CERTIFICATE: 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_BAD_CERTIFICATE; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_UNSUPPORTED_CERTIFICATE: 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_REVOKED: 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_REVOKED; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_EXPIRED: 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_UNKNOWN: 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN; 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_UNKNOWN_CA: 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_UNKNOWN_CA; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_BAD_CERTIFICATE; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_KEY_EXCHANGE; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_key_exchange_rsa( 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tlsv1_server *conn, const u8 *pos, const u8 *end) 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t outlen, outbuflen; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 encr_len; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int use_random = 0; 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) { 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr_len = WPA_GET_BE16(pos); 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbuflen = outlen = end - pos; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out = os_malloc(outlen >= TLS_PRE_MASTER_SECRET_LEN ? 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outlen : TLS_PRE_MASTER_SECRET_LEN); 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out == NULL) { 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ProtocolVersion client_version; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque random[46]; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } PreMasterSecret; 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * public-key-encrypted PreMasterSecret pre_master_secret; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } EncryptedPreMasterSecret; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: To avoid Bleichenbacher attack, we do not report decryption or 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parsing errors from EncryptedPreMasterSecret processing to the 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * client. Instead, a random pre-master secret is used to force the 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake to fail. 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_private_key_decrypt_pkcs1_v15(conn->cred->key, 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos, 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out, &outlen) < 0) { 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt " 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PreMasterSecret (encr_len=%d outlen=%lu)", 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) (end - pos), (unsigned long) outlen); 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt use_random = 1; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (outlen != TLS_PRE_MASTER_SECRET_LEN) { 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected PreMasterSecret " 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length %lu", (unsigned long) outlen); 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt use_random = 1; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE16(out) != conn->client_version) { 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Client version in " 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ClientKeyExchange does not match with version in " 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ClientHello"); 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt use_random = 1; 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (use_random) { 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Using random premaster secret " 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to avoid revealing information about private key"); 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outlen = TLS_PRE_MASTER_SECRET_LEN; 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_get_random(out, outlen)) { 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random " 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data"); 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(out); 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tlsv1_server_derive_keys(conn, out, outlen); 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Clear the pre-master secret since it is not needed anymore */ 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(out, 0, outbuflen); 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(out); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys"); 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_key_exchange_dh_anon( 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tlsv1_server *conn, const u8 *pos, const u8 *end) 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dh_yc; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 dh_yc_len; 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *shared; 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t shared_len; 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * select (PublicValueEncoding) { 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case implicit: struct { }; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case explicit: opaque dh_Yc<1..2^16-1>; 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } dh_public; 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } ClientDiffieHellmanPublic; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientDiffieHellmanPublic", 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos); 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == pos) { 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Implicit public value encoding " 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not supported"); 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid client public value " 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length"); 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_yc_len = WPA_GET_BE16(pos); 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_yc = pos + 2; 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_yc + dh_yc_len > end) { 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Client public value overflow " 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(length %d)", dh_yc_len); 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH Yc (client's public value)", 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_yc, dh_yc_len); 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->cred == NULL || conn->cred->dh_p == NULL || 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret == NULL) { 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available"); 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared_len = conn->cred->dh_p_len; 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared = os_malloc(shared_len); 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (shared == NULL) { 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Could not allocate memory for " 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "DH"); 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* shared = Yc^secret mod p */ 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_mod_exp(dh_yc, dh_yc_len, conn->dh_secret, 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret_len, 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cred->dh_p, conn->cred->dh_p_len, 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared, &shared_len)) { 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(shared); 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: Shared secret from DH key exchange", 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared, shared_len); 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(conn->dh_secret, 0, conn->dh_secret_len); 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->dh_secret); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret = NULL; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tlsv1_server_derive_keys(conn, shared, shared_len); 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Clear the pre-master secret since it is not needed anymore */ 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(shared, 0, shared_len); 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(shared); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys"); 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct, 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_key_exchange keyx; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_suite *suite; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ClientKeyExchange " 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(Left=%lu)", (unsigned long) left); 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ClientKeyExchange " 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) { 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ClientKeyExchange)", type); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ClientKeyExchange"); 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: ClientKeyExchange", pos, len); 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = tls_get_cipher_suite(conn->rl.cipher_suite); 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (suite == NULL) 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyx = TLS_KEY_X_NULL; 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyx = suite->key_exchange; 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keyx == TLS_KEY_X_DH_anon && 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_process_client_key_exchange_dh_anon(conn, pos, end) < 0) 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keyx != TLS_KEY_X_DH_anon && 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_process_client_key_exchange_rsa(conn, pos, end) < 0) 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CERTIFICATE_VERIFY; 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate_verify(struct tlsv1_server *conn, u8 ct, 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t hlen, buflen; 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN], *hpos, *buf; 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { SIGN_ALG_RSA, SIGN_ALG_DSA } alg = SIGN_ALG_RSA; 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 slen; 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) { 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify_peer) { 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Client did not include " 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CertificateVerify"); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_change_cipher_spec(conn, ct, in_data, 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateVerify " 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message (len=%lu)", (unsigned long) left); 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected CertificateVerify " 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message length (len=%lu != left=%lu)", 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY) { 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected CertificateVerify)", type); 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateVerify"); 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Signature signature; 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } CertificateVerify; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hpos = hash; 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alg == SIGN_ALG_RSA) { 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = MD5_MAC_LEN; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.md5_cert == NULL || 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_cert, hpos, &hlen) < 0) 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_cert = NULL; 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_cert, NULL, NULL); 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_cert = NULL; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hpos += MD5_MAC_LEN; 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_cert, NULL, NULL); 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_cert = NULL; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = SHA1_MAC_LEN; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.sha1_cert == NULL || 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_cert, hpos, &hlen) < 0) { 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_cert = NULL; 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_cert = NULL; 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alg == SIGN_ALG_RSA) 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen += MD5_MAC_LEN; 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: CertificateVerify hash", hash, hlen); 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) { 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt slen = WPA_GET_BE16(pos); 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < slen) { 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: Signature", pos, end - pos); 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->client_rsa_key == NULL) { 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No client public key to verify " 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "signature"); 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = end - pos; 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(end - pos); 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_public_key_decrypt_pkcs1(conn->client_rsa_key, 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos, buf, &buflen) < 0) 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt signature"); 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Decrypted Signature", 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, buflen); 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buflen != hlen || os_memcmp(buf, hash, buflen) != 0) { 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid Signature in " 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CertificateVerify - did not match with calculated " 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash"); 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CHANGE_CIPHER_SPEC; 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_change_cipher_spec(struct tlsv1_server *conn, 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ct, const u8 *in_data, 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *in_len) 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) { 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; " 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 1) { 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec"); 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_CHANGE_CIPHER_SPEC) { 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; " 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received data 0x%x", *pos); 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec"); 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_change_read_cipher(&conn->rl) < 0) { 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher " 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for record layer"); 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = pos + 1 - in_data; 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_FINISHED; 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_finished(struct tlsv1_server *conn, u8 ct, 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, hlen; 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 verify_data[TLS_VERIFY_DATA_LEN]; 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN]; 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; " 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for " 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Finished", 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) left); 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) { 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received " 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "type 0x%x", pos[0]); 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos + 1); 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished " 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu > left=%lu)", 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len != TLS_VERIFY_DATA_LEN) { 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length " 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in Finished: %lu (expected %d)", 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, TLS_VERIFY_DATA_LEN); 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished", 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, TLS_VERIFY_DATA_LEN); 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = MD5_MAC_LEN; 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.md5_client == NULL || 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_client, hash, &hlen) < 0) { 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_client = NULL; 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_client, NULL, NULL); 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_client = NULL; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_client = NULL; 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = SHA1_MAC_LEN; 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.sha1_client == NULL || 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_client, hash + MD5_MAC_LEN, 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hlen) < 0) { 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_client = NULL; 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_client = NULL; 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN, 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "client finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN, 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN)) { 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data"); 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)", 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN); 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) { 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data"); 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received Finished"); 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->use_session_ticket) { 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Abbreviated handshake using session ticket; RFC 4507 */ 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Abbreviated handshake completed " 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "successfully"); 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = ESTABLISHED; 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Full handshake */ 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_CHANGE_CIPHER_SPEC; 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_process_handshake(struct tlsv1_server *conn, u8 ct, 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t *len) 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_ALERT) { 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*len < 2) { 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow"); 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d", 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0], buf[1]); 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 2; 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = FAILED; 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (conn->state) { 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_HELLO: 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_client_hello(conn, ct, buf, len)) 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_CERTIFICATE: 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate(conn, ct, buf, len)) 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_KEY_EXCHANGE: 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_client_key_exchange(conn, ct, buf, len)) 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CERTIFICATE_VERIFY: 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate_verify(conn, ct, buf, len)) 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CHANGE_CIPHER_SPEC: 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_change_cipher_spec(conn, ct, buf, len)) 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_FINISHED: 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_client_finished(conn, ct, buf, len)) 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d " 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "while processing received message", 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state); 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_HANDSHAKE) 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, buf, *len); 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1135