18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TLSv1 server - read handshake message 3818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/md5.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha1.h" 141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "crypto/sha256.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/tls.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "x509v3.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_common.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_record.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_server.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_server_i.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct, 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len); 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_change_cipher_spec(struct tlsv1_server *conn, 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ct, const u8 *in_data, 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *in_len); 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtstatic int testing_cipher_suite_filter(struct tlsv1_server *conn, u16 suite) 31818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{ 32818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 33818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if ((conn->test_flags & 34b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt (TLS_BREAK_SRV_KEY_X_HASH | TLS_BREAK_SRV_KEY_X_SIGNATURE | 35b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt TLS_DHE_PRIME_511B | TLS_DHE_PRIME_767B | TLS_DHE_PRIME_15 | 36b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt TLS_DHE_PRIME_58B | TLS_DHE_NON_PRIME)) && 37818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt suite != TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 && 38818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt suite != TLS_DHE_RSA_WITH_AES_256_CBC_SHA && 39818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt suite != TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 && 40818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt suite != TLS_DHE_RSA_WITH_AES_128_CBC_SHA && 41818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt suite != TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) 42818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return 1; 43818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 44818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 45818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return 0; 46818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt} 47818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 48818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 49d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidtstatic void tls_process_status_request_item(struct tlsv1_server *conn, 50d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt const u8 *req, size_t req_len) 51d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt{ 52d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt const u8 *pos, *end; 53d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt u8 status_type; 54d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 55d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos = req; 56d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt end = req + req_len; 57d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 58d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* 59d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * RFC 6961, 2.2: 60d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * struct { 61d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * CertificateStatusType status_type; 62d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * uint16 request_length; 63d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * select (status_type) { 64d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * case ocsp: OCSPStatusRequest; 65d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * case ocsp_multi: OCSPStatusRequest; 66d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * } request; 67d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * } CertificateStatusRequestItemV2; 68d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * 69d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * enum { ocsp(1), ocsp_multi(2), (255) } CertificateStatusType; 70d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt */ 71d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 72d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (end - pos < 1) 73d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt return; /* Truncated data */ 74d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 75d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt status_type = *pos++; 76d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: CertificateStatusType %u", status_type); 77d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (status_type != 1 && status_type != 2) 78d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt return; /* Unsupported status type */ 79d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* 80d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * For now, only OCSP stapling is supported, so ignore the specific 81d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * request, if any. 82d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt */ 83d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: OCSPStatusRequest", pos, end - pos); 84d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 85d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (status_type == 2) 86d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt conn->status_request_multi = 1; 87d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt} 88d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 89d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 90d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidtstatic void tls_process_status_request_v2(struct tlsv1_server *conn, 91d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt const u8 *ext, size_t ext_len) 92d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt{ 93d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt const u8 *pos, *end; 94d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 95d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt conn->status_request_v2 = 1; 96d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 97d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos = ext; 98d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt end = ext + ext_len; 99d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 100d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt /* 101d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * RFC 6961, 2.2: 102d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * struct { 103d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * CertificateStatusRequestItemV2 104d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * certificate_status_req_list<1..2^16-1>; 105d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt * } CertificateStatusRequestListV2; 106d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt */ 107d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 108d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt while (end - pos >= 2) { 109d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt u16 len; 110d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 111d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt len = WPA_GET_BE16(pos); 112d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos += 2; 113d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (len > end - pos) 114d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt break; /* Truncated data */ 115d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt tls_process_status_request_item(conn, pos, len); 116d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt pos += len; 117d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 118d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt} 119d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 120d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_hello(struct tlsv1_server *conn, u8 ct, 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end, *c; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, i, j; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 cipher_suite; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 num_suites; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int compr_null_found; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 ext_type, ext_len; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 132818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Expected Handshake; received content type 0x%x", 133818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt ct); 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* HandshakeType msg_type */ 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) { 147818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Received unexpected handshake message %d (expected ClientHello)", 148818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt *pos); 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 153818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Received ClientHello"); 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint24 length */ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* body - ClientHello */ 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello", pos, len); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ProtocolVersion client_version */ 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_version = WPA_GET_BE16(pos); 172818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Client version %d.%d", 173818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->client_version >> 8, 174818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->client_version & 0xff); 1751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->client_version < TLS_VERSION_1) { 176818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Unexpected protocol version in ClientHello %u.%u", 177818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->client_version >> 8, 178818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->client_version & 0xff); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_PROTOCOL_VERSION); 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (TLS_VERSION == TLS_VERSION_1) 1861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->rl.tls_version = TLS_VERSION_1; 1871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 1881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (conn->client_version >= TLS_VERSION_1_2) 1891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->rl.tls_version = TLS_VERSION_1_2; 1901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 1911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else if (conn->client_version > TLS_VERSION_1_1) 1921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->rl.tls_version = TLS_VERSION_1_1; 1931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 1941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->rl.tls_version = conn->client_version; 195818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Using TLS v%s", 196818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tls_version_str(conn->rl.tls_version)); 1971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Random random */ 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < TLS_RANDOM_LEN) 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->client_random, pos, TLS_RANDOM_LEN); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += TLS_RANDOM_LEN; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client_random", 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_random, TLS_RANDOM_LEN); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SessionID session_id */ 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1) 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN) 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client session_id", pos + 1, *pos); 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 1 + *pos; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for session resumption */ 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CipherSuite cipher_suites<2..2^16-1> */ 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites = WPA_GET_BE16(pos); 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < num_suites) 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client cipher suites", 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, num_suites); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_suites & 1) 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites /= 2; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher_suite = 0; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; !cipher_suite && i < conn->num_cipher_suites; i++) { 231818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (testing_cipher_suite_filter(conn, conn->cipher_suites[i])) 232818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt continue; 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = pos; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < num_suites; j++) { 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 tmp = WPA_GET_BE16(c); 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c += 2; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cipher_suite && tmp == conn->cipher_suites[i]) { 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher_suite = tmp; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += num_suites * 2; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cipher_suite) { 245818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "No supported cipher suite available"); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) { 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for " 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "record layer"); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cipher_suite = cipher_suite; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* CompressionMethod compression_methods<1..2^8-1> */ 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1) 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_suites = *pos++; 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < num_suites) 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: client compression_methods", 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, num_suites); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt compr_null_found = 0; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_suites; i++) { 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos++ == TLS_COMPRESSION_NULL) 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt compr_null_found = 1; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!compr_null_found) { 275818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Client does not accept NULL compression"); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_ILLEGAL_PARAMETER); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos == 1) { 282818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Unexpected extra octet in the end of ClientHello: 0x%02x", 283818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt *pos); 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos >= 2) { 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Extension client_hello_extension_list<0..2^16-1> */ 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_len = WPA_GET_BE16(pos); 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 292818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "%u bytes of ClientHello extensions", 293818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt ext_len); 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos != ext_len) { 295818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Invalid ClientHello extension list length %u (expected %u)", 296818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt ext_len, (unsigned int) (end - pos)); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ExtensionType extension_type (0..65535) 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque extension_data<0..2^16-1> 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } Extension; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) { 309818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Invalid extension_type field"); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_type = WPA_GET_BE16(pos); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) { 317818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Invalid extension_data length field"); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_len = WPA_GET_BE16(pos); 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < ext_len) { 325818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Invalid extension_data field"); 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto decode_error; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 329818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "ClientHello Extension type %u", 330818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt ext_type); 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello " 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Extension data", pos, ext_len); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ext_type == TLS_EXT_SESSION_TICKET) { 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = os_malloc(ext_len); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket) { 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->session_ticket, pos, 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext_len); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len = ext_len; 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 342d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } else if (ext_type == TLS_EXT_STATUS_REQUEST) { 343d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt conn->status_request = 1; 344d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } else if (ext_type == TLS_EXT_STATUS_REQUEST_V2) { 345d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt tls_process_status_request_v2(conn, pos, 346d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt ext_len); 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ext_len; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 355818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "ClientHello OK - proceed to ServerHello"); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_HELLO; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdecode_error: 361818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Failed to decode ClientHello"); 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate(struct tlsv1_server *conn, u8 ct, 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, list_len, cert_len, idx; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct x509_certificate *chain = NULL, *last = NULL, *cert; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reason; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 378818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Expected Handshake; received content type 0x%x", 379818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt ct); 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 389818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Too short Certificate message (len=%lu)", 390818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) left); 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 402818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Unexpected Certificate message length (len=%lu != left=%lu)", 403818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) len, (unsigned long) left); 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) { 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify_peer) { 411818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Client did not include Certificate"); 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_client_key_exchange(conn, ct, in_data, 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) { 421818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Received unexpected handshake message %d (expected Certificate/ClientKeyExchange)", 422818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt type); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 428818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Received Certificate (certificate_list len %lu)", 429818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) len); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque ASN.1Cert<2^24-1>; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ASN.1Cert certificate_list<1..2^24-1>; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } Certificate; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 442818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Too short Certificate (left=%lu)", 443818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) left); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt list_len = WPA_GET_BE24(pos); 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) (end - pos) != list_len) { 453818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Unexpected certificate_list length (len=%lu left=%lu)", 454818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) list_len, 455818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) (end - pos)); 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = 0; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 464818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Failed to parse certificate_list"); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert_len = WPA_GET_BE24(pos); 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) (end - pos) < cert_len) { 475818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Unexpected certificate length (len=%lu left=%lu)", 476818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) cert_len, 477818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) (end - pos)); 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 484818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Certificate %lu (len %lu)", 485818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) idx, (unsigned long) cert_len); 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (idx == 0) { 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_public_key_free(conn->client_rsa_key); 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_parse_cert(pos, cert_len, 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->client_rsa_key)) { 491818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Failed to parse the certificate"); 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_BAD_CERTIFICATE); 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = x509_certificate_parse(pos, cert_len); 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 501818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Failed to parse the certificate"); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_BAD_CERTIFICATE); 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (last == NULL) 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chain = cert; 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last->next = cert; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last = cert; 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx++; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += cert_len; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (x509_certificate_chain_validate(conn->cred->trusted_certs, chain, 519c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt &reason, 0) < 0) { 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tls_reason; 521818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Server certificate chain validation failed (reason=%d)", 522818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt reason); 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (reason) { 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_BAD_CERTIFICATE: 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_BAD_CERTIFICATE; 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_UNSUPPORTED_CERTIFICATE: 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE; 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_REVOKED: 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_REVOKED; 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_EXPIRED: 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED; 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_CERTIFICATE_UNKNOWN: 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN; 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_VALIDATE_UNKNOWN_CA: 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_UNKNOWN_CA; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_reason = TLS_ALERT_BAD_CERTIFICATE; 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason); 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 548d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt return -1; 549d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt } 550d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt 551d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt if (chain && (chain->extensions_present & X509_EXT_EXT_KEY_USAGE) && 552d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt !(chain->ext_key_usage & 553d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt (X509_EXT_KEY_USAGE_ANY | X509_EXT_KEY_USAGE_CLIENT_AUTH))) { 554d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 555d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt TLS_ALERT_BAD_CERTIFICATE); 556d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt x509_certificate_chain_free(chain); 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509_certificate_chain_free(chain); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_KEY_EXCHANGE; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_key_exchange_rsa( 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tlsv1_server *conn, const u8 *pos, const u8 *end) 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out; 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t outlen, outbuflen; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 encr_len; 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int use_random = 0; 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 2) { 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr_len = WPA_GET_BE16(pos); 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 5871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (pos + encr_len > end) { 588818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Invalid ClientKeyExchange format: encr_len=%u left=%u", 589818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt encr_len, (unsigned int) (end - pos)); 5901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 5911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_DECODE_ERROR); 5921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 5931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbuflen = outlen = end - pos; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out = os_malloc(outlen >= TLS_PRE_MASTER_SECRET_LEN ? 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outlen : TLS_PRE_MASTER_SECRET_LEN); 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out == NULL) { 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ProtocolVersion client_version; 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * opaque random[46]; 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } PreMasterSecret; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * public-key-encrypted PreMasterSecret pre_master_secret; 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } EncryptedPreMasterSecret; 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: To avoid Bleichenbacher attack, we do not report decryption or 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * parsing errors from EncryptedPreMasterSecret processing to the 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * client. Instead, a random pre-master secret is used to force the 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake to fail. 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_private_key_decrypt_pkcs1_v15(conn->cred->key, 6231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos, encr_len, 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out, &outlen) < 0) { 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt " 6261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "PreMasterSecret (encr_len=%u outlen=%lu)", 6271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt encr_len, (unsigned long) outlen); 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt use_random = 1; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!use_random && outlen != TLS_PRE_MASTER_SECRET_LEN) { 632818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Unexpected PreMasterSecret length %lu", 633818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) outlen); 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt use_random = 1; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!use_random && WPA_GET_BE16(out) != conn->client_version) { 638818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Client version in ClientKeyExchange does not match with version in ClientHello"); 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt use_random = 1; 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (use_random) { 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Using random premaster secret " 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to avoid revealing information about private key"); 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outlen = TLS_PRE_MASTER_SECRET_LEN; 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_get_random(out, outlen)) { 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random " 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data"); 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(out); 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tlsv1_server_derive_keys(conn, out, outlen); 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Clear the pre-master secret since it is not needed anymore */ 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(out, 0, outbuflen); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(out); 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys"); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 673818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtstatic int tls_process_client_key_exchange_dh( 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tlsv1_server *conn, const u8 *pos, const u8 *end) 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dh_yc; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 dh_yc_len; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *shared; 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t shared_len; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 681b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt const u8 *dh_p; 682b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt size_t dh_p_len; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * select (PublicValueEncoding) { 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case implicit: struct { }; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case explicit: opaque dh_Yc<1..2^16-1>; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } dh_public; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } ClientDiffieHellmanPublic; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 693818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "ClientDiffieHellmanPublic received"); 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientDiffieHellmanPublic", 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end - pos); 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == pos) { 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Implicit public value encoding " 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not supported"); 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) { 706818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Invalid client public value length"); 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_yc_len = WPA_GET_BE16(pos); 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_yc = pos + 2; 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (dh_yc_len > end - dh_yc) { 716818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Client public value overflow (length %d)", 717818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt dh_yc_len); 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: DH Yc (client's public value)", 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_yc, dh_yc_len); 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->cred == NULL || conn->cred->dh_p == NULL || 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret == NULL) { 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available"); 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 734b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt tlsv1_server_get_dh_p(conn, &dh_p, &dh_p_len); 735b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 736b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt shared_len = dh_p_len; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared = os_malloc(shared_len); 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (shared == NULL) { 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Could not allocate memory for " 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "DH"); 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* shared = Yc^secret mod p */ 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_mod_exp(dh_yc, dh_yc_len, conn->dh_secret, 748b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt conn->dh_secret_len, dh_p, dh_p_len, 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared, &shared_len)) { 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(shared); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: Shared secret from DH key exchange", 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared, shared_len); 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(conn->dh_secret, 0, conn->dh_secret_len); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->dh_secret); 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret = NULL; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = tlsv1_server_derive_keys(conn, shared, shared_len); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Clear the pre-master secret since it is not needed anymore */ 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(shared, 0, shared_len); 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(shared); 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys"); 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct, 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_key_exchange keyx; 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_suite *suite; 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 789818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Expected Handshake; received content type 0x%x", 790818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt ct); 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 800818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Too short ClientKeyExchange (Left=%lu)", 801818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) left); 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 813818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Mismatch in ClientKeyExchange length (len=%lu != left=%lu)", 814818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) len, (unsigned long) left); 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) { 823818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Received unexpected handshake message %d (expected ClientKeyExchange)", 824818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt type); 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 830818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Received ClientKeyExchange"); 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLSv1: ClientKeyExchange", pos, len); 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = tls_get_cipher_suite(conn->rl.cipher_suite); 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (suite == NULL) 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyx = TLS_KEY_X_NULL; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keyx = suite->key_exchange; 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 840818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if ((keyx == TLS_KEY_X_DH_anon || keyx == TLS_KEY_X_DHE_RSA) && 841818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tls_process_client_key_exchange_dh(conn, pos, end) < 0) 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 844818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (keyx != TLS_KEY_X_DH_anon && keyx != TLS_KEY_X_DHE_RSA && 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_process_client_key_exchange_rsa(conn, pos, end) < 0) 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CERTIFICATE_VERIFY; 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_certificate_verify(struct tlsv1_server *conn, u8 ct, 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len; 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 862818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt size_t hlen; 863818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN], *hpos; 864818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt u8 alert; 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) { 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify_peer) { 868818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Client did not include CertificateVerify"); 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_process_change_cipher_spec(conn, ct, in_data, 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len); 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 879818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Expected Handshake; received content type 0x%x", 880818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt ct); 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 890818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Too short CertificateVerify message (len=%lu)", 891818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) left); 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = *pos++; 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 903818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Unexpected CertificateVerify message length (len=%lu != left=%lu)", 904818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) len, (unsigned long) left); 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY) { 913818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Received unexpected handshake message %d (expected CertificateVerify)", 914818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt type); 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 920818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Received CertificateVerify"); 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct { 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Signature signature; 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * } CertificateVerify; 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hpos = hash; 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 9311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->rl.tls_version == TLS_VERSION_1_2) { 9321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 9331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * RFC 5246, 4.7: 9341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * TLS v1.2 adds explicit indication of the used signature and 9351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * hash algorithms. 9361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 9371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * struct { 9381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * HashAlgorithm hash; 9391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * SignatureAlgorithm signature; 9401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * } SignatureAndHashAlgorithm; 9411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 9421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (end - pos < 2) { 9431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_DECODE_ERROR); 9451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 9461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (pos[0] != TLS_HASH_ALG_SHA256 || 9481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos[1] != TLS_SIGN_ALG_RSA) { 9491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1.2: Unsupported hash(%u)/" 9501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "signature(%u) algorithm", 9511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos[0], pos[1]); 9521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 9541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 9551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos += 2; 9571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = SHA256_MAC_LEN; 9591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->verify.sha256_cert == NULL || 9601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_finish(conn->verify.sha256_cert, hpos, &hlen) < 9611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 0) { 9621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_cert = NULL; 9631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 9651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 9661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_cert = NULL; 9681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 9691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 9701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 971203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt hlen = MD5_MAC_LEN; 972203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (conn->verify.md5_cert == NULL || 973203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt crypto_hash_finish(conn->verify.md5_cert, hpos, &hlen) < 0) { 974203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 975203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 976203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt conn->verify.md5_cert = NULL; 977203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt crypto_hash_finish(conn->verify.sha1_cert, NULL, NULL); 978203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt conn->verify.sha1_cert = NULL; 979203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt return -1; 980203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 981203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt hpos += MD5_MAC_LEN; 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_cert = NULL; 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = SHA1_MAC_LEN; 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.sha1_cert == NULL || 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_cert, hpos, &hlen) < 0) { 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_cert = NULL; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_cert = NULL; 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 994203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt hlen += MD5_MAC_LEN; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 9971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 9991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: CertificateVerify hash", hash, hlen); 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1002818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (tls_verify_signature(conn->rl.tls_version, conn->client_rsa_key, 1003818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt hash, hlen, pos, end - pos, &alert) < 0) { 1004818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Invalid Signature in CertificateVerify"); 1005818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert); 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CHANGE_CIPHER_SPEC; 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_change_cipher_spec(struct tlsv1_server *conn, 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ct, const u8 *in_data, 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *in_len) 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) { 1025818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Expected ChangeCipherSpec; received content type 0x%x", 1026818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt ct); 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 1) { 1036818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Too short ChangeCipherSpec"); 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos != TLS_CHANGE_CIPHER_SPEC) { 1043818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Expected ChangeCipherSpec; received data 0x%x", 1044818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt *pos); 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1050818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Received ChangeCipherSpec"); 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_change_read_cipher(&conn->rl) < 0) { 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher " 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for record layer"); 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = pos + 1 - in_data; 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_FINISHED; 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_process_client_finished(struct tlsv1_server *conn, u8 ct, 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t *in_len) 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left, len, hlen; 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 verify_data[TLS_VERIFY_DATA_LEN]; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN]; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1075818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 1076818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if ((conn->test_flags & 1077818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (TLS_BREAK_SRV_KEY_X_HASH | TLS_BREAK_SRV_KEY_X_SIGNATURE)) && 1078818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt !conn->test_failure_reported) { 1079818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "TEST-FAILURE: Client Finished received after invalid ServerKeyExchange"); 1080818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->test_failure_reported = 1; 1081818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 1082b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 1083b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if ((conn->test_flags & TLS_DHE_PRIME_15) && 1084b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt !conn->test_failure_reported) { 1085b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt tlsv1_server_log(conn, "TEST-FAILURE: Client Finished received after bogus DHE \"prime\" 15"); 1086b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt conn->test_failure_reported = 1; 1087b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 1088b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 1089b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if ((conn->test_flags & TLS_DHE_PRIME_58B) && 1090b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt !conn->test_failure_reported) { 1091b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt tlsv1_server_log(conn, "TEST-FAILURE: Client Finished received after short 58-bit DHE prime in long container"); 1092b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt conn->test_failure_reported = 1; 1093b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 1094b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 1095b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if ((conn->test_flags & TLS_DHE_PRIME_511B) && 1096b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt !conn->test_failure_reported) { 1097b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt tlsv1_server_log(conn, "TEST-WARNING: Client Finished received after short 511-bit DHE prime (insecure)"); 1098b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt conn->test_failure_reported = 1; 1099b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 1100b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 1101b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if ((conn->test_flags & TLS_DHE_PRIME_767B) && 1102b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt !conn->test_failure_reported) { 1103b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt tlsv1_server_log(conn, "TEST-NOTE: Client Finished received after 767-bit DHE prime (relatively insecure)"); 1104b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt conn->test_failure_reported = 1; 1105b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 1106b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 1107b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if ((conn->test_flags & TLS_DHE_NON_PRIME) && 1108b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt !conn->test_failure_reported) { 1109b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt tlsv1_server_log(conn, "TEST-NOTE: Client Finished received after non-prime claimed as DHE prime"); 1110b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt conn->test_failure_reported = 1; 1111b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 1112818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 1113818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE) { 1115818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Expected Finished; received content type 0x%x", 1116818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt ct); 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = *in_len; 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 1126818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Too short record (left=%lu) forFinished", 1127818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) left); 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) { 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received " 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "type 0x%x", pos[0]); 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = WPA_GET_BE24(pos + 1); 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > left) { 1147818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Too short buffer for Finished (len=%lu > left=%lu)", 1148818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) len, (unsigned long) left); 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + len; 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len != TLS_VERIFY_DATA_LEN) { 1155818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Unexpected verify_data length in Finished: %lu (expected %d)", 1156818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt (unsigned long) len, TLS_VERIFY_DATA_LEN); 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished", 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, TLS_VERIFY_DATA_LEN); 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 11651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->rl.tls_version >= TLS_VERSION_1_2) { 11661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = SHA256_MAC_LEN; 11671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->verify.sha256_client == NULL || 11681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_finish(conn->verify.sha256_client, hash, &hlen) 11691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt < 0) { 11701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 11721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_client = NULL; 11731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 11741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->verify.sha256_client = NULL; 11761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 11771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 11781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = MD5_MAC_LEN; 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.md5_client == NULL || 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.md5_client, hash, &hlen) < 0) { 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_client = NULL; 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_client, NULL, NULL); 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_client = NULL; 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.md5_client = NULL; 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = SHA1_MAC_LEN; 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify.sha1_client == NULL || 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(conn->verify.sha1_client, hash + MD5_MAC_LEN, 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hlen) < 0) { 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_client = NULL; 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify.sha1_client = NULL; 12001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hlen = MD5_MAC_LEN + SHA1_MAC_LEN; 12011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_TLSV12 12031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 12041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_TLSV12 */ 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (tls_prf(conn->rl.tls_version, 12071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->master_secret, TLS_MASTER_SECRET_LEN, 12081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "client finished", hash, hlen, 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN)) { 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data"); 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECRYPT_ERROR); 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)", 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_data, TLS_VERIFY_DATA_LEN); 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (os_memcmp_const(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) { 1219818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Mismatch in verify_data"); 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1223818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Received Finished"); 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *in_len = end - in_data; 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->use_session_ticket) { 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Abbreviated handshake using session ticket; RFC 4507 */ 1229818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Abbreviated handshake completed successfully"); 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = ESTABLISHED; 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Full handshake */ 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = SERVER_CHANGE_CIPHER_SPEC; 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_process_handshake(struct tlsv1_server *conn, u8 ct, 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t *len) 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_ALERT) { 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*len < 2) { 1245818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Alert underflow"); 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_DECODE_ERROR); 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1250818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Received alert %d:%d", buf[0], buf[1]); 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 2; 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = FAILED; 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (conn->state) { 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_HELLO: 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_client_hello(conn, ct, buf, len)) 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_CERTIFICATE: 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate(conn, ct, buf, len)) 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_KEY_EXCHANGE: 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_client_key_exchange(conn, ct, buf, len)) 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CERTIFICATE_VERIFY: 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_certificate_verify(conn, ct, buf, len)) 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CHANGE_CIPHER_SPEC: 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_change_cipher_spec(conn, ct, buf, len)) 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CLIENT_FINISHED: 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_process_client_finished(conn, ct, buf, len)) 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1282818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tlsv1_server_log(conn, "Unexpected state %d while processing received message", 1283818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conn->state); 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ct == TLS_CONTENT_TYPE_HANDSHAKE) 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_add(&conn->verify, buf, *len); 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1292