• 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 "md5.h"
19 #include "sha1.h"
20 #include "x509v3.h"
21 #include "tls.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) < 0) {
369 		int tls_reason;
370 		wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain "
371 			   "validation failed (reason=%d)", reason);
372 		switch (reason) {
373 		case X509_VALIDATE_BAD_CERTIFICATE:
374 			tls_reason = TLS_ALERT_BAD_CERTIFICATE;
375 			break;
376 		case X509_VALIDATE_UNSUPPORTED_CERTIFICATE:
377 			tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE;
378 			break;
379 		case X509_VALIDATE_CERTIFICATE_REVOKED:
380 			tls_reason = TLS_ALERT_CERTIFICATE_REVOKED;
381 			break;
382 		case X509_VALIDATE_CERTIFICATE_EXPIRED:
383 			tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED;
384 			break;
385 		case X509_VALIDATE_CERTIFICATE_UNKNOWN:
386 			tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN;
387 			break;
388 		case X509_VALIDATE_UNKNOWN_CA:
389 			tls_reason = TLS_ALERT_UNKNOWN_CA;
390 			break;
391 		default:
392 			tls_reason = TLS_ALERT_BAD_CERTIFICATE;
393 			break;
394 		}
395 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason);
396 		x509_certificate_chain_free(chain);
397 		return -1;
398 	}
399 
400 	x509_certificate_chain_free(chain);
401 
402 	*in_len = end - in_data;
403 
404 	conn->state = SERVER_KEY_EXCHANGE;
405 
406 	return 0;
407 }
408 
409 
tlsv1_process_diffie_hellman(struct tlsv1_client * conn,const u8 * buf,size_t len)410 static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn,
411 					const u8 *buf, size_t len)
412 {
413 	const u8 *pos, *end;
414 
415 	tlsv1_client_free_dh(conn);
416 
417 	pos = buf;
418 	end = buf + len;
419 
420 	if (end - pos < 3)
421 		goto fail;
422 	conn->dh_p_len = WPA_GET_BE16(pos);
423 	pos += 2;
424 	if (conn->dh_p_len == 0 || end - pos < (int) conn->dh_p_len) {
425 		wpa_printf(MSG_DEBUG, "TLSv1: Invalid dh_p length %lu",
426 			   (unsigned long) conn->dh_p_len);
427 		goto fail;
428 	}
429 	conn->dh_p = os_malloc(conn->dh_p_len);
430 	if (conn->dh_p == NULL)
431 		goto fail;
432 	os_memcpy(conn->dh_p, pos, conn->dh_p_len);
433 	pos += conn->dh_p_len;
434 	wpa_hexdump(MSG_DEBUG, "TLSv1: DH p (prime)",
435 		    conn->dh_p, conn->dh_p_len);
436 
437 	if (end - pos < 3)
438 		goto fail;
439 	conn->dh_g_len = WPA_GET_BE16(pos);
440 	pos += 2;
441 	if (conn->dh_g_len == 0 || end - pos < (int) conn->dh_g_len)
442 		goto fail;
443 	conn->dh_g = os_malloc(conn->dh_g_len);
444 	if (conn->dh_g == NULL)
445 		goto fail;
446 	os_memcpy(conn->dh_g, pos, conn->dh_g_len);
447 	pos += conn->dh_g_len;
448 	wpa_hexdump(MSG_DEBUG, "TLSv1: DH g (generator)",
449 		    conn->dh_g, conn->dh_g_len);
450 	if (conn->dh_g_len == 1 && conn->dh_g[0] < 2)
451 		goto fail;
452 
453 	if (end - pos < 3)
454 		goto fail;
455 	conn->dh_ys_len = WPA_GET_BE16(pos);
456 	pos += 2;
457 	if (conn->dh_ys_len == 0 || end - pos < (int) conn->dh_ys_len)
458 		goto fail;
459 	conn->dh_ys = os_malloc(conn->dh_ys_len);
460 	if (conn->dh_ys == NULL)
461 		goto fail;
462 	os_memcpy(conn->dh_ys, pos, conn->dh_ys_len);
463 	pos += conn->dh_ys_len;
464 	wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)",
465 		    conn->dh_ys, conn->dh_ys_len);
466 
467 	return 0;
468 
469 fail:
470 	wpa_printf(MSG_DEBUG, "TLSv1: Processing DH params failed");
471 	tlsv1_client_free_dh(conn);
472 	return -1;
473 }
474 
475 
tls_process_server_key_exchange(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)476 static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
477 					   const u8 *in_data, size_t *in_len)
478 {
479 	const u8 *pos, *end;
480 	size_t left, len;
481 	u8 type;
482 	const struct tls_cipher_suite *suite;
483 
484 	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
485 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
486 			   "received content type 0x%x", ct);
487 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
488 			  TLS_ALERT_UNEXPECTED_MESSAGE);
489 		return -1;
490 	}
491 
492 	pos = in_data;
493 	left = *in_len;
494 
495 	if (left < 4) {
496 		wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerKeyExchange "
497 			   "(Left=%lu)", (unsigned long) left);
498 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
499 		return -1;
500 	}
501 
502 	type = *pos++;
503 	len = WPA_GET_BE24(pos);
504 	pos += 3;
505 	left -= 4;
506 
507 	if (len > left) {
508 		wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerKeyExchange "
509 			   "length (len=%lu != left=%lu)",
510 			   (unsigned long) len, (unsigned long) left);
511 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
512 		return -1;
513 	}
514 
515 	end = pos + len;
516 
517 	if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
518 		return tls_process_certificate_request(conn, ct, in_data,
519 						       in_len);
520 	if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
521 		return tls_process_server_hello_done(conn, ct, in_data,
522 						     in_len);
523 	if (type != TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE) {
524 		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
525 			   "message %d (expected ServerKeyExchange/"
526 			   "CertificateRequest/ServerHelloDone)", type);
527 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
528 			  TLS_ALERT_UNEXPECTED_MESSAGE);
529 		return -1;
530 	}
531 
532 	wpa_printf(MSG_DEBUG, "TLSv1: Received ServerKeyExchange");
533 
534 	if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) {
535 		wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not allowed "
536 			   "with the selected cipher suite");
537 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
538 			  TLS_ALERT_UNEXPECTED_MESSAGE);
539 		return -1;
540 	}
541 
542 	wpa_hexdump(MSG_DEBUG, "TLSv1: ServerKeyExchange", pos, len);
543 	suite = tls_get_cipher_suite(conn->rl.cipher_suite);
544 	if (suite && suite->key_exchange == TLS_KEY_X_DH_anon) {
545 		if (tlsv1_process_diffie_hellman(conn, pos, len) < 0) {
546 			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
547 				  TLS_ALERT_DECODE_ERROR);
548 			return -1;
549 		}
550 	} else {
551 		wpa_printf(MSG_DEBUG, "TLSv1: UnexpectedServerKeyExchange");
552 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
553 			  TLS_ALERT_UNEXPECTED_MESSAGE);
554 		return -1;
555 	}
556 
557 	*in_len = end - in_data;
558 
559 	conn->state = SERVER_CERTIFICATE_REQUEST;
560 
561 	return 0;
562 }
563 
564 
tls_process_certificate_request(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)565 static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
566 					   const u8 *in_data, size_t *in_len)
567 {
568 	const u8 *pos, *end;
569 	size_t left, len;
570 	u8 type;
571 
572 	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
573 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
574 			   "received content type 0x%x", ct);
575 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
576 			  TLS_ALERT_UNEXPECTED_MESSAGE);
577 		return -1;
578 	}
579 
580 	pos = in_data;
581 	left = *in_len;
582 
583 	if (left < 4) {
584 		wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateRequest "
585 			   "(left=%lu)", (unsigned long) left);
586 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
587 		return -1;
588 	}
589 
590 	type = *pos++;
591 	len = WPA_GET_BE24(pos);
592 	pos += 3;
593 	left -= 4;
594 
595 	if (len > left) {
596 		wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in CertificateRequest "
597 			   "length (len=%lu != left=%lu)",
598 			   (unsigned long) len, (unsigned long) left);
599 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
600 		return -1;
601 	}
602 
603 	end = pos + len;
604 
605 	if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
606 		return tls_process_server_hello_done(conn, ct, in_data,
607 						     in_len);
608 	if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) {
609 		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
610 			   "message %d (expected CertificateRequest/"
611 			   "ServerHelloDone)", type);
612 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
613 			  TLS_ALERT_UNEXPECTED_MESSAGE);
614 		return -1;
615 	}
616 
617 	wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateRequest");
618 
619 	conn->certificate_requested = 1;
620 
621 	*in_len = end - in_data;
622 
623 	conn->state = SERVER_HELLO_DONE;
624 
625 	return 0;
626 }
627 
628 
tls_process_server_hello_done(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)629 static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
630 					 const u8 *in_data, size_t *in_len)
631 {
632 	const u8 *pos, *end;
633 	size_t left, len;
634 	u8 type;
635 
636 	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
637 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
638 			   "received content type 0x%x", ct);
639 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
640 			  TLS_ALERT_UNEXPECTED_MESSAGE);
641 		return -1;
642 	}
643 
644 	pos = in_data;
645 	left = *in_len;
646 
647 	if (left < 4) {
648 		wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerHelloDone "
649 			   "(left=%lu)", (unsigned long) left);
650 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
651 		return -1;
652 	}
653 
654 	type = *pos++;
655 	len = WPA_GET_BE24(pos);
656 	pos += 3;
657 	left -= 4;
658 
659 	if (len > left) {
660 		wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerHelloDone "
661 			   "length (len=%lu != left=%lu)",
662 			   (unsigned long) len, (unsigned long) left);
663 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
664 		return -1;
665 	}
666 	end = pos + len;
667 
668 	if (type != TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) {
669 		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
670 			   "message %d (expected ServerHelloDone)", type);
671 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
672 			  TLS_ALERT_UNEXPECTED_MESSAGE);
673 		return -1;
674 	}
675 
676 	wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHelloDone");
677 
678 	*in_len = end - in_data;
679 
680 	conn->state = CLIENT_KEY_EXCHANGE;
681 
682 	return 0;
683 }
684 
685 
tls_process_server_change_cipher_spec(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)686 static int tls_process_server_change_cipher_spec(struct tlsv1_client *conn,
687 						 u8 ct, const u8 *in_data,
688 						 size_t *in_len)
689 {
690 	const u8 *pos;
691 	size_t left;
692 
693 	if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
694 		wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
695 			   "received content type 0x%x", ct);
696 		if (conn->use_session_ticket) {
697 			int res;
698 			wpa_printf(MSG_DEBUG, "TLSv1: Server may have "
699 				   "rejected SessionTicket");
700 			conn->use_session_ticket = 0;
701 
702 			/* Notify upper layers that SessionTicket failed */
703 			res = conn->session_ticket_cb(
704 				conn->session_ticket_cb_ctx, NULL, 0, NULL,
705 				NULL, NULL);
706 			if (res < 0) {
707 				wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket "
708 					   "callback indicated failure");
709 				tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
710 					  TLS_ALERT_HANDSHAKE_FAILURE);
711 				return -1;
712 			}
713 
714 			conn->state = SERVER_CERTIFICATE;
715 			return tls_process_certificate(conn, ct, in_data,
716 						       in_len);
717 		}
718 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
719 			  TLS_ALERT_UNEXPECTED_MESSAGE);
720 		return -1;
721 	}
722 
723 	pos = in_data;
724 	left = *in_len;
725 
726 	if (left < 1) {
727 		wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec");
728 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
729 		return -1;
730 	}
731 
732 	if (*pos != TLS_CHANGE_CIPHER_SPEC) {
733 		wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
734 			   "received data 0x%x", *pos);
735 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
736 			  TLS_ALERT_UNEXPECTED_MESSAGE);
737 		return -1;
738 	}
739 
740 	wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec");
741 	if (tlsv1_record_change_read_cipher(&conn->rl) < 0) {
742 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher "
743 			   "for record layer");
744 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
745 			  TLS_ALERT_INTERNAL_ERROR);
746 		return -1;
747 	}
748 
749 	*in_len = pos + 1 - in_data;
750 
751 	conn->state = SERVER_FINISHED;
752 
753 	return 0;
754 }
755 
756 
tls_process_server_finished(struct tlsv1_client * conn,u8 ct,const u8 * in_data,size_t * in_len)757 static int tls_process_server_finished(struct tlsv1_client *conn, u8 ct,
758 				       const u8 *in_data, size_t *in_len)
759 {
760 	const u8 *pos, *end;
761 	size_t left, len, hlen;
762 	u8 verify_data[TLS_VERIFY_DATA_LEN];
763 	u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
764 
765 	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
766 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; "
767 			   "received content type 0x%x", ct);
768 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
769 			  TLS_ALERT_UNEXPECTED_MESSAGE);
770 		return -1;
771 	}
772 
773 	pos = in_data;
774 	left = *in_len;
775 
776 	if (left < 4) {
777 		wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for "
778 			   "Finished",
779 			   (unsigned long) left);
780 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
781 			  TLS_ALERT_DECODE_ERROR);
782 		return -1;
783 	}
784 
785 	if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) {
786 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received "
787 			   "type 0x%x", pos[0]);
788 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
789 			  TLS_ALERT_UNEXPECTED_MESSAGE);
790 		return -1;
791 	}
792 
793 	len = WPA_GET_BE24(pos + 1);
794 
795 	pos += 4;
796 	left -= 4;
797 
798 	if (len > left) {
799 		wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished "
800 			   "(len=%lu > left=%lu)",
801 			   (unsigned long) len, (unsigned long) left);
802 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
803 			  TLS_ALERT_DECODE_ERROR);
804 		return -1;
805 	}
806 	end = pos + len;
807 	if (len != TLS_VERIFY_DATA_LEN) {
808 		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length "
809 			   "in Finished: %lu (expected %d)",
810 			   (unsigned long) len, TLS_VERIFY_DATA_LEN);
811 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
812 			  TLS_ALERT_DECODE_ERROR);
813 		return -1;
814 	}
815 	wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
816 		    pos, TLS_VERIFY_DATA_LEN);
817 
818 	hlen = MD5_MAC_LEN;
819 	if (conn->verify.md5_server == NULL ||
820 	    crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) {
821 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
822 			  TLS_ALERT_INTERNAL_ERROR);
823 		conn->verify.md5_server = NULL;
824 		crypto_hash_finish(conn->verify.sha1_server, NULL, NULL);
825 		conn->verify.sha1_server = NULL;
826 		return -1;
827 	}
828 	conn->verify.md5_server = NULL;
829 	hlen = SHA1_MAC_LEN;
830 	if (conn->verify.sha1_server == NULL ||
831 	    crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN,
832 			       &hlen) < 0) {
833 		conn->verify.sha1_server = NULL;
834 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
835 			  TLS_ALERT_INTERNAL_ERROR);
836 		return -1;
837 	}
838 	conn->verify.sha1_server = NULL;
839 
840 	if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
841 		    "server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
842 		    verify_data, TLS_VERIFY_DATA_LEN)) {
843 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");
844 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
845 			  TLS_ALERT_DECRYPT_ERROR);
846 		return -1;
847 	}
848 	wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
849 			verify_data, TLS_VERIFY_DATA_LEN);
850 
851 	if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
852 		wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data");
853 		return -1;
854 	}
855 
856 	wpa_printf(MSG_DEBUG, "TLSv1: Received Finished");
857 
858 	*in_len = end - in_data;
859 
860 	conn->state = (conn->session_resumed || conn->use_session_ticket) ?
861 		CHANGE_CIPHER_SPEC : ACK_FINISHED;
862 
863 	return 0;
864 }
865 
866 
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)867 static int tls_process_application_data(struct tlsv1_client *conn, u8 ct,
868 					const u8 *in_data, size_t *in_len,
869 					u8 **out_data, size_t *out_len)
870 {
871 	const u8 *pos;
872 	size_t left;
873 
874 	if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
875 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Application Data; "
876 			   "received content type 0x%x", ct);
877 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
878 			  TLS_ALERT_UNEXPECTED_MESSAGE);
879 		return -1;
880 	}
881 
882 	pos = in_data;
883 	left = *in_len;
884 
885 	wpa_hexdump(MSG_DEBUG, "TLSv1: Application Data included in Handshake",
886 		    pos, left);
887 
888 	*out_data = os_malloc(left);
889 	if (*out_data) {
890 		os_memcpy(*out_data, pos, left);
891 		*out_len = left;
892 	}
893 
894 	return 0;
895 }
896 
897 
tlsv1_client_process_handshake(struct tlsv1_client * conn,u8 ct,const u8 * buf,size_t * len,u8 ** out_data,size_t * out_len)898 int tlsv1_client_process_handshake(struct tlsv1_client *conn, u8 ct,
899 				   const u8 *buf, size_t *len,
900 				   u8 **out_data, size_t *out_len)
901 {
902 	if (ct == TLS_CONTENT_TYPE_ALERT) {
903 		if (*len < 2) {
904 			wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow");
905 			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
906 				  TLS_ALERT_DECODE_ERROR);
907 			return -1;
908 		}
909 		wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",
910 			   buf[0], buf[1]);
911 		*len = 2;
912 		conn->state = FAILED;
913 		return -1;
914 	}
915 
916 	if (ct == TLS_CONTENT_TYPE_HANDSHAKE && *len >= 4 &&
917 	    buf[0] == TLS_HANDSHAKE_TYPE_HELLO_REQUEST) {
918 		size_t hr_len = WPA_GET_BE24(buf + 1);
919 		if (hr_len > *len - 4) {
920 			wpa_printf(MSG_DEBUG, "TLSv1: HelloRequest underflow");
921 			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
922 				  TLS_ALERT_DECODE_ERROR);
923 			return -1;
924 		}
925 		wpa_printf(MSG_DEBUG, "TLSv1: Ignored HelloRequest");
926 		*len = 4 + hr_len;
927 		return 0;
928 	}
929 
930 	switch (conn->state) {
931 	case SERVER_HELLO:
932 		if (tls_process_server_hello(conn, ct, buf, len))
933 			return -1;
934 		break;
935 	case SERVER_CERTIFICATE:
936 		if (tls_process_certificate(conn, ct, buf, len))
937 			return -1;
938 		break;
939 	case SERVER_KEY_EXCHANGE:
940 		if (tls_process_server_key_exchange(conn, ct, buf, len))
941 			return -1;
942 		break;
943 	case SERVER_CERTIFICATE_REQUEST:
944 		if (tls_process_certificate_request(conn, ct, buf, len))
945 			return -1;
946 		break;
947 	case SERVER_HELLO_DONE:
948 		if (tls_process_server_hello_done(conn, ct, buf, len))
949 			return -1;
950 		break;
951 	case SERVER_CHANGE_CIPHER_SPEC:
952 		if (tls_process_server_change_cipher_spec(conn, ct, buf, len))
953 			return -1;
954 		break;
955 	case SERVER_FINISHED:
956 		if (tls_process_server_finished(conn, ct, buf, len))
957 			return -1;
958 		break;
959 	case ACK_FINISHED:
960 		if (out_data &&
961 		    tls_process_application_data(conn, ct, buf, len, out_data,
962 						 out_len))
963 			return -1;
964 		break;
965 	default:
966 		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d "
967 			   "while processing received message",
968 			   conn->state);
969 		return -1;
970 	}
971 
972 	if (ct == TLS_CONTENT_TYPE_HANDSHAKE)
973 		tls_verify_hash_add(&conn->verify, buf, *len);
974 
975 	return 0;
976 }
977