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