16d49e1aeSJan Lentfer /*
26d49e1aeSJan Lentfer * TLSv1 server - read handshake message
3*a1157835SDaniel Fojt * Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi>
46d49e1aeSJan Lentfer *
53ff40c12SJohn Marino * This software may be distributed under the terms of the BSD license.
63ff40c12SJohn Marino * See README for more details.
76d49e1aeSJan Lentfer */
86d49e1aeSJan Lentfer
96d49e1aeSJan Lentfer #include "includes.h"
106d49e1aeSJan Lentfer
116d49e1aeSJan Lentfer #include "common.h"
123ff40c12SJohn Marino #include "crypto/md5.h"
133ff40c12SJohn Marino #include "crypto/sha1.h"
143ff40c12SJohn Marino #include "crypto/sha256.h"
153ff40c12SJohn Marino #include "crypto/tls.h"
166d49e1aeSJan Lentfer #include "x509v3.h"
176d49e1aeSJan Lentfer #include "tlsv1_common.h"
186d49e1aeSJan Lentfer #include "tlsv1_record.h"
196d49e1aeSJan Lentfer #include "tlsv1_server.h"
206d49e1aeSJan Lentfer #include "tlsv1_server_i.h"
216d49e1aeSJan Lentfer
226d49e1aeSJan Lentfer
236d49e1aeSJan Lentfer static int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct,
246d49e1aeSJan Lentfer const u8 *in_data, size_t *in_len);
256d49e1aeSJan Lentfer static int tls_process_change_cipher_spec(struct tlsv1_server *conn,
266d49e1aeSJan Lentfer u8 ct, const u8 *in_data,
276d49e1aeSJan Lentfer size_t *in_len);
286d49e1aeSJan Lentfer
296d49e1aeSJan Lentfer
testing_cipher_suite_filter(struct tlsv1_server * conn,u16 suite)30*a1157835SDaniel Fojt static int testing_cipher_suite_filter(struct tlsv1_server *conn, u16 suite)
31*a1157835SDaniel Fojt {
32*a1157835SDaniel Fojt #ifdef CONFIG_TESTING_OPTIONS
33*a1157835SDaniel Fojt if ((conn->test_flags &
34*a1157835SDaniel Fojt (TLS_BREAK_SRV_KEY_X_HASH | TLS_BREAK_SRV_KEY_X_SIGNATURE |
35*a1157835SDaniel Fojt TLS_DHE_PRIME_511B | TLS_DHE_PRIME_767B | TLS_DHE_PRIME_15 |
36*a1157835SDaniel Fojt TLS_DHE_PRIME_58B | TLS_DHE_NON_PRIME)) &&
37*a1157835SDaniel Fojt suite != TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 &&
38*a1157835SDaniel Fojt suite != TLS_DHE_RSA_WITH_AES_256_CBC_SHA &&
39*a1157835SDaniel Fojt suite != TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 &&
40*a1157835SDaniel Fojt suite != TLS_DHE_RSA_WITH_AES_128_CBC_SHA &&
41*a1157835SDaniel Fojt suite != TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
42*a1157835SDaniel Fojt return 1;
43*a1157835SDaniel Fojt #endif /* CONFIG_TESTING_OPTIONS */
44*a1157835SDaniel Fojt
45*a1157835SDaniel Fojt return 0;
46*a1157835SDaniel Fojt }
47*a1157835SDaniel Fojt
48*a1157835SDaniel Fojt
tls_process_status_request_item(struct tlsv1_server * conn,const u8 * req,size_t req_len)49*a1157835SDaniel Fojt static void tls_process_status_request_item(struct tlsv1_server *conn,
50*a1157835SDaniel Fojt const u8 *req, size_t req_len)
51*a1157835SDaniel Fojt {
52*a1157835SDaniel Fojt const u8 *pos, *end;
53*a1157835SDaniel Fojt u8 status_type;
54*a1157835SDaniel Fojt
55*a1157835SDaniel Fojt pos = req;
56*a1157835SDaniel Fojt end = req + req_len;
57*a1157835SDaniel Fojt
58*a1157835SDaniel Fojt /*
59*a1157835SDaniel Fojt * RFC 6961, 2.2:
60*a1157835SDaniel Fojt * struct {
61*a1157835SDaniel Fojt * CertificateStatusType status_type;
62*a1157835SDaniel Fojt * uint16 request_length;
63*a1157835SDaniel Fojt * select (status_type) {
64*a1157835SDaniel Fojt * case ocsp: OCSPStatusRequest;
65*a1157835SDaniel Fojt * case ocsp_multi: OCSPStatusRequest;
66*a1157835SDaniel Fojt * } request;
67*a1157835SDaniel Fojt * } CertificateStatusRequestItemV2;
68*a1157835SDaniel Fojt *
69*a1157835SDaniel Fojt * enum { ocsp(1), ocsp_multi(2), (255) } CertificateStatusType;
70*a1157835SDaniel Fojt */
71*a1157835SDaniel Fojt
72*a1157835SDaniel Fojt if (end - pos < 1)
73*a1157835SDaniel Fojt return; /* Truncated data */
74*a1157835SDaniel Fojt
75*a1157835SDaniel Fojt status_type = *pos++;
76*a1157835SDaniel Fojt wpa_printf(MSG_DEBUG, "TLSv1: CertificateStatusType %u", status_type);
77*a1157835SDaniel Fojt if (status_type != 1 && status_type != 2)
78*a1157835SDaniel Fojt return; /* Unsupported status type */
79*a1157835SDaniel Fojt /*
80*a1157835SDaniel Fojt * For now, only OCSP stapling is supported, so ignore the specific
81*a1157835SDaniel Fojt * request, if any.
82*a1157835SDaniel Fojt */
83*a1157835SDaniel Fojt wpa_hexdump(MSG_DEBUG, "TLSv1: OCSPStatusRequest", pos, end - pos);
84*a1157835SDaniel Fojt
85*a1157835SDaniel Fojt if (status_type == 2)
86*a1157835SDaniel Fojt conn->status_request_multi = 1;
87*a1157835SDaniel Fojt }
88*a1157835SDaniel Fojt
89*a1157835SDaniel Fojt
tls_process_status_request_v2(struct tlsv1_server * conn,const u8 * ext,size_t ext_len)90*a1157835SDaniel Fojt static void tls_process_status_request_v2(struct tlsv1_server *conn,
91*a1157835SDaniel Fojt const u8 *ext, size_t ext_len)
92*a1157835SDaniel Fojt {
93*a1157835SDaniel Fojt const u8 *pos, *end;
94*a1157835SDaniel Fojt
95*a1157835SDaniel Fojt conn->status_request_v2 = 1;
96*a1157835SDaniel Fojt
97*a1157835SDaniel Fojt pos = ext;
98*a1157835SDaniel Fojt end = ext + ext_len;
99*a1157835SDaniel Fojt
100*a1157835SDaniel Fojt /*
101*a1157835SDaniel Fojt * RFC 6961, 2.2:
102*a1157835SDaniel Fojt * struct {
103*a1157835SDaniel Fojt * CertificateStatusRequestItemV2
104*a1157835SDaniel Fojt * certificate_status_req_list<1..2^16-1>;
105*a1157835SDaniel Fojt * } CertificateStatusRequestListV2;
106*a1157835SDaniel Fojt */
107*a1157835SDaniel Fojt
108*a1157835SDaniel Fojt while (end - pos >= 2) {
109*a1157835SDaniel Fojt u16 len;
110*a1157835SDaniel Fojt
111*a1157835SDaniel Fojt len = WPA_GET_BE16(pos);
112*a1157835SDaniel Fojt pos += 2;
113*a1157835SDaniel Fojt if (len > end - pos)
114*a1157835SDaniel Fojt break; /* Truncated data */
115*a1157835SDaniel Fojt tls_process_status_request_item(conn, pos, len);
116*a1157835SDaniel Fojt pos += len;
117*a1157835SDaniel Fojt }
118*a1157835SDaniel Fojt }
119*a1157835SDaniel Fojt
120*a1157835SDaniel Fojt
tls_process_client_hello(struct tlsv1_server * conn,u8 ct,const u8 * in_data,size_t * in_len)1216d49e1aeSJan Lentfer static int tls_process_client_hello(struct tlsv1_server *conn, u8 ct,
1226d49e1aeSJan Lentfer const u8 *in_data, size_t *in_len)
1236d49e1aeSJan Lentfer {
1246d49e1aeSJan Lentfer const u8 *pos, *end, *c;
1256d49e1aeSJan Lentfer size_t left, len, i, j;
1266d49e1aeSJan Lentfer u16 cipher_suite;
1276d49e1aeSJan Lentfer u16 num_suites;
1286d49e1aeSJan Lentfer int compr_null_found;
1296d49e1aeSJan Lentfer u16 ext_type, ext_len;
1306d49e1aeSJan Lentfer
1316d49e1aeSJan Lentfer if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
132*a1157835SDaniel Fojt tlsv1_server_log(conn, "Expected Handshake; received content type 0x%x",
133*a1157835SDaniel Fojt ct);
1346d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1356d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
1366d49e1aeSJan Lentfer return -1;
1376d49e1aeSJan Lentfer }
1386d49e1aeSJan Lentfer
1396d49e1aeSJan Lentfer pos = in_data;
1406d49e1aeSJan Lentfer left = *in_len;
1416d49e1aeSJan Lentfer
142*a1157835SDaniel Fojt if (left < 4) {
143*a1157835SDaniel Fojt tlsv1_server_log(conn,
144*a1157835SDaniel Fojt "Truncated handshake message (expected ClientHello)");
1456d49e1aeSJan Lentfer goto decode_error;
146*a1157835SDaniel Fojt }
1476d49e1aeSJan Lentfer
1486d49e1aeSJan Lentfer /* HandshakeType msg_type */
1496d49e1aeSJan Lentfer if (*pos != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) {
150*a1157835SDaniel Fojt tlsv1_server_log(conn, "Received unexpected handshake message %d (expected ClientHello)",
151*a1157835SDaniel Fojt *pos);
1526d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1536d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
1546d49e1aeSJan Lentfer return -1;
1556d49e1aeSJan Lentfer }
156*a1157835SDaniel Fojt tlsv1_server_log(conn, "Received ClientHello");
1576d49e1aeSJan Lentfer pos++;
1586d49e1aeSJan Lentfer /* uint24 length */
1596d49e1aeSJan Lentfer len = WPA_GET_BE24(pos);
1606d49e1aeSJan Lentfer pos += 3;
1616d49e1aeSJan Lentfer left -= 4;
1626d49e1aeSJan Lentfer
163*a1157835SDaniel Fojt if (len > left) {
164*a1157835SDaniel Fojt tlsv1_server_log(conn,
165*a1157835SDaniel Fojt "Truncated ClientHello (len=%d left=%d)",
166*a1157835SDaniel Fojt (int) len, (int) left);
1676d49e1aeSJan Lentfer goto decode_error;
168*a1157835SDaniel Fojt }
1696d49e1aeSJan Lentfer
1706d49e1aeSJan Lentfer /* body - ClientHello */
1716d49e1aeSJan Lentfer
1726d49e1aeSJan Lentfer wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello", pos, len);
1736d49e1aeSJan Lentfer end = pos + len;
1746d49e1aeSJan Lentfer
1756d49e1aeSJan Lentfer /* ProtocolVersion client_version */
176*a1157835SDaniel Fojt if (end - pos < 2) {
177*a1157835SDaniel Fojt tlsv1_server_log(conn, "Truncated ClientHello/client_version");
1786d49e1aeSJan Lentfer goto decode_error;
179*a1157835SDaniel Fojt }
1806d49e1aeSJan Lentfer conn->client_version = WPA_GET_BE16(pos);
181*a1157835SDaniel Fojt tlsv1_server_log(conn, "Client version %d.%d",
182*a1157835SDaniel Fojt conn->client_version >> 8,
183*a1157835SDaniel Fojt conn->client_version & 0xff);
1843ff40c12SJohn Marino if (conn->client_version < TLS_VERSION_1) {
185*a1157835SDaniel Fojt tlsv1_server_log(conn, "Unexpected protocol version in ClientHello %u.%u",
1863ff40c12SJohn Marino conn->client_version >> 8,
1873ff40c12SJohn Marino conn->client_version & 0xff);
1886d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1896d49e1aeSJan Lentfer TLS_ALERT_PROTOCOL_VERSION);
1906d49e1aeSJan Lentfer return -1;
1916d49e1aeSJan Lentfer }
1926d49e1aeSJan Lentfer pos += 2;
1936d49e1aeSJan Lentfer
1943ff40c12SJohn Marino if (TLS_VERSION == TLS_VERSION_1)
1953ff40c12SJohn Marino conn->rl.tls_version = TLS_VERSION_1;
1963ff40c12SJohn Marino #ifdef CONFIG_TLSV12
1973ff40c12SJohn Marino else if (conn->client_version >= TLS_VERSION_1_2)
1983ff40c12SJohn Marino conn->rl.tls_version = TLS_VERSION_1_2;
1993ff40c12SJohn Marino #endif /* CONFIG_TLSV12 */
2003ff40c12SJohn Marino else if (conn->client_version > TLS_VERSION_1_1)
2013ff40c12SJohn Marino conn->rl.tls_version = TLS_VERSION_1_1;
2023ff40c12SJohn Marino else
2033ff40c12SJohn Marino conn->rl.tls_version = conn->client_version;
204*a1157835SDaniel Fojt tlsv1_server_log(conn, "Using TLS v%s",
2053ff40c12SJohn Marino tls_version_str(conn->rl.tls_version));
2063ff40c12SJohn Marino
2076d49e1aeSJan Lentfer /* Random random */
208*a1157835SDaniel Fojt if (end - pos < TLS_RANDOM_LEN) {
209*a1157835SDaniel Fojt tlsv1_server_log(conn, "Truncated ClientHello/client_random");
2106d49e1aeSJan Lentfer goto decode_error;
211*a1157835SDaniel Fojt }
2126d49e1aeSJan Lentfer
2136d49e1aeSJan Lentfer os_memcpy(conn->client_random, pos, TLS_RANDOM_LEN);
2146d49e1aeSJan Lentfer pos += TLS_RANDOM_LEN;
2156d49e1aeSJan Lentfer wpa_hexdump(MSG_MSGDUMP, "TLSv1: client_random",
2166d49e1aeSJan Lentfer conn->client_random, TLS_RANDOM_LEN);
2176d49e1aeSJan Lentfer
2186d49e1aeSJan Lentfer /* SessionID session_id */
219*a1157835SDaniel Fojt if (end - pos < 1) {
220*a1157835SDaniel Fojt tlsv1_server_log(conn, "Truncated ClientHello/session_id len");
2216d49e1aeSJan Lentfer goto decode_error;
222*a1157835SDaniel Fojt }
223*a1157835SDaniel Fojt if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN) {
224*a1157835SDaniel Fojt tlsv1_server_log(conn, "Truncated ClientHello/session_id");
2256d49e1aeSJan Lentfer goto decode_error;
226*a1157835SDaniel Fojt }
2276d49e1aeSJan Lentfer wpa_hexdump(MSG_MSGDUMP, "TLSv1: client session_id", pos + 1, *pos);
2286d49e1aeSJan Lentfer pos += 1 + *pos;
2296d49e1aeSJan Lentfer /* TODO: add support for session resumption */
2306d49e1aeSJan Lentfer
2316d49e1aeSJan Lentfer /* CipherSuite cipher_suites<2..2^16-1> */
232*a1157835SDaniel Fojt if (end - pos < 2) {
233*a1157835SDaniel Fojt tlsv1_server_log(conn,
234*a1157835SDaniel Fojt "Truncated ClientHello/cipher_suites len");
2356d49e1aeSJan Lentfer goto decode_error;
236*a1157835SDaniel Fojt }
2376d49e1aeSJan Lentfer num_suites = WPA_GET_BE16(pos);
2386d49e1aeSJan Lentfer pos += 2;
239*a1157835SDaniel Fojt if (end - pos < num_suites) {
240*a1157835SDaniel Fojt tlsv1_server_log(conn, "Truncated ClientHello/cipher_suites");
2416d49e1aeSJan Lentfer goto decode_error;
242*a1157835SDaniel Fojt }
2436d49e1aeSJan Lentfer wpa_hexdump(MSG_MSGDUMP, "TLSv1: client cipher suites",
2446d49e1aeSJan Lentfer pos, num_suites);
245*a1157835SDaniel Fojt if (num_suites & 1) {
246*a1157835SDaniel Fojt tlsv1_server_log(conn, "Odd len ClientHello/cipher_suites");
2476d49e1aeSJan Lentfer goto decode_error;
248*a1157835SDaniel Fojt }
2496d49e1aeSJan Lentfer num_suites /= 2;
2506d49e1aeSJan Lentfer
2516d49e1aeSJan Lentfer cipher_suite = 0;
2526d49e1aeSJan Lentfer for (i = 0; !cipher_suite && i < conn->num_cipher_suites; i++) {
253*a1157835SDaniel Fojt if (testing_cipher_suite_filter(conn, conn->cipher_suites[i]))
254*a1157835SDaniel Fojt continue;
2556d49e1aeSJan Lentfer c = pos;
2566d49e1aeSJan Lentfer for (j = 0; j < num_suites; j++) {
2576d49e1aeSJan Lentfer u16 tmp = WPA_GET_BE16(c);
2586d49e1aeSJan Lentfer c += 2;
2596d49e1aeSJan Lentfer if (!cipher_suite && tmp == conn->cipher_suites[i]) {
2606d49e1aeSJan Lentfer cipher_suite = tmp;
2616d49e1aeSJan Lentfer break;
2626d49e1aeSJan Lentfer }
2636d49e1aeSJan Lentfer }
2646d49e1aeSJan Lentfer }
2656d49e1aeSJan Lentfer pos += num_suites * 2;
2666d49e1aeSJan Lentfer if (!cipher_suite) {
267*a1157835SDaniel Fojt tlsv1_server_log(conn, "No supported cipher suite available");
2686d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
2696d49e1aeSJan Lentfer TLS_ALERT_ILLEGAL_PARAMETER);
2706d49e1aeSJan Lentfer return -1;
2716d49e1aeSJan Lentfer }
2726d49e1aeSJan Lentfer
2736d49e1aeSJan Lentfer if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) {
2746d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for "
2756d49e1aeSJan Lentfer "record layer");
2766d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
2776d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
2786d49e1aeSJan Lentfer return -1;
2796d49e1aeSJan Lentfer }
2806d49e1aeSJan Lentfer
2816d49e1aeSJan Lentfer conn->cipher_suite = cipher_suite;
2826d49e1aeSJan Lentfer
2836d49e1aeSJan Lentfer /* CompressionMethod compression_methods<1..2^8-1> */
284*a1157835SDaniel Fojt if (end - pos < 1) {
285*a1157835SDaniel Fojt tlsv1_server_log(conn,
286*a1157835SDaniel Fojt "Truncated ClientHello/compression_methods len");
2876d49e1aeSJan Lentfer goto decode_error;
288*a1157835SDaniel Fojt }
2896d49e1aeSJan Lentfer num_suites = *pos++;
290*a1157835SDaniel Fojt if (end - pos < num_suites) {
291*a1157835SDaniel Fojt tlsv1_server_log(conn,
292*a1157835SDaniel Fojt "Truncated ClientHello/compression_methods");
2936d49e1aeSJan Lentfer goto decode_error;
294*a1157835SDaniel Fojt }
2956d49e1aeSJan Lentfer wpa_hexdump(MSG_MSGDUMP, "TLSv1: client compression_methods",
2966d49e1aeSJan Lentfer pos, num_suites);
2976d49e1aeSJan Lentfer compr_null_found = 0;
2986d49e1aeSJan Lentfer for (i = 0; i < num_suites; i++) {
2996d49e1aeSJan Lentfer if (*pos++ == TLS_COMPRESSION_NULL)
3006d49e1aeSJan Lentfer compr_null_found = 1;
3016d49e1aeSJan Lentfer }
3026d49e1aeSJan Lentfer if (!compr_null_found) {
303*a1157835SDaniel Fojt tlsv1_server_log(conn, "Client does not accept NULL compression");
3046d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
3056d49e1aeSJan Lentfer TLS_ALERT_ILLEGAL_PARAMETER);
3066d49e1aeSJan Lentfer return -1;
3076d49e1aeSJan Lentfer }
3086d49e1aeSJan Lentfer
3096d49e1aeSJan Lentfer if (end - pos == 1) {
310*a1157835SDaniel Fojt tlsv1_server_log(conn, "Unexpected extra octet in the end of ClientHello: 0x%02x",
311*a1157835SDaniel Fojt *pos);
3126d49e1aeSJan Lentfer goto decode_error;
3136d49e1aeSJan Lentfer }
3146d49e1aeSJan Lentfer
3156d49e1aeSJan Lentfer if (end - pos >= 2) {
3166d49e1aeSJan Lentfer /* Extension client_hello_extension_list<0..2^16-1> */
3176d49e1aeSJan Lentfer ext_len = WPA_GET_BE16(pos);
3186d49e1aeSJan Lentfer pos += 2;
3196d49e1aeSJan Lentfer
320*a1157835SDaniel Fojt tlsv1_server_log(conn, "%u bytes of ClientHello extensions",
321*a1157835SDaniel Fojt ext_len);
3226d49e1aeSJan Lentfer if (end - pos != ext_len) {
323*a1157835SDaniel Fojt tlsv1_server_log(conn, "Invalid ClientHello extension list length %u (expected %u)",
3246d49e1aeSJan Lentfer ext_len, (unsigned int) (end - pos));
3256d49e1aeSJan Lentfer goto decode_error;
3266d49e1aeSJan Lentfer }
3276d49e1aeSJan Lentfer
3286d49e1aeSJan Lentfer /*
3296d49e1aeSJan Lentfer * struct {
3306d49e1aeSJan Lentfer * ExtensionType extension_type (0..65535)
3316d49e1aeSJan Lentfer * opaque extension_data<0..2^16-1>
3326d49e1aeSJan Lentfer * } Extension;
3336d49e1aeSJan Lentfer */
3346d49e1aeSJan Lentfer
3356d49e1aeSJan Lentfer while (pos < end) {
3366d49e1aeSJan Lentfer if (end - pos < 2) {
337*a1157835SDaniel Fojt tlsv1_server_log(conn, "Invalid extension_type field");
3386d49e1aeSJan Lentfer goto decode_error;
3396d49e1aeSJan Lentfer }
3406d49e1aeSJan Lentfer
3416d49e1aeSJan Lentfer ext_type = WPA_GET_BE16(pos);
3426d49e1aeSJan Lentfer pos += 2;
3436d49e1aeSJan Lentfer
3446d49e1aeSJan Lentfer if (end - pos < 2) {
345*a1157835SDaniel Fojt tlsv1_server_log(conn, "Invalid extension_data length field");
3466d49e1aeSJan Lentfer goto decode_error;
3476d49e1aeSJan Lentfer }
3486d49e1aeSJan Lentfer
3496d49e1aeSJan Lentfer ext_len = WPA_GET_BE16(pos);
3506d49e1aeSJan Lentfer pos += 2;
3516d49e1aeSJan Lentfer
3526d49e1aeSJan Lentfer if (end - pos < ext_len) {
353*a1157835SDaniel Fojt tlsv1_server_log(conn, "Invalid extension_data field");
3546d49e1aeSJan Lentfer goto decode_error;
3556d49e1aeSJan Lentfer }
3566d49e1aeSJan Lentfer
357*a1157835SDaniel Fojt tlsv1_server_log(conn, "ClientHello Extension type %u",
358*a1157835SDaniel Fojt ext_type);
3596d49e1aeSJan Lentfer wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello "
3606d49e1aeSJan Lentfer "Extension data", pos, ext_len);
3616d49e1aeSJan Lentfer
3626d49e1aeSJan Lentfer if (ext_type == TLS_EXT_SESSION_TICKET) {
3636d49e1aeSJan Lentfer os_free(conn->session_ticket);
3646d49e1aeSJan Lentfer conn->session_ticket = os_malloc(ext_len);
3656d49e1aeSJan Lentfer if (conn->session_ticket) {
3666d49e1aeSJan Lentfer os_memcpy(conn->session_ticket, pos,
3676d49e1aeSJan Lentfer ext_len);
3686d49e1aeSJan Lentfer conn->session_ticket_len = ext_len;
3696d49e1aeSJan Lentfer }
370*a1157835SDaniel Fojt } else if (ext_type == TLS_EXT_STATUS_REQUEST) {
371*a1157835SDaniel Fojt conn->status_request = 1;
372*a1157835SDaniel Fojt } else if (ext_type == TLS_EXT_STATUS_REQUEST_V2) {
373*a1157835SDaniel Fojt tls_process_status_request_v2(conn, pos,
374*a1157835SDaniel Fojt ext_len);
3756d49e1aeSJan Lentfer }
3766d49e1aeSJan Lentfer
3776d49e1aeSJan Lentfer pos += ext_len;
3786d49e1aeSJan Lentfer }
3796d49e1aeSJan Lentfer }
3806d49e1aeSJan Lentfer
3816d49e1aeSJan Lentfer *in_len = end - in_data;
3826d49e1aeSJan Lentfer
383*a1157835SDaniel Fojt tlsv1_server_log(conn, "ClientHello OK - proceed to ServerHello");
3846d49e1aeSJan Lentfer conn->state = SERVER_HELLO;
3856d49e1aeSJan Lentfer
3866d49e1aeSJan Lentfer return 0;
3876d49e1aeSJan Lentfer
3886d49e1aeSJan Lentfer decode_error:
389*a1157835SDaniel Fojt tlsv1_server_log(conn, "Failed to decode ClientHello");
3906d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
3916d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
3926d49e1aeSJan Lentfer return -1;
3936d49e1aeSJan Lentfer }
3946d49e1aeSJan Lentfer
3956d49e1aeSJan Lentfer
tls_process_certificate(struct tlsv1_server * conn,u8 ct,const u8 * in_data,size_t * in_len)3966d49e1aeSJan Lentfer static int tls_process_certificate(struct tlsv1_server *conn, u8 ct,
3976d49e1aeSJan Lentfer const u8 *in_data, size_t *in_len)
3986d49e1aeSJan Lentfer {
3996d49e1aeSJan Lentfer const u8 *pos, *end;
4006d49e1aeSJan Lentfer size_t left, len, list_len, cert_len, idx;
4016d49e1aeSJan Lentfer u8 type;
4026d49e1aeSJan Lentfer struct x509_certificate *chain = NULL, *last = NULL, *cert;
4036d49e1aeSJan Lentfer int reason;
4046d49e1aeSJan Lentfer
4056d49e1aeSJan Lentfer if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
406*a1157835SDaniel Fojt tlsv1_server_log(conn, "Expected Handshake; received content type 0x%x",
407*a1157835SDaniel Fojt ct);
4086d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
4096d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
4106d49e1aeSJan Lentfer return -1;
4116d49e1aeSJan Lentfer }
4126d49e1aeSJan Lentfer
4136d49e1aeSJan Lentfer pos = in_data;
4146d49e1aeSJan Lentfer left = *in_len;
4156d49e1aeSJan Lentfer
4166d49e1aeSJan Lentfer if (left < 4) {
417*a1157835SDaniel Fojt tlsv1_server_log(conn, "Too short Certificate message (len=%lu)",
418*a1157835SDaniel Fojt (unsigned long) left);
4196d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
4206d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
4216d49e1aeSJan Lentfer return -1;
4226d49e1aeSJan Lentfer }
4236d49e1aeSJan Lentfer
4246d49e1aeSJan Lentfer type = *pos++;
4256d49e1aeSJan Lentfer len = WPA_GET_BE24(pos);
4266d49e1aeSJan Lentfer pos += 3;
4276d49e1aeSJan Lentfer left -= 4;
4286d49e1aeSJan Lentfer
4296d49e1aeSJan Lentfer if (len > left) {
430*a1157835SDaniel Fojt tlsv1_server_log(conn, "Unexpected Certificate message length (len=%lu != left=%lu)",
4316d49e1aeSJan Lentfer (unsigned long) len, (unsigned long) left);
4326d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
4336d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
4346d49e1aeSJan Lentfer return -1;
4356d49e1aeSJan Lentfer }
4366d49e1aeSJan Lentfer
4376d49e1aeSJan Lentfer if (type == TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) {
4386d49e1aeSJan Lentfer if (conn->verify_peer) {
439*a1157835SDaniel Fojt tlsv1_server_log(conn, "Client did not include Certificate");
4406d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
4416d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
4426d49e1aeSJan Lentfer return -1;
4436d49e1aeSJan Lentfer }
4446d49e1aeSJan Lentfer
4456d49e1aeSJan Lentfer return tls_process_client_key_exchange(conn, ct, in_data,
4466d49e1aeSJan Lentfer in_len);
4476d49e1aeSJan Lentfer }
4486d49e1aeSJan Lentfer if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) {
449*a1157835SDaniel Fojt tlsv1_server_log(conn, "Received unexpected handshake message %d (expected Certificate/ClientKeyExchange)",
450*a1157835SDaniel Fojt type);
4516d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
4526d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
4536d49e1aeSJan Lentfer return -1;
4546d49e1aeSJan Lentfer }
4556d49e1aeSJan Lentfer
456*a1157835SDaniel Fojt tlsv1_server_log(conn, "Received Certificate (certificate_list len %lu)",
4576d49e1aeSJan Lentfer (unsigned long) len);
4586d49e1aeSJan Lentfer
4596d49e1aeSJan Lentfer /*
4606d49e1aeSJan Lentfer * opaque ASN.1Cert<2^24-1>;
4616d49e1aeSJan Lentfer *
4626d49e1aeSJan Lentfer * struct {
4636d49e1aeSJan Lentfer * ASN.1Cert certificate_list<1..2^24-1>;
4646d49e1aeSJan Lentfer * } Certificate;
4656d49e1aeSJan Lentfer */
4666d49e1aeSJan Lentfer
4676d49e1aeSJan Lentfer end = pos + len;
4686d49e1aeSJan Lentfer
4696d49e1aeSJan Lentfer if (end - pos < 3) {
470*a1157835SDaniel Fojt tlsv1_server_log(conn, "Too short Certificate (left=%lu)",
471*a1157835SDaniel Fojt (unsigned long) left);
4726d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
4736d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
4746d49e1aeSJan Lentfer return -1;
4756d49e1aeSJan Lentfer }
4766d49e1aeSJan Lentfer
4776d49e1aeSJan Lentfer list_len = WPA_GET_BE24(pos);
4786d49e1aeSJan Lentfer pos += 3;
4796d49e1aeSJan Lentfer
4806d49e1aeSJan Lentfer if ((size_t) (end - pos) != list_len) {
481*a1157835SDaniel Fojt tlsv1_server_log(conn, "Unexpected certificate_list length (len=%lu left=%lu)",
4826d49e1aeSJan Lentfer (unsigned long) list_len,
4836d49e1aeSJan Lentfer (unsigned long) (end - pos));
4846d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
4856d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
4866d49e1aeSJan Lentfer return -1;
4876d49e1aeSJan Lentfer }
4886d49e1aeSJan Lentfer
4896d49e1aeSJan Lentfer idx = 0;
4906d49e1aeSJan Lentfer while (pos < end) {
4916d49e1aeSJan Lentfer if (end - pos < 3) {
492*a1157835SDaniel Fojt tlsv1_server_log(conn, "Failed to parse certificate_list");
4936d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
4946d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
4956d49e1aeSJan Lentfer x509_certificate_chain_free(chain);
4966d49e1aeSJan Lentfer return -1;
4976d49e1aeSJan Lentfer }
4986d49e1aeSJan Lentfer
4996d49e1aeSJan Lentfer cert_len = WPA_GET_BE24(pos);
5006d49e1aeSJan Lentfer pos += 3;
5016d49e1aeSJan Lentfer
5026d49e1aeSJan Lentfer if ((size_t) (end - pos) < cert_len) {
503*a1157835SDaniel Fojt tlsv1_server_log(conn, "Unexpected certificate length (len=%lu left=%lu)",
5046d49e1aeSJan Lentfer (unsigned long) cert_len,
5056d49e1aeSJan Lentfer (unsigned long) (end - pos));
5066d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
5076d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
5086d49e1aeSJan Lentfer x509_certificate_chain_free(chain);
5096d49e1aeSJan Lentfer return -1;
5106d49e1aeSJan Lentfer }
5116d49e1aeSJan Lentfer
512*a1157835SDaniel Fojt tlsv1_server_log(conn, "Certificate %lu (len %lu)",
5136d49e1aeSJan Lentfer (unsigned long) idx, (unsigned long) cert_len);
5146d49e1aeSJan Lentfer
5156d49e1aeSJan Lentfer if (idx == 0) {
5166d49e1aeSJan Lentfer crypto_public_key_free(conn->client_rsa_key);
5176d49e1aeSJan Lentfer if (tls_parse_cert(pos, cert_len,
5186d49e1aeSJan Lentfer &conn->client_rsa_key)) {
519*a1157835SDaniel Fojt tlsv1_server_log(conn, "Failed to parse the certificate");
5206d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
5216d49e1aeSJan Lentfer TLS_ALERT_BAD_CERTIFICATE);
5226d49e1aeSJan Lentfer x509_certificate_chain_free(chain);
5236d49e1aeSJan Lentfer return -1;
5246d49e1aeSJan Lentfer }
5256d49e1aeSJan Lentfer }
5266d49e1aeSJan Lentfer
5276d49e1aeSJan Lentfer cert = x509_certificate_parse(pos, cert_len);
5286d49e1aeSJan Lentfer if (cert == NULL) {
529*a1157835SDaniel Fojt tlsv1_server_log(conn, "Failed to parse the certificate");
5306d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
5316d49e1aeSJan Lentfer TLS_ALERT_BAD_CERTIFICATE);
5326d49e1aeSJan Lentfer x509_certificate_chain_free(chain);
5336d49e1aeSJan Lentfer return -1;
5346d49e1aeSJan Lentfer }
5356d49e1aeSJan Lentfer
5366d49e1aeSJan Lentfer if (last == NULL)
5376d49e1aeSJan Lentfer chain = cert;
5386d49e1aeSJan Lentfer else
5396d49e1aeSJan Lentfer last->next = cert;
5406d49e1aeSJan Lentfer last = cert;
5416d49e1aeSJan Lentfer
5426d49e1aeSJan Lentfer idx++;
5436d49e1aeSJan Lentfer pos += cert_len;
5446d49e1aeSJan Lentfer }
5456d49e1aeSJan Lentfer
5466d49e1aeSJan Lentfer if (x509_certificate_chain_validate(conn->cred->trusted_certs, chain,
5473ff40c12SJohn Marino &reason, 0) < 0) {
5486d49e1aeSJan Lentfer int tls_reason;
549*a1157835SDaniel Fojt tlsv1_server_log(conn, "Server certificate chain validation failed (reason=%d)",
550*a1157835SDaniel Fojt reason);
5516d49e1aeSJan Lentfer switch (reason) {
5526d49e1aeSJan Lentfer case X509_VALIDATE_BAD_CERTIFICATE:
5536d49e1aeSJan Lentfer tls_reason = TLS_ALERT_BAD_CERTIFICATE;
5546d49e1aeSJan Lentfer break;
5556d49e1aeSJan Lentfer case X509_VALIDATE_UNSUPPORTED_CERTIFICATE:
5566d49e1aeSJan Lentfer tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE;
5576d49e1aeSJan Lentfer break;
5586d49e1aeSJan Lentfer case X509_VALIDATE_CERTIFICATE_REVOKED:
5596d49e1aeSJan Lentfer tls_reason = TLS_ALERT_CERTIFICATE_REVOKED;
5606d49e1aeSJan Lentfer break;
5616d49e1aeSJan Lentfer case X509_VALIDATE_CERTIFICATE_EXPIRED:
5626d49e1aeSJan Lentfer tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED;
5636d49e1aeSJan Lentfer break;
5646d49e1aeSJan Lentfer case X509_VALIDATE_CERTIFICATE_UNKNOWN:
5656d49e1aeSJan Lentfer tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN;
5666d49e1aeSJan Lentfer break;
5676d49e1aeSJan Lentfer case X509_VALIDATE_UNKNOWN_CA:
5686d49e1aeSJan Lentfer tls_reason = TLS_ALERT_UNKNOWN_CA;
5696d49e1aeSJan Lentfer break;
5706d49e1aeSJan Lentfer default:
5716d49e1aeSJan Lentfer tls_reason = TLS_ALERT_BAD_CERTIFICATE;
5726d49e1aeSJan Lentfer break;
5736d49e1aeSJan Lentfer }
5746d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason);
5756d49e1aeSJan Lentfer x509_certificate_chain_free(chain);
5766d49e1aeSJan Lentfer return -1;
5776d49e1aeSJan Lentfer }
5786d49e1aeSJan Lentfer
579*a1157835SDaniel Fojt if (chain && (chain->extensions_present & X509_EXT_EXT_KEY_USAGE) &&
580*a1157835SDaniel Fojt !(chain->ext_key_usage &
581*a1157835SDaniel Fojt (X509_EXT_KEY_USAGE_ANY | X509_EXT_KEY_USAGE_CLIENT_AUTH))) {
582*a1157835SDaniel Fojt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
583*a1157835SDaniel Fojt TLS_ALERT_BAD_CERTIFICATE);
584*a1157835SDaniel Fojt x509_certificate_chain_free(chain);
585*a1157835SDaniel Fojt return -1;
586*a1157835SDaniel Fojt }
587*a1157835SDaniel Fojt
5886d49e1aeSJan Lentfer x509_certificate_chain_free(chain);
5896d49e1aeSJan Lentfer
5906d49e1aeSJan Lentfer *in_len = end - in_data;
5916d49e1aeSJan Lentfer
5926d49e1aeSJan Lentfer conn->state = CLIENT_KEY_EXCHANGE;
5936d49e1aeSJan Lentfer
5946d49e1aeSJan Lentfer return 0;
5956d49e1aeSJan Lentfer }
5966d49e1aeSJan Lentfer
5976d49e1aeSJan Lentfer
tls_process_client_key_exchange_rsa(struct tlsv1_server * conn,const u8 * pos,const u8 * end)5986d49e1aeSJan Lentfer static int tls_process_client_key_exchange_rsa(
5996d49e1aeSJan Lentfer struct tlsv1_server *conn, const u8 *pos, const u8 *end)
6006d49e1aeSJan Lentfer {
6016d49e1aeSJan Lentfer u8 *out;
6026d49e1aeSJan Lentfer size_t outlen, outbuflen;
6036d49e1aeSJan Lentfer u16 encr_len;
6046d49e1aeSJan Lentfer int res;
6056d49e1aeSJan Lentfer int use_random = 0;
6066d49e1aeSJan Lentfer
6076d49e1aeSJan Lentfer if (end - pos < 2) {
6086d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
6096d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
6106d49e1aeSJan Lentfer return -1;
6116d49e1aeSJan Lentfer }
6126d49e1aeSJan Lentfer
6136d49e1aeSJan Lentfer encr_len = WPA_GET_BE16(pos);
6146d49e1aeSJan Lentfer pos += 2;
6153ff40c12SJohn Marino if (pos + encr_len > end) {
616*a1157835SDaniel Fojt tlsv1_server_log(conn, "Invalid ClientKeyExchange format: encr_len=%u left=%u",
6173ff40c12SJohn Marino encr_len, (unsigned int) (end - pos));
6183ff40c12SJohn Marino tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
6193ff40c12SJohn Marino TLS_ALERT_DECODE_ERROR);
6203ff40c12SJohn Marino return -1;
6213ff40c12SJohn Marino }
6226d49e1aeSJan Lentfer
6236d49e1aeSJan Lentfer outbuflen = outlen = end - pos;
6246d49e1aeSJan Lentfer out = os_malloc(outlen >= TLS_PRE_MASTER_SECRET_LEN ?
6256d49e1aeSJan Lentfer outlen : TLS_PRE_MASTER_SECRET_LEN);
6266d49e1aeSJan Lentfer if (out == NULL) {
6276d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
6286d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
6296d49e1aeSJan Lentfer return -1;
6306d49e1aeSJan Lentfer }
6316d49e1aeSJan Lentfer
6326d49e1aeSJan Lentfer /*
6336d49e1aeSJan Lentfer * struct {
6346d49e1aeSJan Lentfer * ProtocolVersion client_version;
6356d49e1aeSJan Lentfer * opaque random[46];
6366d49e1aeSJan Lentfer * } PreMasterSecret;
6376d49e1aeSJan Lentfer *
6386d49e1aeSJan Lentfer * struct {
6396d49e1aeSJan Lentfer * public-key-encrypted PreMasterSecret pre_master_secret;
6406d49e1aeSJan Lentfer * } EncryptedPreMasterSecret;
6416d49e1aeSJan Lentfer */
6426d49e1aeSJan Lentfer
6436d49e1aeSJan Lentfer /*
6446d49e1aeSJan Lentfer * Note: To avoid Bleichenbacher attack, we do not report decryption or
6456d49e1aeSJan Lentfer * parsing errors from EncryptedPreMasterSecret processing to the
6466d49e1aeSJan Lentfer * client. Instead, a random pre-master secret is used to force the
6476d49e1aeSJan Lentfer * handshake to fail.
6486d49e1aeSJan Lentfer */
6496d49e1aeSJan Lentfer
6506d49e1aeSJan Lentfer if (crypto_private_key_decrypt_pkcs1_v15(conn->cred->key,
6513ff40c12SJohn Marino pos, encr_len,
6526d49e1aeSJan Lentfer out, &outlen) < 0) {
6536d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt "
6543ff40c12SJohn Marino "PreMasterSecret (encr_len=%u outlen=%lu)",
6553ff40c12SJohn Marino encr_len, (unsigned long) outlen);
6566d49e1aeSJan Lentfer use_random = 1;
6576d49e1aeSJan Lentfer }
6586d49e1aeSJan Lentfer
6593ff40c12SJohn Marino if (!use_random && outlen != TLS_PRE_MASTER_SECRET_LEN) {
660*a1157835SDaniel Fojt tlsv1_server_log(conn, "Unexpected PreMasterSecret length %lu",
661*a1157835SDaniel Fojt (unsigned long) outlen);
6626d49e1aeSJan Lentfer use_random = 1;
6636d49e1aeSJan Lentfer }
6646d49e1aeSJan Lentfer
6653ff40c12SJohn Marino if (!use_random && WPA_GET_BE16(out) != conn->client_version) {
666*a1157835SDaniel Fojt tlsv1_server_log(conn, "Client version in ClientKeyExchange does not match with version in ClientHello");
6676d49e1aeSJan Lentfer use_random = 1;
6686d49e1aeSJan Lentfer }
6696d49e1aeSJan Lentfer
6706d49e1aeSJan Lentfer if (use_random) {
6716d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: Using random premaster secret "
6726d49e1aeSJan Lentfer "to avoid revealing information about private key");
6736d49e1aeSJan Lentfer outlen = TLS_PRE_MASTER_SECRET_LEN;
6746d49e1aeSJan Lentfer if (os_get_random(out, outlen)) {
6756d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random "
6766d49e1aeSJan Lentfer "data");
6776d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
6786d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
6796d49e1aeSJan Lentfer os_free(out);
6806d49e1aeSJan Lentfer return -1;
6816d49e1aeSJan Lentfer }
6826d49e1aeSJan Lentfer }
6836d49e1aeSJan Lentfer
6846d49e1aeSJan Lentfer res = tlsv1_server_derive_keys(conn, out, outlen);
6856d49e1aeSJan Lentfer
6866d49e1aeSJan Lentfer /* Clear the pre-master secret since it is not needed anymore */
6876d49e1aeSJan Lentfer os_memset(out, 0, outbuflen);
6886d49e1aeSJan Lentfer os_free(out);
6896d49e1aeSJan Lentfer
6906d49e1aeSJan Lentfer if (res) {
6916d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
6926d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
6936d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
6946d49e1aeSJan Lentfer return -1;
6956d49e1aeSJan Lentfer }
6966d49e1aeSJan Lentfer
6976d49e1aeSJan Lentfer return 0;
6986d49e1aeSJan Lentfer }
6996d49e1aeSJan Lentfer
7006d49e1aeSJan Lentfer
tls_process_client_key_exchange_dh(struct tlsv1_server * conn,const u8 * pos,const u8 * end)701*a1157835SDaniel Fojt static int tls_process_client_key_exchange_dh(
7026d49e1aeSJan Lentfer struct tlsv1_server *conn, const u8 *pos, const u8 *end)
7036d49e1aeSJan Lentfer {
7046d49e1aeSJan Lentfer const u8 *dh_yc;
7056d49e1aeSJan Lentfer u16 dh_yc_len;
7066d49e1aeSJan Lentfer u8 *shared;
7076d49e1aeSJan Lentfer size_t shared_len;
7086d49e1aeSJan Lentfer int res;
709*a1157835SDaniel Fojt const u8 *dh_p;
710*a1157835SDaniel Fojt size_t dh_p_len;
7116d49e1aeSJan Lentfer
7126d49e1aeSJan Lentfer /*
7136d49e1aeSJan Lentfer * struct {
7146d49e1aeSJan Lentfer * select (PublicValueEncoding) {
7156d49e1aeSJan Lentfer * case implicit: struct { };
7166d49e1aeSJan Lentfer * case explicit: opaque dh_Yc<1..2^16-1>;
7176d49e1aeSJan Lentfer * } dh_public;
7186d49e1aeSJan Lentfer * } ClientDiffieHellmanPublic;
7196d49e1aeSJan Lentfer */
7206d49e1aeSJan Lentfer
721*a1157835SDaniel Fojt tlsv1_server_log(conn, "ClientDiffieHellmanPublic received");
7226d49e1aeSJan Lentfer wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientDiffieHellmanPublic",
7236d49e1aeSJan Lentfer pos, end - pos);
7246d49e1aeSJan Lentfer
7256d49e1aeSJan Lentfer if (end == pos) {
7266d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: Implicit public value encoding "
7276d49e1aeSJan Lentfer "not supported");
7286d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
7296d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
7306d49e1aeSJan Lentfer return -1;
7316d49e1aeSJan Lentfer }
7326d49e1aeSJan Lentfer
7336d49e1aeSJan Lentfer if (end - pos < 3) {
734*a1157835SDaniel Fojt tlsv1_server_log(conn, "Invalid client public value length");
7356d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
7366d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
7376d49e1aeSJan Lentfer return -1;
7386d49e1aeSJan Lentfer }
7396d49e1aeSJan Lentfer
7406d49e1aeSJan Lentfer dh_yc_len = WPA_GET_BE16(pos);
7416d49e1aeSJan Lentfer dh_yc = pos + 2;
7426d49e1aeSJan Lentfer
743*a1157835SDaniel Fojt if (dh_yc_len > end - dh_yc) {
744*a1157835SDaniel Fojt tlsv1_server_log(conn, "Client public value overflow (length %d)",
745*a1157835SDaniel Fojt dh_yc_len);
7466d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
7476d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
7486d49e1aeSJan Lentfer return -1;
7496d49e1aeSJan Lentfer }
7506d49e1aeSJan Lentfer
7516d49e1aeSJan Lentfer wpa_hexdump(MSG_DEBUG, "TLSv1: DH Yc (client's public value)",
7526d49e1aeSJan Lentfer dh_yc, dh_yc_len);
7536d49e1aeSJan Lentfer
7546d49e1aeSJan Lentfer if (conn->cred == NULL || conn->cred->dh_p == NULL ||
7556d49e1aeSJan Lentfer conn->dh_secret == NULL) {
7566d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available");
7576d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
7586d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
7596d49e1aeSJan Lentfer return -1;
7606d49e1aeSJan Lentfer }
7616d49e1aeSJan Lentfer
762*a1157835SDaniel Fojt tlsv1_server_get_dh_p(conn, &dh_p, &dh_p_len);
763*a1157835SDaniel Fojt
764*a1157835SDaniel Fojt shared_len = dh_p_len;
7656d49e1aeSJan Lentfer shared = os_malloc(shared_len);
7666d49e1aeSJan Lentfer if (shared == NULL) {
7676d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: Could not allocate memory for "
7686d49e1aeSJan Lentfer "DH");
7696d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
7706d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
7716d49e1aeSJan Lentfer return -1;
7726d49e1aeSJan Lentfer }
7736d49e1aeSJan Lentfer
7746d49e1aeSJan Lentfer /* shared = Yc^secret mod p */
7756d49e1aeSJan Lentfer if (crypto_mod_exp(dh_yc, dh_yc_len, conn->dh_secret,
776*a1157835SDaniel Fojt conn->dh_secret_len, dh_p, dh_p_len,
7776d49e1aeSJan Lentfer shared, &shared_len)) {
7786d49e1aeSJan Lentfer os_free(shared);
7796d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
7806d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
7816d49e1aeSJan Lentfer return -1;
7826d49e1aeSJan Lentfer }
7836d49e1aeSJan Lentfer wpa_hexdump_key(MSG_DEBUG, "TLSv1: Shared secret from DH key exchange",
7846d49e1aeSJan Lentfer shared, shared_len);
7856d49e1aeSJan Lentfer
7866d49e1aeSJan Lentfer os_memset(conn->dh_secret, 0, conn->dh_secret_len);
7876d49e1aeSJan Lentfer os_free(conn->dh_secret);
7886d49e1aeSJan Lentfer conn->dh_secret = NULL;
7896d49e1aeSJan Lentfer
7906d49e1aeSJan Lentfer res = tlsv1_server_derive_keys(conn, shared, shared_len);
7916d49e1aeSJan Lentfer
7926d49e1aeSJan Lentfer /* Clear the pre-master secret since it is not needed anymore */
7936d49e1aeSJan Lentfer os_memset(shared, 0, shared_len);
7946d49e1aeSJan Lentfer os_free(shared);
7956d49e1aeSJan Lentfer
7966d49e1aeSJan Lentfer if (res) {
7976d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
7986d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
7996d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
8006d49e1aeSJan Lentfer return -1;
8016d49e1aeSJan Lentfer }
8026d49e1aeSJan Lentfer
8036d49e1aeSJan Lentfer return 0;
8046d49e1aeSJan Lentfer }
8056d49e1aeSJan Lentfer
8066d49e1aeSJan Lentfer
tls_process_client_key_exchange(struct tlsv1_server * conn,u8 ct,const u8 * in_data,size_t * in_len)8076d49e1aeSJan Lentfer static int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct,
8086d49e1aeSJan Lentfer const u8 *in_data, size_t *in_len)
8096d49e1aeSJan Lentfer {
8106d49e1aeSJan Lentfer const u8 *pos, *end;
8116d49e1aeSJan Lentfer size_t left, len;
8126d49e1aeSJan Lentfer u8 type;
8136d49e1aeSJan Lentfer tls_key_exchange keyx;
8146d49e1aeSJan Lentfer const struct tls_cipher_suite *suite;
8156d49e1aeSJan Lentfer
8166d49e1aeSJan Lentfer if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
817*a1157835SDaniel Fojt tlsv1_server_log(conn, "Expected Handshake; received content type 0x%x",
818*a1157835SDaniel Fojt ct);
8196d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
8206d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
8216d49e1aeSJan Lentfer return -1;
8226d49e1aeSJan Lentfer }
8236d49e1aeSJan Lentfer
8246d49e1aeSJan Lentfer pos = in_data;
8256d49e1aeSJan Lentfer left = *in_len;
8266d49e1aeSJan Lentfer
8276d49e1aeSJan Lentfer if (left < 4) {
828*a1157835SDaniel Fojt tlsv1_server_log(conn, "Too short ClientKeyExchange (Left=%lu)",
829*a1157835SDaniel Fojt (unsigned long) left);
8306d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
8316d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
8326d49e1aeSJan Lentfer return -1;
8336d49e1aeSJan Lentfer }
8346d49e1aeSJan Lentfer
8356d49e1aeSJan Lentfer type = *pos++;
8366d49e1aeSJan Lentfer len = WPA_GET_BE24(pos);
8376d49e1aeSJan Lentfer pos += 3;
8386d49e1aeSJan Lentfer left -= 4;
8396d49e1aeSJan Lentfer
8406d49e1aeSJan Lentfer if (len > left) {
841*a1157835SDaniel Fojt tlsv1_server_log(conn, "Mismatch in ClientKeyExchange length (len=%lu != left=%lu)",
8426d49e1aeSJan Lentfer (unsigned long) len, (unsigned long) left);
8436d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
8446d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
8456d49e1aeSJan Lentfer return -1;
8466d49e1aeSJan Lentfer }
8476d49e1aeSJan Lentfer
8486d49e1aeSJan Lentfer end = pos + len;
8496d49e1aeSJan Lentfer
8506d49e1aeSJan Lentfer if (type != TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) {
851*a1157835SDaniel Fojt tlsv1_server_log(conn, "Received unexpected handshake message %d (expected ClientKeyExchange)",
852*a1157835SDaniel Fojt type);
8536d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
8546d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
8556d49e1aeSJan Lentfer return -1;
8566d49e1aeSJan Lentfer }
8576d49e1aeSJan Lentfer
858*a1157835SDaniel Fojt tlsv1_server_log(conn, "Received ClientKeyExchange");
8596d49e1aeSJan Lentfer
8606d49e1aeSJan Lentfer wpa_hexdump(MSG_DEBUG, "TLSv1: ClientKeyExchange", pos, len);
8616d49e1aeSJan Lentfer
8626d49e1aeSJan Lentfer suite = tls_get_cipher_suite(conn->rl.cipher_suite);
8636d49e1aeSJan Lentfer if (suite == NULL)
8646d49e1aeSJan Lentfer keyx = TLS_KEY_X_NULL;
8656d49e1aeSJan Lentfer else
8666d49e1aeSJan Lentfer keyx = suite->key_exchange;
8676d49e1aeSJan Lentfer
868*a1157835SDaniel Fojt if ((keyx == TLS_KEY_X_DH_anon || keyx == TLS_KEY_X_DHE_RSA) &&
869*a1157835SDaniel Fojt tls_process_client_key_exchange_dh(conn, pos, end) < 0)
8706d49e1aeSJan Lentfer return -1;
8716d49e1aeSJan Lentfer
872*a1157835SDaniel Fojt if (keyx != TLS_KEY_X_DH_anon && keyx != TLS_KEY_X_DHE_RSA &&
8736d49e1aeSJan Lentfer tls_process_client_key_exchange_rsa(conn, pos, end) < 0)
8746d49e1aeSJan Lentfer return -1;
8756d49e1aeSJan Lentfer
8766d49e1aeSJan Lentfer *in_len = end - in_data;
8776d49e1aeSJan Lentfer
8786d49e1aeSJan Lentfer conn->state = CERTIFICATE_VERIFY;
8796d49e1aeSJan Lentfer
8806d49e1aeSJan Lentfer return 0;
8816d49e1aeSJan Lentfer }
8826d49e1aeSJan Lentfer
8836d49e1aeSJan Lentfer
tls_process_certificate_verify(struct tlsv1_server * conn,u8 ct,const u8 * in_data,size_t * in_len)8846d49e1aeSJan Lentfer static int tls_process_certificate_verify(struct tlsv1_server *conn, u8 ct,
8856d49e1aeSJan Lentfer const u8 *in_data, size_t *in_len)
8866d49e1aeSJan Lentfer {
8876d49e1aeSJan Lentfer const u8 *pos, *end;
8886d49e1aeSJan Lentfer size_t left, len;
8896d49e1aeSJan Lentfer u8 type;
890*a1157835SDaniel Fojt size_t hlen;
891*a1157835SDaniel Fojt u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN], *hpos;
892*a1157835SDaniel Fojt u8 alert;
8936d49e1aeSJan Lentfer
8946d49e1aeSJan Lentfer if (ct == TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
8956d49e1aeSJan Lentfer if (conn->verify_peer) {
896*a1157835SDaniel Fojt tlsv1_server_log(conn, "Client did not include CertificateVerify");
8976d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
8986d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
8996d49e1aeSJan Lentfer return -1;
9006d49e1aeSJan Lentfer }
9016d49e1aeSJan Lentfer
9026d49e1aeSJan Lentfer return tls_process_change_cipher_spec(conn, ct, in_data,
9036d49e1aeSJan Lentfer in_len);
9046d49e1aeSJan Lentfer }
9056d49e1aeSJan Lentfer
9066d49e1aeSJan Lentfer if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
907*a1157835SDaniel Fojt tlsv1_server_log(conn, "Expected Handshake; received content type 0x%x",
908*a1157835SDaniel Fojt ct);
9096d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
9106d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
9116d49e1aeSJan Lentfer return -1;
9126d49e1aeSJan Lentfer }
9136d49e1aeSJan Lentfer
9146d49e1aeSJan Lentfer pos = in_data;
9156d49e1aeSJan Lentfer left = *in_len;
9166d49e1aeSJan Lentfer
9176d49e1aeSJan Lentfer if (left < 4) {
918*a1157835SDaniel Fojt tlsv1_server_log(conn, "Too short CertificateVerify message (len=%lu)",
919*a1157835SDaniel Fojt (unsigned long) left);
9206d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
9216d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
9226d49e1aeSJan Lentfer return -1;
9236d49e1aeSJan Lentfer }
9246d49e1aeSJan Lentfer
9256d49e1aeSJan Lentfer type = *pos++;
9266d49e1aeSJan Lentfer len = WPA_GET_BE24(pos);
9276d49e1aeSJan Lentfer pos += 3;
9286d49e1aeSJan Lentfer left -= 4;
9296d49e1aeSJan Lentfer
9306d49e1aeSJan Lentfer if (len > left) {
931*a1157835SDaniel Fojt tlsv1_server_log(conn, "Unexpected CertificateVerify message length (len=%lu != left=%lu)",
9326d49e1aeSJan Lentfer (unsigned long) len, (unsigned long) left);
9336d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
9346d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
9356d49e1aeSJan Lentfer return -1;
9366d49e1aeSJan Lentfer }
9376d49e1aeSJan Lentfer
9386d49e1aeSJan Lentfer end = pos + len;
9396d49e1aeSJan Lentfer
9406d49e1aeSJan Lentfer if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY) {
941*a1157835SDaniel Fojt tlsv1_server_log(conn, "Received unexpected handshake message %d (expected CertificateVerify)",
942*a1157835SDaniel Fojt type);
9436d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
9446d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
9456d49e1aeSJan Lentfer return -1;
9466d49e1aeSJan Lentfer }
9476d49e1aeSJan Lentfer
948*a1157835SDaniel Fojt tlsv1_server_log(conn, "Received CertificateVerify");
9496d49e1aeSJan Lentfer
9506d49e1aeSJan Lentfer /*
9516d49e1aeSJan Lentfer * struct {
9526d49e1aeSJan Lentfer * Signature signature;
9536d49e1aeSJan Lentfer * } CertificateVerify;
9546d49e1aeSJan Lentfer */
9556d49e1aeSJan Lentfer
9566d49e1aeSJan Lentfer hpos = hash;
9576d49e1aeSJan Lentfer
9583ff40c12SJohn Marino #ifdef CONFIG_TLSV12
9593ff40c12SJohn Marino if (conn->rl.tls_version == TLS_VERSION_1_2) {
9603ff40c12SJohn Marino /*
9613ff40c12SJohn Marino * RFC 5246, 4.7:
9623ff40c12SJohn Marino * TLS v1.2 adds explicit indication of the used signature and
9633ff40c12SJohn Marino * hash algorithms.
9643ff40c12SJohn Marino *
9653ff40c12SJohn Marino * struct {
9663ff40c12SJohn Marino * HashAlgorithm hash;
9673ff40c12SJohn Marino * SignatureAlgorithm signature;
9683ff40c12SJohn Marino * } SignatureAndHashAlgorithm;
9693ff40c12SJohn Marino */
9703ff40c12SJohn Marino if (end - pos < 2) {
9713ff40c12SJohn Marino tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
9723ff40c12SJohn Marino TLS_ALERT_DECODE_ERROR);
9733ff40c12SJohn Marino return -1;
9743ff40c12SJohn Marino }
9753ff40c12SJohn Marino if (pos[0] != TLS_HASH_ALG_SHA256 ||
9763ff40c12SJohn Marino pos[1] != TLS_SIGN_ALG_RSA) {
9773ff40c12SJohn Marino wpa_printf(MSG_DEBUG, "TLSv1.2: Unsupported hash(%u)/"
9783ff40c12SJohn Marino "signature(%u) algorithm",
9793ff40c12SJohn Marino pos[0], pos[1]);
9803ff40c12SJohn Marino tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
9813ff40c12SJohn Marino TLS_ALERT_INTERNAL_ERROR);
9823ff40c12SJohn Marino return -1;
9833ff40c12SJohn Marino }
9843ff40c12SJohn Marino pos += 2;
9853ff40c12SJohn Marino
9863ff40c12SJohn Marino hlen = SHA256_MAC_LEN;
9873ff40c12SJohn Marino if (conn->verify.sha256_cert == NULL ||
9883ff40c12SJohn Marino crypto_hash_finish(conn->verify.sha256_cert, hpos, &hlen) <
9893ff40c12SJohn Marino 0) {
9903ff40c12SJohn Marino conn->verify.sha256_cert = NULL;
9913ff40c12SJohn Marino tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
9923ff40c12SJohn Marino TLS_ALERT_INTERNAL_ERROR);
9933ff40c12SJohn Marino return -1;
9943ff40c12SJohn Marino }
9953ff40c12SJohn Marino conn->verify.sha256_cert = NULL;
9963ff40c12SJohn Marino } else {
9973ff40c12SJohn Marino #endif /* CONFIG_TLSV12 */
9983ff40c12SJohn Marino
9996d49e1aeSJan Lentfer hlen = MD5_MAC_LEN;
10006d49e1aeSJan Lentfer if (conn->verify.md5_cert == NULL ||
1001*a1157835SDaniel Fojt crypto_hash_finish(conn->verify.md5_cert, hpos, &hlen) < 0) {
10026d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
10036d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
10046d49e1aeSJan Lentfer conn->verify.md5_cert = NULL;
10056d49e1aeSJan Lentfer crypto_hash_finish(conn->verify.sha1_cert, NULL, NULL);
10066d49e1aeSJan Lentfer conn->verify.sha1_cert = NULL;
10076d49e1aeSJan Lentfer return -1;
10086d49e1aeSJan Lentfer }
10096d49e1aeSJan Lentfer hpos += MD5_MAC_LEN;
10106d49e1aeSJan Lentfer
10116d49e1aeSJan Lentfer conn->verify.md5_cert = NULL;
10126d49e1aeSJan Lentfer hlen = SHA1_MAC_LEN;
10136d49e1aeSJan Lentfer if (conn->verify.sha1_cert == NULL ||
10146d49e1aeSJan Lentfer crypto_hash_finish(conn->verify.sha1_cert, hpos, &hlen) < 0) {
10156d49e1aeSJan Lentfer conn->verify.sha1_cert = NULL;
10166d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
10176d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
10186d49e1aeSJan Lentfer return -1;
10196d49e1aeSJan Lentfer }
10206d49e1aeSJan Lentfer conn->verify.sha1_cert = NULL;
10216d49e1aeSJan Lentfer
10226d49e1aeSJan Lentfer hlen += MD5_MAC_LEN;
10236d49e1aeSJan Lentfer
10243ff40c12SJohn Marino #ifdef CONFIG_TLSV12
10253ff40c12SJohn Marino }
10263ff40c12SJohn Marino #endif /* CONFIG_TLSV12 */
10273ff40c12SJohn Marino
10286d49e1aeSJan Lentfer wpa_hexdump(MSG_MSGDUMP, "TLSv1: CertificateVerify hash", hash, hlen);
10296d49e1aeSJan Lentfer
1030*a1157835SDaniel Fojt if (tls_verify_signature(conn->rl.tls_version, conn->client_rsa_key,
1031*a1157835SDaniel Fojt hash, hlen, pos, end - pos, &alert) < 0) {
1032*a1157835SDaniel Fojt tlsv1_server_log(conn, "Invalid Signature in CertificateVerify");
1033*a1157835SDaniel Fojt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
10346d49e1aeSJan Lentfer return -1;
10356d49e1aeSJan Lentfer }
10366d49e1aeSJan Lentfer
10376d49e1aeSJan Lentfer *in_len = end - in_data;
10386d49e1aeSJan Lentfer
10396d49e1aeSJan Lentfer conn->state = CHANGE_CIPHER_SPEC;
10406d49e1aeSJan Lentfer
10416d49e1aeSJan Lentfer return 0;
10426d49e1aeSJan Lentfer }
10436d49e1aeSJan Lentfer
10446d49e1aeSJan Lentfer
tls_process_change_cipher_spec(struct tlsv1_server * conn,u8 ct,const u8 * in_data,size_t * in_len)10456d49e1aeSJan Lentfer static int tls_process_change_cipher_spec(struct tlsv1_server *conn,
10466d49e1aeSJan Lentfer u8 ct, const u8 *in_data,
10476d49e1aeSJan Lentfer size_t *in_len)
10486d49e1aeSJan Lentfer {
10496d49e1aeSJan Lentfer const u8 *pos;
10506d49e1aeSJan Lentfer size_t left;
10516d49e1aeSJan Lentfer
10526d49e1aeSJan Lentfer if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
1053*a1157835SDaniel Fojt tlsv1_server_log(conn, "Expected ChangeCipherSpec; received content type 0x%x",
1054*a1157835SDaniel Fojt ct);
10556d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
10566d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
10576d49e1aeSJan Lentfer return -1;
10586d49e1aeSJan Lentfer }
10596d49e1aeSJan Lentfer
10606d49e1aeSJan Lentfer pos = in_data;
10616d49e1aeSJan Lentfer left = *in_len;
10626d49e1aeSJan Lentfer
10636d49e1aeSJan Lentfer if (left < 1) {
1064*a1157835SDaniel Fojt tlsv1_server_log(conn, "Too short ChangeCipherSpec");
10656d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
10666d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
10676d49e1aeSJan Lentfer return -1;
10686d49e1aeSJan Lentfer }
10696d49e1aeSJan Lentfer
10706d49e1aeSJan Lentfer if (*pos != TLS_CHANGE_CIPHER_SPEC) {
1071*a1157835SDaniel Fojt tlsv1_server_log(conn, "Expected ChangeCipherSpec; received data 0x%x",
1072*a1157835SDaniel Fojt *pos);
10736d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
10746d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
10756d49e1aeSJan Lentfer return -1;
10766d49e1aeSJan Lentfer }
10776d49e1aeSJan Lentfer
1078*a1157835SDaniel Fojt tlsv1_server_log(conn, "Received ChangeCipherSpec");
10796d49e1aeSJan Lentfer if (tlsv1_record_change_read_cipher(&conn->rl) < 0) {
10806d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher "
10816d49e1aeSJan Lentfer "for record layer");
10826d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
10836d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
10846d49e1aeSJan Lentfer return -1;
10856d49e1aeSJan Lentfer }
10866d49e1aeSJan Lentfer
10876d49e1aeSJan Lentfer *in_len = pos + 1 - in_data;
10886d49e1aeSJan Lentfer
10896d49e1aeSJan Lentfer conn->state = CLIENT_FINISHED;
10906d49e1aeSJan Lentfer
10916d49e1aeSJan Lentfer return 0;
10926d49e1aeSJan Lentfer }
10936d49e1aeSJan Lentfer
10946d49e1aeSJan Lentfer
tls_process_client_finished(struct tlsv1_server * conn,u8 ct,const u8 * in_data,size_t * in_len)10956d49e1aeSJan Lentfer static int tls_process_client_finished(struct tlsv1_server *conn, u8 ct,
10966d49e1aeSJan Lentfer const u8 *in_data, size_t *in_len)
10976d49e1aeSJan Lentfer {
10986d49e1aeSJan Lentfer const u8 *pos, *end;
10996d49e1aeSJan Lentfer size_t left, len, hlen;
11006d49e1aeSJan Lentfer u8 verify_data[TLS_VERIFY_DATA_LEN];
11016d49e1aeSJan Lentfer u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
11026d49e1aeSJan Lentfer
1103*a1157835SDaniel Fojt #ifdef CONFIG_TESTING_OPTIONS
1104*a1157835SDaniel Fojt if ((conn->test_flags &
1105*a1157835SDaniel Fojt (TLS_BREAK_SRV_KEY_X_HASH | TLS_BREAK_SRV_KEY_X_SIGNATURE)) &&
1106*a1157835SDaniel Fojt !conn->test_failure_reported) {
1107*a1157835SDaniel Fojt tlsv1_server_log(conn, "TEST-FAILURE: Client Finished received after invalid ServerKeyExchange");
1108*a1157835SDaniel Fojt conn->test_failure_reported = 1;
1109*a1157835SDaniel Fojt }
1110*a1157835SDaniel Fojt
1111*a1157835SDaniel Fojt if ((conn->test_flags & TLS_DHE_PRIME_15) &&
1112*a1157835SDaniel Fojt !conn->test_failure_reported) {
1113*a1157835SDaniel Fojt tlsv1_server_log(conn, "TEST-FAILURE: Client Finished received after bogus DHE \"prime\" 15");
1114*a1157835SDaniel Fojt conn->test_failure_reported = 1;
1115*a1157835SDaniel Fojt }
1116*a1157835SDaniel Fojt
1117*a1157835SDaniel Fojt if ((conn->test_flags & TLS_DHE_PRIME_58B) &&
1118*a1157835SDaniel Fojt !conn->test_failure_reported) {
1119*a1157835SDaniel Fojt tlsv1_server_log(conn, "TEST-FAILURE: Client Finished received after short 58-bit DHE prime in long container");
1120*a1157835SDaniel Fojt conn->test_failure_reported = 1;
1121*a1157835SDaniel Fojt }
1122*a1157835SDaniel Fojt
1123*a1157835SDaniel Fojt if ((conn->test_flags & TLS_DHE_PRIME_511B) &&
1124*a1157835SDaniel Fojt !conn->test_failure_reported) {
1125*a1157835SDaniel Fojt tlsv1_server_log(conn, "TEST-WARNING: Client Finished received after short 511-bit DHE prime (insecure)");
1126*a1157835SDaniel Fojt conn->test_failure_reported = 1;
1127*a1157835SDaniel Fojt }
1128*a1157835SDaniel Fojt
1129*a1157835SDaniel Fojt if ((conn->test_flags & TLS_DHE_PRIME_767B) &&
1130*a1157835SDaniel Fojt !conn->test_failure_reported) {
1131*a1157835SDaniel Fojt tlsv1_server_log(conn, "TEST-NOTE: Client Finished received after 767-bit DHE prime (relatively insecure)");
1132*a1157835SDaniel Fojt conn->test_failure_reported = 1;
1133*a1157835SDaniel Fojt }
1134*a1157835SDaniel Fojt
1135*a1157835SDaniel Fojt if ((conn->test_flags & TLS_DHE_NON_PRIME) &&
1136*a1157835SDaniel Fojt !conn->test_failure_reported) {
1137*a1157835SDaniel Fojt tlsv1_server_log(conn, "TEST-NOTE: Client Finished received after non-prime claimed as DHE prime");
1138*a1157835SDaniel Fojt conn->test_failure_reported = 1;
1139*a1157835SDaniel Fojt }
1140*a1157835SDaniel Fojt #endif /* CONFIG_TESTING_OPTIONS */
1141*a1157835SDaniel Fojt
11426d49e1aeSJan Lentfer if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
1143*a1157835SDaniel Fojt tlsv1_server_log(conn, "Expected Finished; received content type 0x%x",
1144*a1157835SDaniel Fojt ct);
11456d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
11466d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
11476d49e1aeSJan Lentfer return -1;
11486d49e1aeSJan Lentfer }
11496d49e1aeSJan Lentfer
11506d49e1aeSJan Lentfer pos = in_data;
11516d49e1aeSJan Lentfer left = *in_len;
11526d49e1aeSJan Lentfer
11536d49e1aeSJan Lentfer if (left < 4) {
1154*a1157835SDaniel Fojt tlsv1_server_log(conn, "Too short record (left=%lu) forFinished",
11556d49e1aeSJan Lentfer (unsigned long) left);
11566d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
11576d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
11586d49e1aeSJan Lentfer return -1;
11596d49e1aeSJan Lentfer }
11606d49e1aeSJan Lentfer
11616d49e1aeSJan Lentfer if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) {
11626d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received "
11636d49e1aeSJan Lentfer "type 0x%x", pos[0]);
11646d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
11656d49e1aeSJan Lentfer TLS_ALERT_UNEXPECTED_MESSAGE);
11666d49e1aeSJan Lentfer return -1;
11676d49e1aeSJan Lentfer }
11686d49e1aeSJan Lentfer
11696d49e1aeSJan Lentfer len = WPA_GET_BE24(pos + 1);
11706d49e1aeSJan Lentfer
11716d49e1aeSJan Lentfer pos += 4;
11726d49e1aeSJan Lentfer left -= 4;
11736d49e1aeSJan Lentfer
11746d49e1aeSJan Lentfer if (len > left) {
1175*a1157835SDaniel Fojt tlsv1_server_log(conn, "Too short buffer for Finished (len=%lu > left=%lu)",
11766d49e1aeSJan Lentfer (unsigned long) len, (unsigned long) left);
11776d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
11786d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
11796d49e1aeSJan Lentfer return -1;
11806d49e1aeSJan Lentfer }
11816d49e1aeSJan Lentfer end = pos + len;
11826d49e1aeSJan Lentfer if (len != TLS_VERIFY_DATA_LEN) {
1183*a1157835SDaniel Fojt tlsv1_server_log(conn, "Unexpected verify_data length in Finished: %lu (expected %d)",
11846d49e1aeSJan Lentfer (unsigned long) len, TLS_VERIFY_DATA_LEN);
11856d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
11866d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
11876d49e1aeSJan Lentfer return -1;
11886d49e1aeSJan Lentfer }
11896d49e1aeSJan Lentfer wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
11906d49e1aeSJan Lentfer pos, TLS_VERIFY_DATA_LEN);
11916d49e1aeSJan Lentfer
11923ff40c12SJohn Marino #ifdef CONFIG_TLSV12
11933ff40c12SJohn Marino if (conn->rl.tls_version >= TLS_VERSION_1_2) {
11943ff40c12SJohn Marino hlen = SHA256_MAC_LEN;
11953ff40c12SJohn Marino if (conn->verify.sha256_client == NULL ||
11963ff40c12SJohn Marino crypto_hash_finish(conn->verify.sha256_client, hash, &hlen)
11973ff40c12SJohn Marino < 0) {
11983ff40c12SJohn Marino tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
11993ff40c12SJohn Marino TLS_ALERT_INTERNAL_ERROR);
12003ff40c12SJohn Marino conn->verify.sha256_client = NULL;
12013ff40c12SJohn Marino return -1;
12023ff40c12SJohn Marino }
12033ff40c12SJohn Marino conn->verify.sha256_client = NULL;
12043ff40c12SJohn Marino } else {
12053ff40c12SJohn Marino #endif /* CONFIG_TLSV12 */
12063ff40c12SJohn Marino
12076d49e1aeSJan Lentfer hlen = MD5_MAC_LEN;
12086d49e1aeSJan Lentfer if (conn->verify.md5_client == NULL ||
12096d49e1aeSJan Lentfer crypto_hash_finish(conn->verify.md5_client, hash, &hlen) < 0) {
12106d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
12116d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
12126d49e1aeSJan Lentfer conn->verify.md5_client = NULL;
12136d49e1aeSJan Lentfer crypto_hash_finish(conn->verify.sha1_client, NULL, NULL);
12146d49e1aeSJan Lentfer conn->verify.sha1_client = NULL;
12156d49e1aeSJan Lentfer return -1;
12166d49e1aeSJan Lentfer }
12176d49e1aeSJan Lentfer conn->verify.md5_client = NULL;
12186d49e1aeSJan Lentfer hlen = SHA1_MAC_LEN;
12196d49e1aeSJan Lentfer if (conn->verify.sha1_client == NULL ||
12206d49e1aeSJan Lentfer crypto_hash_finish(conn->verify.sha1_client, hash + MD5_MAC_LEN,
12216d49e1aeSJan Lentfer &hlen) < 0) {
12226d49e1aeSJan Lentfer conn->verify.sha1_client = NULL;
12236d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
12246d49e1aeSJan Lentfer TLS_ALERT_INTERNAL_ERROR);
12256d49e1aeSJan Lentfer return -1;
12266d49e1aeSJan Lentfer }
12276d49e1aeSJan Lentfer conn->verify.sha1_client = NULL;
12283ff40c12SJohn Marino hlen = MD5_MAC_LEN + SHA1_MAC_LEN;
12296d49e1aeSJan Lentfer
12303ff40c12SJohn Marino #ifdef CONFIG_TLSV12
12313ff40c12SJohn Marino }
12323ff40c12SJohn Marino #endif /* CONFIG_TLSV12 */
12333ff40c12SJohn Marino
12343ff40c12SJohn Marino if (tls_prf(conn->rl.tls_version,
12353ff40c12SJohn Marino conn->master_secret, TLS_MASTER_SECRET_LEN,
12363ff40c12SJohn Marino "client finished", hash, hlen,
12376d49e1aeSJan Lentfer verify_data, TLS_VERIFY_DATA_LEN)) {
12386d49e1aeSJan Lentfer wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");
12396d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
12406d49e1aeSJan Lentfer TLS_ALERT_DECRYPT_ERROR);
12416d49e1aeSJan Lentfer return -1;
12426d49e1aeSJan Lentfer }
12436d49e1aeSJan Lentfer wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)",
12446d49e1aeSJan Lentfer verify_data, TLS_VERIFY_DATA_LEN);
12456d49e1aeSJan Lentfer
1246*a1157835SDaniel Fojt if (os_memcmp_const(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
1247*a1157835SDaniel Fojt tlsv1_server_log(conn, "Mismatch in verify_data");
1248*a1157835SDaniel Fojt conn->state = FAILED;
12496d49e1aeSJan Lentfer return -1;
12506d49e1aeSJan Lentfer }
12516d49e1aeSJan Lentfer
1252*a1157835SDaniel Fojt tlsv1_server_log(conn, "Received Finished");
12536d49e1aeSJan Lentfer
12546d49e1aeSJan Lentfer *in_len = end - in_data;
12556d49e1aeSJan Lentfer
12566d49e1aeSJan Lentfer if (conn->use_session_ticket) {
12576d49e1aeSJan Lentfer /* Abbreviated handshake using session ticket; RFC 4507 */
1258*a1157835SDaniel Fojt tlsv1_server_log(conn, "Abbreviated handshake completed successfully");
12596d49e1aeSJan Lentfer conn->state = ESTABLISHED;
12606d49e1aeSJan Lentfer } else {
12616d49e1aeSJan Lentfer /* Full handshake */
12626d49e1aeSJan Lentfer conn->state = SERVER_CHANGE_CIPHER_SPEC;
12636d49e1aeSJan Lentfer }
12646d49e1aeSJan Lentfer
12656d49e1aeSJan Lentfer return 0;
12666d49e1aeSJan Lentfer }
12676d49e1aeSJan Lentfer
12686d49e1aeSJan Lentfer
tlsv1_server_process_handshake(struct tlsv1_server * conn,u8 ct,const u8 * buf,size_t * len)12696d49e1aeSJan Lentfer int tlsv1_server_process_handshake(struct tlsv1_server *conn, u8 ct,
12706d49e1aeSJan Lentfer const u8 *buf, size_t *len)
12716d49e1aeSJan Lentfer {
12726d49e1aeSJan Lentfer if (ct == TLS_CONTENT_TYPE_ALERT) {
12736d49e1aeSJan Lentfer if (*len < 2) {
1274*a1157835SDaniel Fojt tlsv1_server_log(conn, "Alert underflow");
12756d49e1aeSJan Lentfer tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
12766d49e1aeSJan Lentfer TLS_ALERT_DECODE_ERROR);
12776d49e1aeSJan Lentfer return -1;
12786d49e1aeSJan Lentfer }
1279*a1157835SDaniel Fojt tlsv1_server_log(conn, "Received alert %d:%d", buf[0], buf[1]);
12806d49e1aeSJan Lentfer *len = 2;
12816d49e1aeSJan Lentfer conn->state = FAILED;
12826d49e1aeSJan Lentfer return -1;
12836d49e1aeSJan Lentfer }
12846d49e1aeSJan Lentfer
12856d49e1aeSJan Lentfer switch (conn->state) {
12866d49e1aeSJan Lentfer case CLIENT_HELLO:
12876d49e1aeSJan Lentfer if (tls_process_client_hello(conn, ct, buf, len))
12886d49e1aeSJan Lentfer return -1;
12896d49e1aeSJan Lentfer break;
12906d49e1aeSJan Lentfer case CLIENT_CERTIFICATE:
12916d49e1aeSJan Lentfer if (tls_process_certificate(conn, ct, buf, len))
12926d49e1aeSJan Lentfer return -1;
12936d49e1aeSJan Lentfer break;
12946d49e1aeSJan Lentfer case CLIENT_KEY_EXCHANGE:
12956d49e1aeSJan Lentfer if (tls_process_client_key_exchange(conn, ct, buf, len))
12966d49e1aeSJan Lentfer return -1;
12976d49e1aeSJan Lentfer break;
12986d49e1aeSJan Lentfer case CERTIFICATE_VERIFY:
12996d49e1aeSJan Lentfer if (tls_process_certificate_verify(conn, ct, buf, len))
13006d49e1aeSJan Lentfer return -1;
13016d49e1aeSJan Lentfer break;
13026d49e1aeSJan Lentfer case CHANGE_CIPHER_SPEC:
13036d49e1aeSJan Lentfer if (tls_process_change_cipher_spec(conn, ct, buf, len))
13046d49e1aeSJan Lentfer return -1;
13056d49e1aeSJan Lentfer break;
13066d49e1aeSJan Lentfer case CLIENT_FINISHED:
13076d49e1aeSJan Lentfer if (tls_process_client_finished(conn, ct, buf, len))
13086d49e1aeSJan Lentfer return -1;
13096d49e1aeSJan Lentfer break;
13106d49e1aeSJan Lentfer default:
1311*a1157835SDaniel Fojt tlsv1_server_log(conn, "Unexpected state %d while processing received message",
13126d49e1aeSJan Lentfer conn->state);
13136d49e1aeSJan Lentfer return -1;
13146d49e1aeSJan Lentfer }
13156d49e1aeSJan Lentfer
13166d49e1aeSJan Lentfer if (ct == TLS_CONTENT_TYPE_HANDSHAKE)
13176d49e1aeSJan Lentfer tls_verify_hash_add(&conn->verify, buf, *len);
13186d49e1aeSJan Lentfer
13196d49e1aeSJan Lentfer return 0;
13206d49e1aeSJan Lentfer }
1321