18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TLSv1 client - 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_client.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_client_i.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct, 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len); 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct, 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len); 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct, 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len); 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_hello(struct tlsv1_client *conn, u8 ct, 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, i; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 cipher_suite; 361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u16 tls_version; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_HANDSHAKE_TYPE_SERVER_HELLO) { 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ServerHello)", *pos); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHello"); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length */ 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - ServerHello */ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ServerHello", pos, len); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ProtocolVersion server_version */ 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tls_version = WPA_GET_BE16(pos); 791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!tls_version_ok(tls_version)) { 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in " 811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "ServerHello %u.%u", pos[0], pos[1]); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_PROTOCOL_VERSION); 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Using TLS v%s", 891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tls_version_str(tls_version)); 901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->rl.tls_version = tls_version; 911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Random random */ 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < TLS_RANDOM_LEN) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->server_random, pos, TLS_RANDOM_LEN); 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RANDOM_LEN; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: server_random", 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->server_random, TLS_RANDOM_LEN); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SessionID session_id */ 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1) 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN) 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_id_len && conn->session_id_len == *pos && 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conn->session_id, pos + 1, conn->session_id_len) == 0) { 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 1 + conn->session_id_len; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Resuming old session"); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_resumed = 1; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_id_len = *pos; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->session_id, pos, conn->session_id_len); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->session_id_len; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id", 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_id, conn->session_id_len); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CipherSuite cipher_suite */ 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher_suite = WPA_GET_BE16(pos); 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < conn->num_cipher_suites; i++) { 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cipher_suite == conn->cipher_suites[i]) 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i == conn->num_cipher_suites) { 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected " 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cipher suite 0x%04x", cipher_suite); 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_resumed && cipher_suite != conn->prev_cipher_suite) { 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Server selected a different " 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cipher suite for a resumed connection (0x%04x != " 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "0x%04x)", cipher_suite, conn->prev_cipher_suite); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) { 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for " 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "record layer"); 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->prev_cipher_suite = cipher_suite; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CompressionMethod compression_method */ 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1) 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_COMPRESSION_NULL) { 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected " 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "compression 0x%02x", *pos); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end != pos) { 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: ServerHello extensions */ 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: Unexpected extra data in the " 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "end of ServerHello", pos, end - pos); 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket_included && conn->session_ticket_cb) { 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: include SessionTicket extension if one was included in 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ServerHello */ 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = conn->session_ticket_cb( 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx, NULL, 0, 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_random, conn->server_random, 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->master_secret); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback " 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "indicated failure"); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_HANDSHAKE_FAILURE); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->use_session_ticket = !!res; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((conn->session_resumed || conn->use_session_ticket) && 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_derive_keys(conn, NULL, 0)) { 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys"); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = (conn->session_resumed || conn->use_session_ticket) ? 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SERVER_CHANGE_CIPHER_SPEC : SERVER_CERTIFICATE; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdecode_error: 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ServerHello"); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate(struct tlsv1_client *conn, u8 ct, 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, list_len, cert_len, idx; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct x509_certificate *chain = NULL, *last = NULL, *cert; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reason; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message " 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu)", (unsigned long) left); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message " 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE) 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_server_key_exchange(conn, ct, in_data, 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_certificate_request(conn, ct, in_data, 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_server_hello_done(conn, ct, in_data, 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) { 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected Certificate/" 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ServerKeyExchange/CertificateRequest/" 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ServerHelloDone)", type); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TLSv1: Received Certificate (certificate_list len %lu)", 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque ASN.1Cert<2^24-1>; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ASN.1Cert certificate_list<1..2^24-1>; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } Certificate; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate " 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(left=%lu)", (unsigned long) left); 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list_len = WPA_GET_BE24(pos); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) (end - pos) != list_len) { 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list " 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu left=%lu)", 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) list_len, 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (end - pos)); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = 0; 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate_list"); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert_len = WPA_GET_BE24(pos); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) (end - pos) < cert_len) { 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate " 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu left=%lu)", 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) cert_len, 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (end - pos)); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)", 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) idx, (unsigned long) cert_len); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (idx == 0) { 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_public_key_free(conn->server_rsa_key); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_parse_cert(pos, cert_len, 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->server_rsa_key)) { 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the certificate"); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_BAD_CERTIFICATE); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = x509_certificate_parse(pos, cert_len); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse " 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the certificate"); 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_BAD_CERTIFICATE); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (last == NULL) 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chain = cert; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last->next = cert; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last = cert; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx++; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += cert_len; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->cred && 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_validate(conn->cred->trusted_certs, chain, 369c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt &reason, conn->disable_time_checks) 370c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt < 0) { 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tls_reason; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain " 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "validation failed (reason=%d)", reason); 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (reason) { 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_BAD_CERTIFICATE: 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_BAD_CERTIFICATE; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_UNSUPPORTED_CERTIFICATE: 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_REVOKED: 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_REVOKED; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_EXPIRED: 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_UNKNOWN: 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_UNKNOWN_CA: 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_UNKNOWN_CA; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_BAD_CERTIFICATE; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason); 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_KEY_EXCHANGE; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tlsv1_process_diffie_hellman(struct tlsv1_client *conn, 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len) 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_client_free_dh(conn); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + len; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_p_len = WPA_GET_BE16(pos); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_p_len == 0 || end - pos < (int) conn->dh_p_len) { 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid dh_p length %lu", 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) conn->dh_p_len); 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_p = os_malloc(conn->dh_p_len); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_p == NULL) 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->dh_p, pos, conn->dh_p_len); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->dh_p_len; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH p (prime)", 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_p, conn->dh_p_len); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_g_len = WPA_GET_BE16(pos); 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_g_len == 0 || end - pos < (int) conn->dh_g_len) 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_g = os_malloc(conn->dh_g_len); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_g == NULL) 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->dh_g, pos, conn->dh_g_len); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->dh_g_len; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH g (generator)", 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_g, conn->dh_g_len); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_g_len == 1 && conn->dh_g[0] < 2) 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_ys_len = WPA_GET_BE16(pos); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_ys_len == 0 || end - pos < (int) conn->dh_ys_len) 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_ys = os_malloc(conn->dh_ys_len); 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->dh_ys == NULL) 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->dh_ys, pos, conn->dh_ys_len); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->dh_ys_len; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)", 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_ys, conn->dh_ys_len); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Processing DH params failed"); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_client_free_dh(conn); 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct, 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_suite *suite; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerKeyExchange " 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(Left=%lu)", (unsigned long) left); 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerKeyExchange " 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_certificate_request(conn, ct, in_data, 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_server_hello_done(conn, ct, in_data, 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE) { 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ServerKeyExchange/" 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CertificateRequest/ServerHelloDone)", type); 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ServerKeyExchange"); 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) { 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not allowed " 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "with the selected cipher suite"); 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: ServerKeyExchange", pos, len); 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = tls_get_cipher_suite(conn->rl.cipher_suite); 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (suite && suite->key_exchange == TLS_KEY_X_DH_anon) { 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_process_diffie_hellman(conn, pos, len) < 0) { 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: UnexpectedServerKeyExchange"); 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_CERTIFICATE_REQUEST; 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct, 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateRequest " 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(left=%lu)", (unsigned long) left); 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in CertificateRequest " 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_server_hello_done(conn, ct, in_data, 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) { 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected CertificateRequest/" 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ServerHelloDone)", type); 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateRequest"); 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->certificate_requested = 1; 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_HELLO_DONE; 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct, 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; " 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerHelloDone " 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(left=%lu)", (unsigned long) left); 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerHelloDone " 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length (len=%lu != left=%lu)", 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) { 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake " 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message %d (expected ServerHelloDone)", type); 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHelloDone"); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_KEY_EXCHANGE; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_change_cipher_spec(struct tlsv1_client *conn, 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ct, const u8 *in_data, 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *in_len) 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) { 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; " 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->use_session_ticket) { 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Server may have " 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "rejected SessionTicket"); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->use_session_ticket = 0; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Notify upper layers that SessionTicket failed */ 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = conn->session_ticket_cb( 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx, NULL, 0, NULL, 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL); 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket " 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "callback indicated failure"); 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_HANDSHAKE_FAILURE); 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_CERTIFICATE; 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_certificate(conn, ct, in_data, 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 1) { 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec"); 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_CHANGE_CIPHER_SPEC) { 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; " 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received data 0x%x", *pos); 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec"); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_change_read_cipher(&conn->rl) < 0) { 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher " 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for record layer"); 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = pos + 1 - in_data; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_FINISHED; 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_server_finished(struct tlsv1_client *conn, u8 ct, 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, hlen; 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 verify_data[TLS_VERIFY_DATA_LEN]; 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN]; 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; " 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for " 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Finished", 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) left); 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) { 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received " 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "type 0x%x", pos[0]); 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos + 1); 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished " 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu > left=%lu)", 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) left); 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len != TLS_VERIFY_DATA_LEN) { 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length " 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in Finished: %lu (expected %d)", 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, TLS_VERIFY_DATA_LEN); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished", 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, TLS_VERIFY_DATA_LEN); 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 8211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->rl.tls_version >= TLS_VERSION_1_2) { 8221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = SHA256_MAC_LEN; 8231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->verify.sha256_server == NULL || 8241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_finish(conn->verify.sha256_server, hash, &hlen) 8251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt < 0) { 8261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_server = NULL; 8291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 8301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_server = NULL; 8321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 8331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 8341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = MD5_MAC_LEN; 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.md5_server == NULL || 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) { 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_server = NULL; 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_server, NULL, NULL); 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_server = NULL; 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = SHA1_MAC_LEN; 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.sha1_server == NULL || 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN, 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hlen) < 0) { 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_server = NULL; 8561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = MD5_MAC_LEN + SHA1_MAC_LEN; 8571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 8591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (tls_prf(conn->rl.tls_version, 8631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->master_secret, TLS_MASTER_SECRET_LEN, 8641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "server finished", hash, hlen, 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN)) { 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data"); 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)", 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN); 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) { 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data"); 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received Finished"); 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = (conn->session_resumed || conn->use_session_ticket) ? 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CHANGE_CIPHER_SPEC : ACK_FINISHED; 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_application_data(struct tlsv1_client *conn, u8 ct, 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len, 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **out_data, size_t *out_len) 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) { 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Application Data; " 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received content type 0x%x", ct); 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: Application Data included in Handshake", 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, left); 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_data = os_malloc(left); 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*out_data) { 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(*out_data, pos, left); 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = left; 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_client_process_handshake(struct tlsv1_client *conn, u8 ct, 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t *len, 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 **out_data, size_t *out_len) 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_ALERT) { 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*len < 2) { 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow"); 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d", 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0], buf[1]); 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 2; 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = FAILED; 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_HANDSHAKE && *len >= 4 && 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] == TLS_HANDSHAKE_TYPE_HELLO_REQUEST) { 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t hr_len = WPA_GET_BE24(buf + 1); 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hr_len > *len - 4) { 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: HelloRequest underflow"); 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_alert(conn, TLS_ALERT_LEVEL_FATAL, 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Ignored HelloRequest"); 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 4 + hr_len; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (conn->state) { 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_HELLO: 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_hello(conn, ct, buf, len)) 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_CERTIFICATE: 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate(conn, ct, buf, len)) 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_KEY_EXCHANGE: 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_key_exchange(conn, ct, buf, len)) 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_CERTIFICATE_REQUEST: 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate_request(conn, ct, buf, len)) 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_HELLO_DONE: 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_hello_done(conn, ct, buf, len)) 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_CHANGE_CIPHER_SPEC: 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_change_cipher_spec(conn, ct, buf, len)) 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SERVER_FINISHED: 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_server_finished(conn, ct, buf, len)) 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case ACK_FINISHED: 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data && 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_process_application_data(conn, ct, buf, len, out_data, 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_len)) 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d " 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "while processing received message", 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state); 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_HANDSHAKE) 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, buf, *len); 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1000