• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * TLSv1 client - read handshake message
3  * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14 
15 #include "includes.h"
16 
17 #include "common.h"
18 #include "crypto/md5.h"
19 #include "crypto/sha1.h"
20 #include "crypto/tls.h"
21 #include "x509v3.h"
22 #include "tlsv1_common.h"
23 #include "tlsv1_record.h"
24 #include "tlsv1_client.h"
25 #include "tlsv1_client_i.h"
26 
27 static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
28 					   const u8 *in_data, size_t *in_len);
29 static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
30 					   const u8 *in_data, size_t *in_len);
31 static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
32 					 const u8 *in_data, size_t *in_len);
33 
34 
tls_process_server_hello(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)35 static int tls_process_server_hello(struct tlsv1_client *conn, u8 ct,
36 				    const u8 *in_data, size_t *in_len)
37 {
38 	const u8 *pos, *end;
39 	size_t left, len, i;
40 	u16 cipher_suite;
41 
42 	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
43 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
44 			   "received content type 0x%x", ct);
45 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
46 			  TLS_ALERT_UNEXPECTED_MESSAGE);
47 		return -1;
48 	}
49 
50 	pos = in_data;
51 	left = *in_len;
52 
53 	if (left < 4)
54 		goto decode_error;
55 
56 	/* HandshakeType msg_type */
57 	if (*pos != TLS_HANDSHAKE_TYPE_SERVER_HELLO) {
58 		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
59 			   "message %d (expected ServerHello)", *pos);
60 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
61 			  TLS_ALERT_UNEXPECTED_MESSAGE);
62 		return -1;
63 	}
64 	wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHello");
65 	pos++;
66 	/* uint24 length */
67 	len = WPA_GET_BE24(pos);
68 	pos += 3;
69 	left -= 4;
70 
71 	if (len > left)
72 		goto decode_error;
73 
74 	/* body - ServerHello */
75 
76 	wpa_hexdump(MSG_MSGDUMP, "TLSv1: ServerHello", pos, len);
77 	end = pos + len;
78 
79 	/* ProtocolVersion server_version */
80 	if (end - pos < 2)
81 		goto decode_error;
82 	if (WPA_GET_BE16(pos) != TLS_VERSION) {
83 		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in "
84 			   "ServerHello");
85 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
86 			  TLS_ALERT_PROTOCOL_VERSION);
87 		return -1;
88 	}
89 	pos += 2;
90 
91 	/* Random random */
92 	if (end - pos < TLS_RANDOM_LEN)
93 		goto decode_error;
94 
95 	os_memcpy(conn->server_random, pos, TLS_RANDOM_LEN);
96 	pos += TLS_RANDOM_LEN;
97 	wpa_hexdump(MSG_MSGDUMP, "TLSv1: server_random",
98 		    conn->server_random, TLS_RANDOM_LEN);
99 
100 	/* SessionID session_id */
101 	if (end - pos < 1)
102 		goto decode_error;
103 	if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN)
104 		goto decode_error;
105 	if (conn->session_id_len && conn->session_id_len == *pos &&
106 	    os_memcmp(conn->session_id, pos + 1, conn->session_id_len) == 0) {
107 		pos += 1 + conn->session_id_len;
108 		wpa_printf(MSG_DEBUG, "TLSv1: Resuming old session");
109 		conn->session_resumed = 1;
110 	} else {
111 		conn->session_id_len = *pos;
112 		pos++;
113 		os_memcpy(conn->session_id, pos, conn->session_id_len);
114 		pos += conn->session_id_len;
115 	}
116 	wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id",
117 		    conn->session_id, conn->session_id_len);
118 
119 	/* CipherSuite cipher_suite */
120 	if (end - pos < 2)
121 		goto decode_error;
122 	cipher_suite = WPA_GET_BE16(pos);
123 	pos += 2;
124 	for (i = 0; i < conn->num_cipher_suites; i++) {
125 		if (cipher_suite == conn->cipher_suites[i])
126 			break;
127 	}
128 	if (i == conn->num_cipher_suites) {
129 		wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "
130 			   "cipher suite 0x%04x", cipher_suite);
131 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
132 			  TLS_ALERT_ILLEGAL_PARAMETER);
133 		return -1;
134 	}
135 
136 	if (conn->session_resumed && cipher_suite != conn->prev_cipher_suite) {
137 		wpa_printf(MSG_DEBUG, "TLSv1: Server selected a different "
138 			   "cipher suite for a resumed connection (0x%04x != "
139 			   "0x%04x)", cipher_suite, conn->prev_cipher_suite);
140 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
141 			  TLS_ALERT_ILLEGAL_PARAMETER);
142 		return -1;
143 	}
144 
145 	if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) {
146 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for "
147 			   "record layer");
148 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
149 			  TLS_ALERT_INTERNAL_ERROR);
150 		return -1;
151 	}
152 
153 	conn->prev_cipher_suite = cipher_suite;
154 
155 	/* CompressionMethod compression_method */
156 	if (end - pos < 1)
157 		goto decode_error;
158 	if (*pos != TLS_COMPRESSION_NULL) {
159 		wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "
160 			   "compression 0x%02x", *pos);
161 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
162 			  TLS_ALERT_ILLEGAL_PARAMETER);
163 		return -1;
164 	}
165 	pos++;
166 
167 	if (end != pos) {
168 		/* TODO: ServerHello extensions */
169 		wpa_hexdump(MSG_DEBUG, "TLSv1: Unexpected extra data in the "
170 			    "end of ServerHello", pos, end - pos);
171 		goto decode_error;
172 	}
173 
174 	if (conn->session_ticket_included && conn->session_ticket_cb) {
175 		/* TODO: include SessionTicket extension if one was included in
176 		 * ServerHello */
177 		int res = conn->session_ticket_cb(
178 			conn->session_ticket_cb_ctx, NULL, 0,
179 			conn->client_random, conn->server_random,
180 			conn->master_secret);
181 		if (res < 0) {
182 			wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback "
183 				   "indicated failure");
184 			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
185 				  TLS_ALERT_HANDSHAKE_FAILURE);
186 			return -1;
187 		}
188 		conn->use_session_ticket = !!res;
189 	}
190 
191 	if ((conn->session_resumed || conn->use_session_ticket) &&
192 	    tls_derive_keys(conn, NULL, 0)) {
193 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
194 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
195 			  TLS_ALERT_INTERNAL_ERROR);
196 		return -1;
197 	}
198 
199 	*in_len = end - in_data;
200 
201 	conn->state = (conn->session_resumed || conn->use_session_ticket) ?
202 		SERVER_CHANGE_CIPHER_SPEC : SERVER_CERTIFICATE;
203 
204 	return 0;
205 
206 decode_error:
207 	wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ServerHello");
208 	tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
209 	return -1;
210 }
211 
212 
tls_process_certificate(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)213 static int tls_process_certificate(struct tlsv1_client *conn, u8 ct,
214 				   const u8 *in_data, size_t *in_len)
215 {
216 	const u8 *pos, *end;
217 	size_t left, len, list_len, cert_len, idx;
218 	u8 type;
219 	struct x509_certificate *chain = NULL, *last = NULL, *cert;
220 	int reason;
221 
222 	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
223 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
224 			   "received content type 0x%x", ct);
225 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
226 			  TLS_ALERT_UNEXPECTED_MESSAGE);
227 		return -1;
228 	}
229 
230 	pos = in_data;
231 	left = *in_len;
232 
233 	if (left < 4) {
234 		wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message "
235 			   "(len=%lu)", (unsigned long) left);
236 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
237 		return -1;
238 	}
239 
240 	type = *pos++;
241 	len = WPA_GET_BE24(pos);
242 	pos += 3;
243 	left -= 4;
244 
245 	if (len > left) {
246 		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message "
247 			   "length (len=%lu != left=%lu)",
248 			   (unsigned long) len, (unsigned long) left);
249 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
250 		return -1;
251 	}
252 
253 	if (type == TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE)
254 		return tls_process_server_key_exchange(conn, ct, in_data,
255 						       in_len);
256 	if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
257 		return tls_process_certificate_request(conn, ct, in_data,
258 						       in_len);
259 	if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
260 		return tls_process_server_hello_done(conn, ct, in_data,
261 						     in_len);
262 	if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) {
263 		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
264 			   "message %d (expected Certificate/"
265 			   "ServerKeyExchange/CertificateRequest/"
266 			   "ServerHelloDone)", type);
267 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
268 			  TLS_ALERT_UNEXPECTED_MESSAGE);
269 		return -1;
270 	}
271 
272 	wpa_printf(MSG_DEBUG,
273 		   "TLSv1: Received Certificate (certificate_list len %lu)",
274 		   (unsigned long) len);
275 
276 	/*
277 	 * opaque ASN.1Cert<2^24-1>;
278 	 *
279 	 * struct {
280 	 *     ASN.1Cert certificate_list<1..2^24-1>;
281 	 * } Certificate;
282 	 */
283 
284 	end = pos + len;
285 
286 	if (end - pos < 3) {
287 		wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate "
288 			   "(left=%lu)", (unsigned long) left);
289 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
290 		return -1;
291 	}
292 
293 	list_len = WPA_GET_BE24(pos);
294 	pos += 3;
295 
296 	if ((size_t) (end - pos) != list_len) {
297 		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list "
298 			   "length (len=%lu left=%lu)",
299 			   (unsigned long) list_len,
300 			   (unsigned long) (end - pos));
301 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
302 		return -1;
303 	}
304 
305 	idx = 0;
306 	while (pos < end) {
307 		if (end - pos < 3) {
308 			wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
309 				   "certificate_list");
310 			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
311 				  TLS_ALERT_DECODE_ERROR);
312 			x509_certificate_chain_free(chain);
313 			return -1;
314 		}
315 
316 		cert_len = WPA_GET_BE24(pos);
317 		pos += 3;
318 
319 		if ((size_t) (end - pos) < cert_len) {
320 			wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate "
321 				   "length (len=%lu left=%lu)",
322 				   (unsigned long) cert_len,
323 				   (unsigned long) (end - pos));
324 			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
325 				  TLS_ALERT_DECODE_ERROR);
326 			x509_certificate_chain_free(chain);
327 			return -1;
328 		}
329 
330 		wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)",
331 			   (unsigned long) idx, (unsigned long) cert_len);
332 
333 		if (idx == 0) {
334 			crypto_public_key_free(conn->server_rsa_key);
335 			if (tls_parse_cert(pos, cert_len,
336 					   &conn->server_rsa_key)) {
337 				wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
338 					   "the certificate");
339 				tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
340 					  TLS_ALERT_BAD_CERTIFICATE);
341 				x509_certificate_chain_free(chain);
342 				return -1;
343 			}
344 		}
345 
346 		cert = x509_certificate_parse(pos, cert_len);
347 		if (cert == NULL) {
348 			wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
349 				   "the certificate");
350 			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
351 				  TLS_ALERT_BAD_CERTIFICATE);
352 			x509_certificate_chain_free(chain);
353 			return -1;
354 		}
355 
356 		if (last == NULL)
357 			chain = cert;
358 		else
359 			last->next = cert;
360 		last = cert;
361 
362 		idx++;
363 		pos += cert_len;
364 	}
365 
366 	if (conn->cred &&
367 	    x509_certificate_chain_validate(conn->cred->trusted_certs, chain,
368 					    &reason, conn->disable_time_checks)
369 	    < 0) {
370 		int tls_reason;
371 		wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain "
372 			   "validation failed (reason=%d)", reason);
373 		switch (reason) {
374 		case X509_VALIDATE_BAD_CERTIFICATE:
375 			tls_reason = TLS_ALERT_BAD_CERTIFICATE;
376 			break;
377 		case X509_VALIDATE_UNSUPPORTED_CERTIFICATE:
378 			tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE;
379 			break;
380 		case X509_VALIDATE_CERTIFICATE_REVOKED:
381 			tls_reason = TLS_ALERT_CERTIFICATE_REVOKED;
382 			break;
383 		case X509_VALIDATE_CERTIFICATE_EXPIRED:
384 			tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED;
385 			break;
386 		case X509_VALIDATE_CERTIFICATE_UNKNOWN:
387 			tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN;
388 			break;
389 		case X509_VALIDATE_UNKNOWN_CA:
390 			tls_reason = TLS_ALERT_UNKNOWN_CA;
391 			break;
392 		default:
393 			tls_reason = TLS_ALERT_BAD_CERTIFICATE;
394 			break;
395 		}
396 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason);
397 		x509_certificate_chain_free(chain);
398 		return -1;
399 	}
400 
401 	x509_certificate_chain_free(chain);
402 
403 	*in_len = end - in_data;
404 
405 	conn->state = SERVER_KEY_EXCHANGE;
406 
407 	return 0;
408 }
409 
410 
tlsv1_process_diffie_hellman(struct tlsv1_client * conn,const u8 * buf,size_t len)411 static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn,
412 					const u8 *buf, size_t len)
413 {
414 	const u8 *pos, *end;
415 
416 	tlsv1_client_free_dh(conn);
417 
418 	pos = buf;
419 	end = buf + len;
420 
421 	if (end - pos < 3)
422 		goto fail;
423 	conn->dh_p_len = WPA_GET_BE16(pos);
424 	pos += 2;
425 	if (conn->dh_p_len == 0 || end - pos < (int) conn->dh_p_len) {
426 		wpa_printf(MSG_DEBUG, "TLSv1: Invalid dh_p length %lu",
427 			   (unsigned long) conn->dh_p_len);
428 		goto fail;
429 	}
430 	conn->dh_p = os_malloc(conn->dh_p_len);
431 	if (conn->dh_p == NULL)
432 		goto fail;
433 	os_memcpy(conn->dh_p, pos, conn->dh_p_len);
434 	pos += conn->dh_p_len;
435 	wpa_hexdump(MSG_DEBUG, "TLSv1: DH p (prime)",
436 		    conn->dh_p, conn->dh_p_len);
437 
438 	if (end - pos < 3)
439 		goto fail;
440 	conn->dh_g_len = WPA_GET_BE16(pos);
441 	pos += 2;
442 	if (conn->dh_g_len == 0 || end - pos < (int) conn->dh_g_len)
443 		goto fail;
444 	conn->dh_g = os_malloc(conn->dh_g_len);
445 	if (conn->dh_g == NULL)
446 		goto fail;
447 	os_memcpy(conn->dh_g, pos, conn->dh_g_len);
448 	pos += conn->dh_g_len;
449 	wpa_hexdump(MSG_DEBUG, "TLSv1: DH g (generator)",
450 		    conn->dh_g, conn->dh_g_len);
451 	if (conn->dh_g_len == 1 && conn->dh_g[0] < 2)
452 		goto fail;
453 
454 	if (end - pos < 3)
455 		goto fail;
456 	conn->dh_ys_len = WPA_GET_BE16(pos);
457 	pos += 2;
458 	if (conn->dh_ys_len == 0 || end - pos < (int) conn->dh_ys_len)
459 		goto fail;
460 	conn->dh_ys = os_malloc(conn->dh_ys_len);
461 	if (conn->dh_ys == NULL)
462 		goto fail;
463 	os_memcpy(conn->dh_ys, pos, conn->dh_ys_len);
464 	pos += conn->dh_ys_len;
465 	wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)",
466 		    conn->dh_ys, conn->dh_ys_len);
467 
468 	return 0;
469 
470 fail:
471 	wpa_printf(MSG_DEBUG, "TLSv1: Processing DH params failed");
472 	tlsv1_client_free_dh(conn);
473 	return -1;
474 }
475 
476 
tls_process_server_key_exchange(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)477 static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
478 					   const u8 *in_data, size_t *in_len)
479 {
480 	const u8 *pos, *end;
481 	size_t left, len;
482 	u8 type;
483 	const struct tls_cipher_suite *suite;
484 
485 	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
486 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
487 			   "received content type 0x%x", ct);
488 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
489 			  TLS_ALERT_UNEXPECTED_MESSAGE);
490 		return -1;
491 	}
492 
493 	pos = in_data;
494 	left = *in_len;
495 
496 	if (left < 4) {
497 		wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerKeyExchange "
498 			   "(Left=%lu)", (unsigned long) left);
499 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
500 		return -1;
501 	}
502 
503 	type = *pos++;
504 	len = WPA_GET_BE24(pos);
505 	pos += 3;
506 	left -= 4;
507 
508 	if (len > left) {
509 		wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerKeyExchange "
510 			   "length (len=%lu != left=%lu)",
511 			   (unsigned long) len, (unsigned long) left);
512 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
513 		return -1;
514 	}
515 
516 	end = pos + len;
517 
518 	if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
519 		return tls_process_certificate_request(conn, ct, in_data,
520 						       in_len);
521 	if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
522 		return tls_process_server_hello_done(conn, ct, in_data,
523 						     in_len);
524 	if (type != TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE) {
525 		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
526 			   "message %d (expected ServerKeyExchange/"
527 			   "CertificateRequest/ServerHelloDone)", type);
528 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
529 			  TLS_ALERT_UNEXPECTED_MESSAGE);
530 		return -1;
531 	}
532 
533 	wpa_printf(MSG_DEBUG, "TLSv1: Received ServerKeyExchange");
534 
535 	if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) {
536 		wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not allowed "
537 			   "with the selected cipher suite");
538 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
539 			  TLS_ALERT_UNEXPECTED_MESSAGE);
540 		return -1;
541 	}
542 
543 	wpa_hexdump(MSG_DEBUG, "TLSv1: ServerKeyExchange", pos, len);
544 	suite = tls_get_cipher_suite(conn->rl.cipher_suite);
545 	if (suite && suite->key_exchange == TLS_KEY_X_DH_anon) {
546 		if (tlsv1_process_diffie_hellman(conn, pos, len) < 0) {
547 			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
548 				  TLS_ALERT_DECODE_ERROR);
549 			return -1;
550 		}
551 	} else {
552 		wpa_printf(MSG_DEBUG, "TLSv1: UnexpectedServerKeyExchange");
553 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
554 			  TLS_ALERT_UNEXPECTED_MESSAGE);
555 		return -1;
556 	}
557 
558 	*in_len = end - in_data;
559 
560 	conn->state = SERVER_CERTIFICATE_REQUEST;
561 
562 	return 0;
563 }
564 
565 
tls_process_certificate_request(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)566 static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
567 					   const u8 *in_data, size_t *in_len)
568 {
569 	const u8 *pos, *end;
570 	size_t left, len;
571 	u8 type;
572 
573 	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
574 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
575 			   "received content type 0x%x", ct);
576 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
577 			  TLS_ALERT_UNEXPECTED_MESSAGE);
578 		return -1;
579 	}
580 
581 	pos = in_data;
582 	left = *in_len;
583 
584 	if (left < 4) {
585 		wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateRequest "
586 			   "(left=%lu)", (unsigned long) left);
587 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
588 		return -1;
589 	}
590 
591 	type = *pos++;
592 	len = WPA_GET_BE24(pos);
593 	pos += 3;
594 	left -= 4;
595 
596 	if (len > left) {
597 		wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in CertificateRequest "
598 			   "length (len=%lu != left=%lu)",
599 			   (unsigned long) len, (unsigned long) left);
600 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
601 		return -1;
602 	}
603 
604 	end = pos + len;
605 
606 	if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
607 		return tls_process_server_hello_done(conn, ct, in_data,
608 						     in_len);
609 	if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) {
610 		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
611 			   "message %d (expected CertificateRequest/"
612 			   "ServerHelloDone)", type);
613 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
614 			  TLS_ALERT_UNEXPECTED_MESSAGE);
615 		return -1;
616 	}
617 
618 	wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateRequest");
619 
620 	conn->certificate_requested = 1;
621 
622 	*in_len = end - in_data;
623 
624 	conn->state = SERVER_HELLO_DONE;
625 
626 	return 0;
627 }
628 
629 
tls_process_server_hello_done(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)630 static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
631 					 const u8 *in_data, size_t *in_len)
632 {
633 	const u8 *pos, *end;
634 	size_t left, len;
635 	u8 type;
636 
637 	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
638 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
639 			   "received content type 0x%x", ct);
640 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
641 			  TLS_ALERT_UNEXPECTED_MESSAGE);
642 		return -1;
643 	}
644 
645 	pos = in_data;
646 	left = *in_len;
647 
648 	if (left < 4) {
649 		wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerHelloDone "
650 			   "(left=%lu)", (unsigned long) left);
651 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
652 		return -1;
653 	}
654 
655 	type = *pos++;
656 	len = WPA_GET_BE24(pos);
657 	pos += 3;
658 	left -= 4;
659 
660 	if (len > left) {
661 		wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerHelloDone "
662 			   "length (len=%lu != left=%lu)",
663 			   (unsigned long) len, (unsigned long) left);
664 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
665 		return -1;
666 	}
667 	end = pos + len;
668 
669 	if (type != TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) {
670 		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
671 			   "message %d (expected ServerHelloDone)", type);
672 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
673 			  TLS_ALERT_UNEXPECTED_MESSAGE);
674 		return -1;
675 	}
676 
677 	wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHelloDone");
678 
679 	*in_len = end - in_data;
680 
681 	conn->state = CLIENT_KEY_EXCHANGE;
682 
683 	return 0;
684 }
685 
686 
tls_process_server_change_cipher_spec(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)687 static int tls_process_server_change_cipher_spec(struct tlsv1_client *conn,
688 						 u8 ct, const u8 *in_data,
689 						 size_t *in_len)
690 {
691 	const u8 *pos;
692 	size_t left;
693 
694 	if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
695 		wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
696 			   "received content type 0x%x", ct);
697 		if (conn->use_session_ticket) {
698 			int res;
699 			wpa_printf(MSG_DEBUG, "TLSv1: Server may have "
700 				   "rejected SessionTicket");
701 			conn->use_session_ticket = 0;
702 
703 			/* Notify upper layers that SessionTicket failed */
704 			res = conn->session_ticket_cb(
705 				conn->session_ticket_cb_ctx, NULL, 0, NULL,
706 				NULL, NULL);
707 			if (res < 0) {
708 				wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket "
709 					   "callback indicated failure");
710 				tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
711 					  TLS_ALERT_HANDSHAKE_FAILURE);
712 				return -1;
713 			}
714 
715 			conn->state = SERVER_CERTIFICATE;
716 			return tls_process_certificate(conn, ct, in_data,
717 						       in_len);
718 		}
719 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
720 			  TLS_ALERT_UNEXPECTED_MESSAGE);
721 		return -1;
722 	}
723 
724 	pos = in_data;
725 	left = *in_len;
726 
727 	if (left < 1) {
728 		wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec");
729 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
730 		return -1;
731 	}
732 
733 	if (*pos != TLS_CHANGE_CIPHER_SPEC) {
734 		wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
735 			   "received data 0x%x", *pos);
736 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
737 			  TLS_ALERT_UNEXPECTED_MESSAGE);
738 		return -1;
739 	}
740 
741 	wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec");
742 	if (tlsv1_record_change_read_cipher(&conn->rl) < 0) {
743 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher "
744 			   "for record layer");
745 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
746 			  TLS_ALERT_INTERNAL_ERROR);
747 		return -1;
748 	}
749 
750 	*in_len = pos + 1 - in_data;
751 
752 	conn->state = SERVER_FINISHED;
753 
754 	return 0;
755 }
756 
757 
tls_process_server_finished(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)758 static int tls_process_server_finished(struct tlsv1_client *conn, u8 ct,
759 				       const u8 *in_data, size_t *in_len)
760 {
761 	const u8 *pos, *end;
762 	size_t left, len, hlen;
763 	u8 verify_data[TLS_VERIFY_DATA_LEN];
764 	u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
765 
766 	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
767 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; "
768 			   "received content type 0x%x", ct);
769 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
770 			  TLS_ALERT_UNEXPECTED_MESSAGE);
771 		return -1;
772 	}
773 
774 	pos = in_data;
775 	left = *in_len;
776 
777 	if (left < 4) {
778 		wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for "
779 			   "Finished",
780 			   (unsigned long) left);
781 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
782 			  TLS_ALERT_DECODE_ERROR);
783 		return -1;
784 	}
785 
786 	if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) {
787 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received "
788 			   "type 0x%x", pos[0]);
789 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
790 			  TLS_ALERT_UNEXPECTED_MESSAGE);
791 		return -1;
792 	}
793 
794 	len = WPA_GET_BE24(pos + 1);
795 
796 	pos += 4;
797 	left -= 4;
798 
799 	if (len > left) {
800 		wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished "
801 			   "(len=%lu > left=%lu)",
802 			   (unsigned long) len, (unsigned long) left);
803 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
804 			  TLS_ALERT_DECODE_ERROR);
805 		return -1;
806 	}
807 	end = pos + len;
808 	if (len != TLS_VERIFY_DATA_LEN) {
809 		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length "
810 			   "in Finished: %lu (expected %d)",
811 			   (unsigned long) len, TLS_VERIFY_DATA_LEN);
812 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
813 			  TLS_ALERT_DECODE_ERROR);
814 		return -1;
815 	}
816 	wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
817 		    pos, TLS_VERIFY_DATA_LEN);
818 
819 	hlen = MD5_MAC_LEN;
820 	if (conn->verify.md5_server == NULL ||
821 	    crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) {
822 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
823 			  TLS_ALERT_INTERNAL_ERROR);
824 		conn->verify.md5_server = NULL;
825 		crypto_hash_finish(conn->verify.sha1_server, NULL, NULL);
826 		conn->verify.sha1_server = NULL;
827 		return -1;
828 	}
829 	conn->verify.md5_server = NULL;
830 	hlen = SHA1_MAC_LEN;
831 	if (conn->verify.sha1_server == NULL ||
832 	    crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN,
833 			       &hlen) < 0) {
834 		conn->verify.sha1_server = NULL;
835 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
836 			  TLS_ALERT_INTERNAL_ERROR);
837 		return -1;
838 	}
839 	conn->verify.sha1_server = NULL;
840 
841 	if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
842 		    "server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
843 		    verify_data, TLS_VERIFY_DATA_LEN)) {
844 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");
845 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
846 			  TLS_ALERT_DECRYPT_ERROR);
847 		return -1;
848 	}
849 	wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
850 			verify_data, TLS_VERIFY_DATA_LEN);
851 
852 	if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
853 		wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data");
854 		return -1;
855 	}
856 
857 	wpa_printf(MSG_DEBUG, "TLSv1: Received Finished");
858 
859 	*in_len = end - in_data;
860 
861 	conn->state = (conn->session_resumed || conn->use_session_ticket) ?
862 		CHANGE_CIPHER_SPEC : ACK_FINISHED;
863 
864 	return 0;
865 }
866 
867 
tls_process_application_data(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len,u8 ** out_data,size_t * out_len)868 static int tls_process_application_data(struct tlsv1_client *conn, u8 ct,
869 					const u8 *in_data, size_t *in_len,
870 					u8 **out_data, size_t *out_len)
871 {
872 	const u8 *pos;
873 	size_t left;
874 
875 	if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
876 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Application Data; "
877 			   "received content type 0x%x", ct);
878 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
879 			  TLS_ALERT_UNEXPECTED_MESSAGE);
880 		return -1;
881 	}
882 
883 	pos = in_data;
884 	left = *in_len;
885 
886 	wpa_hexdump(MSG_DEBUG, "TLSv1: Application Data included in Handshake",
887 		    pos, left);
888 
889 	*out_data = os_malloc(left);
890 	if (*out_data) {
891 		os_memcpy(*out_data, pos, left);
892 		*out_len = left;
893 	}
894 
895 	return 0;
896 }
897 
898 
tlsv1_client_process_handshake(struct tlsv1_client * conn,u8 ct,const u8 * buf,size_t * len,u8 ** out_data,size_t * out_len)899 int tlsv1_client_process_handshake(struct tlsv1_client *conn, u8 ct,
900 				   const u8 *buf, size_t *len,
901 				   u8 **out_data, size_t *out_len)
902 {
903 	if (ct == TLS_CONTENT_TYPE_ALERT) {
904 		if (*len < 2) {
905 			wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow");
906 			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
907 				  TLS_ALERT_DECODE_ERROR);
908 			return -1;
909 		}
910 		wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",
911 			   buf[0], buf[1]);
912 		*len = 2;
913 		conn->state = FAILED;
914 		return -1;
915 	}
916 
917 	if (ct == TLS_CONTENT_TYPE_HANDSHAKE && *len >= 4 &&
918 	    buf[0] == TLS_HANDSHAKE_TYPE_HELLO_REQUEST) {
919 		size_t hr_len = WPA_GET_BE24(buf + 1);
920 		if (hr_len > *len - 4) {
921 			wpa_printf(MSG_DEBUG, "TLSv1: HelloRequest underflow");
922 			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
923 				  TLS_ALERT_DECODE_ERROR);
924 			return -1;
925 		}
926 		wpa_printf(MSG_DEBUG, "TLSv1: Ignored HelloRequest");
927 		*len = 4 + hr_len;
928 		return 0;
929 	}
930 
931 	switch (conn->state) {
932 	case SERVER_HELLO:
933 		if (tls_process_server_hello(conn, ct, buf, len))
934 			return -1;
935 		break;
936 	case SERVER_CERTIFICATE:
937 		if (tls_process_certificate(conn, ct, buf, len))
938 			return -1;
939 		break;
940 	case SERVER_KEY_EXCHANGE:
941 		if (tls_process_server_key_exchange(conn, ct, buf, len))
942 			return -1;
943 		break;
944 	case SERVER_CERTIFICATE_REQUEST:
945 		if (tls_process_certificate_request(conn, ct, buf, len))
946 			return -1;
947 		break;
948 	case SERVER_HELLO_DONE:
949 		if (tls_process_server_hello_done(conn, ct, buf, len))
950 			return -1;
951 		break;
952 	case SERVER_CHANGE_CIPHER_SPEC:
953 		if (tls_process_server_change_cipher_spec(conn, ct, buf, len))
954 			return -1;
955 		break;
956 	case SERVER_FINISHED:
957 		if (tls_process_server_finished(conn, ct, buf, len))
958 			return -1;
959 		break;
960 	case ACK_FINISHED:
961 		if (out_data &&
962 		    tls_process_application_data(conn, ct, buf, len, out_data,
963 						 out_len))
964 			return -1;
965 		break;
966 	default:
967 		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d "
968 			   "while processing received message",
969 			   conn->state);
970 		return -1;
971 	}
972 
973 	if (ct == TLS_CONTENT_TYPE_HANDSHAKE)
974 		tls_verify_hash_add(&conn->verify, buf, *len);
975 
976 	return 0;
977 }
978