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