1 /*
2  * TLSv1 server - write 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_server.h"
25 #include "tlsv1_server_i.h"
26 
27 
tls_server_cert_chain_der_len(struct tlsv1_server * conn)28 static size_t tls_server_cert_chain_der_len(struct tlsv1_server *conn)
29 {
30 	size_t len = 0;
31 	struct x509_certificate *cert;
32 
33 	cert = conn->cred->cert;
34 	while (cert) {
35 		len += 3 + cert->cert_len;
36 		if (x509_certificate_self_signed(cert))
37 			break;
38 		cert = x509_certificate_get_subject(conn->cred->trusted_certs,
39 						    &cert->issuer);
40 	}
41 
42 	return len;
43 }
44 
45 
tls_write_server_hello(struct tlsv1_server * conn,u8 ** msgpos,u8 * end)46 static int tls_write_server_hello(struct tlsv1_server *conn,
47 				  u8 **msgpos, u8 *end)
48 {
49 	u8 *pos, *rhdr, *hs_start, *hs_length;
50 	struct os_time now;
51 	size_t rlen;
52 
53 	pos = *msgpos;
54 
55 	wpa_printf(MSG_DEBUG, "TLSv1: Send ServerHello");
56 	rhdr = pos;
57 	pos += TLS_RECORD_HEADER_LEN;
58 
59 	os_get_time(&now);
60 	WPA_PUT_BE32(conn->server_random, now.sec);
61 	if (os_get_random(conn->server_random + 4, TLS_RANDOM_LEN - 4)) {
62 		wpa_printf(MSG_ERROR, "TLSv1: Could not generate "
63 			   "server_random");
64 		return -1;
65 	}
66 	wpa_hexdump(MSG_MSGDUMP, "TLSv1: server_random",
67 		    conn->server_random, TLS_RANDOM_LEN);
68 
69 	conn->session_id_len = TLS_SESSION_ID_MAX_LEN;
70 	if (os_get_random(conn->session_id, conn->session_id_len)) {
71 		wpa_printf(MSG_ERROR, "TLSv1: Could not generate "
72 			   "session_id");
73 		return -1;
74 	}
75 	wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id",
76 		    conn->session_id, conn->session_id_len);
77 
78 	/* opaque fragment[TLSPlaintext.length] */
79 
80 	/* Handshake */
81 	hs_start = pos;
82 	/* HandshakeType msg_type */
83 	*pos++ = TLS_HANDSHAKE_TYPE_SERVER_HELLO;
84 	/* uint24 length (to be filled) */
85 	hs_length = pos;
86 	pos += 3;
87 	/* body - ServerHello */
88 	/* ProtocolVersion server_version */
89 	WPA_PUT_BE16(pos, TLS_VERSION);
90 	pos += 2;
91 	/* Random random: uint32 gmt_unix_time, opaque random_bytes */
92 	os_memcpy(pos, conn->server_random, TLS_RANDOM_LEN);
93 	pos += TLS_RANDOM_LEN;
94 	/* SessionID session_id */
95 	*pos++ = conn->session_id_len;
96 	os_memcpy(pos, conn->session_id, conn->session_id_len);
97 	pos += conn->session_id_len;
98 	/* CipherSuite cipher_suite */
99 	WPA_PUT_BE16(pos, conn->cipher_suite);
100 	pos += 2;
101 	/* CompressionMethod compression_method */
102 	*pos++ = TLS_COMPRESSION_NULL;
103 
104 	if (conn->session_ticket && conn->session_ticket_cb) {
105 		int res = conn->session_ticket_cb(
106 			conn->session_ticket_cb_ctx,
107 			conn->session_ticket, conn->session_ticket_len,
108 			conn->client_random, conn->server_random,
109 			conn->master_secret);
110 		if (res < 0) {
111 			wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback "
112 				   "indicated failure");
113 			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
114 					   TLS_ALERT_HANDSHAKE_FAILURE);
115 			return -1;
116 		}
117 		conn->use_session_ticket = res;
118 
119 		if (conn->use_session_ticket) {
120 			if (tlsv1_server_derive_keys(conn, NULL, 0) < 0) {
121 				wpa_printf(MSG_DEBUG, "TLSv1: Failed to "
122 					   "derive keys");
123 				tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
124 						   TLS_ALERT_INTERNAL_ERROR);
125 				return -1;
126 			}
127 		}
128 
129 		/*
130 		 * RFC 4507 specifies that server would include an empty
131 		 * SessionTicket extension in ServerHello and a
132 		 * NewSessionTicket message after the ServerHello. However,
133 		 * EAP-FAST (RFC 4851), i.e., the only user of SessionTicket
134 		 * extension at the moment, does not use such extensions.
135 		 *
136 		 * TODO: Add support for configuring RFC 4507 behavior and make
137 		 * EAP-FAST disable it.
138 		 */
139 	}
140 
141 	WPA_PUT_BE24(hs_length, pos - hs_length - 3);
142 	tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
143 
144 	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
145 			      rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
146 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record");
147 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
148 				   TLS_ALERT_INTERNAL_ERROR);
149 		return -1;
150 	}
151 	pos = rhdr + rlen;
152 
153 	*msgpos = pos;
154 
155 	return 0;
156 }
157 
158 
tls_write_server_certificate(struct tlsv1_server * conn,u8 ** msgpos,u8 * end)159 static int tls_write_server_certificate(struct tlsv1_server *conn,
160 					u8 **msgpos, u8 *end)
161 {
162 	u8 *pos, *rhdr, *hs_start, *hs_length, *cert_start;
163 	size_t rlen;
164 	struct x509_certificate *cert;
165 	const struct tls_cipher_suite *suite;
166 
167 	suite = tls_get_cipher_suite(conn->rl.cipher_suite);
168 	if (suite && suite->key_exchange == TLS_KEY_X_DH_anon) {
169 		wpa_printf(MSG_DEBUG, "TLSv1: Do not send Certificate when "
170 			   "using anonymous DH");
171 		return 0;
172 	}
173 
174 	pos = *msgpos;
175 
176 	wpa_printf(MSG_DEBUG, "TLSv1: Send Certificate");
177 	rhdr = pos;
178 	pos += TLS_RECORD_HEADER_LEN;
179 
180 	/* opaque fragment[TLSPlaintext.length] */
181 
182 	/* Handshake */
183 	hs_start = pos;
184 	/* HandshakeType msg_type */
185 	*pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE;
186 	/* uint24 length (to be filled) */
187 	hs_length = pos;
188 	pos += 3;
189 	/* body - Certificate */
190 	/* uint24 length (to be filled) */
191 	cert_start = pos;
192 	pos += 3;
193 	cert = conn->cred->cert;
194 	while (cert) {
195 		if (pos + 3 + cert->cert_len > end) {
196 			wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space "
197 				   "for Certificate (cert_len=%lu left=%lu)",
198 				   (unsigned long) cert->cert_len,
199 				   (unsigned long) (end - pos));
200 			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
201 					   TLS_ALERT_INTERNAL_ERROR);
202 			return -1;
203 		}
204 		WPA_PUT_BE24(pos, cert->cert_len);
205 		pos += 3;
206 		os_memcpy(pos, cert->cert_start, cert->cert_len);
207 		pos += cert->cert_len;
208 
209 		if (x509_certificate_self_signed(cert))
210 			break;
211 		cert = x509_certificate_get_subject(conn->cred->trusted_certs,
212 						    &cert->issuer);
213 	}
214 	if (cert == conn->cred->cert || cert == NULL) {
215 		/*
216 		 * Server was not configured with all the needed certificates
217 		 * to form a full certificate chain. The client may fail to
218 		 * validate the chain unless it is configured with all the
219 		 * missing CA certificates.
220 		 */
221 		wpa_printf(MSG_DEBUG, "TLSv1: Full server certificate chain "
222 			   "not configured - validation may fail");
223 	}
224 	WPA_PUT_BE24(cert_start, pos - cert_start - 3);
225 
226 	WPA_PUT_BE24(hs_length, pos - hs_length - 3);
227 
228 	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
229 			      rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
230 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
231 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
232 				   TLS_ALERT_INTERNAL_ERROR);
233 		return -1;
234 	}
235 	pos = rhdr + rlen;
236 
237 	tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
238 
239 	*msgpos = pos;
240 
241 	return 0;
242 }
243 
244 
tls_write_server_key_exchange(struct tlsv1_server * conn,u8 ** msgpos,u8 * end)245 static int tls_write_server_key_exchange(struct tlsv1_server *conn,
246 					 u8 **msgpos, u8 *end)
247 {
248 	tls_key_exchange keyx;
249 	const struct tls_cipher_suite *suite;
250 	u8 *pos, *rhdr, *hs_start, *hs_length;
251 	size_t rlen;
252 	u8 *dh_ys;
253 	size_t dh_ys_len;
254 
255 	suite = tls_get_cipher_suite(conn->rl.cipher_suite);
256 	if (suite == NULL)
257 		keyx = TLS_KEY_X_NULL;
258 	else
259 		keyx = suite->key_exchange;
260 
261 	if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) {
262 		wpa_printf(MSG_DEBUG, "TLSv1: No ServerKeyExchange needed");
263 		return 0;
264 	}
265 
266 	if (keyx != TLS_KEY_X_DH_anon) {
267 		/* TODO? */
268 		wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not yet "
269 			   "supported with key exchange type %d", keyx);
270 		return -1;
271 	}
272 
273 	if (conn->cred == NULL || conn->cred->dh_p == NULL ||
274 	    conn->cred->dh_g == NULL) {
275 		wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available for "
276 			   "ServerKeyExhcange");
277 		return -1;
278 	}
279 
280 	os_free(conn->dh_secret);
281 	conn->dh_secret_len = conn->cred->dh_p_len;
282 	conn->dh_secret = os_malloc(conn->dh_secret_len);
283 	if (conn->dh_secret == NULL) {
284 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate "
285 			   "memory for secret (Diffie-Hellman)");
286 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
287 				   TLS_ALERT_INTERNAL_ERROR);
288 		return -1;
289 	}
290 	if (os_get_random(conn->dh_secret, conn->dh_secret_len)) {
291 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random "
292 			   "data for Diffie-Hellman");
293 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
294 				   TLS_ALERT_INTERNAL_ERROR);
295 		os_free(conn->dh_secret);
296 		conn->dh_secret = NULL;
297 		return -1;
298 	}
299 
300 	if (os_memcmp(conn->dh_secret, conn->cred->dh_p, conn->dh_secret_len) >
301 	    0)
302 		conn->dh_secret[0] = 0; /* make sure secret < p */
303 
304 	pos = conn->dh_secret;
305 	while (pos + 1 < conn->dh_secret + conn->dh_secret_len && *pos == 0)
306 		pos++;
307 	if (pos != conn->dh_secret) {
308 		os_memmove(conn->dh_secret, pos,
309 			   conn->dh_secret_len - (pos - conn->dh_secret));
310 		conn->dh_secret_len -= pos - conn->dh_secret;
311 	}
312 	wpa_hexdump_key(MSG_DEBUG, "TLSv1: DH server's secret value",
313 			conn->dh_secret, conn->dh_secret_len);
314 
315 	/* Ys = g^secret mod p */
316 	dh_ys_len = conn->cred->dh_p_len;
317 	dh_ys = os_malloc(dh_ys_len);
318 	if (dh_ys == NULL) {
319 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate memory for "
320 			   "Diffie-Hellman");
321 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
322 				   TLS_ALERT_INTERNAL_ERROR);
323 		return -1;
324 	}
325 	if (crypto_mod_exp(conn->cred->dh_g, conn->cred->dh_g_len,
326 			   conn->dh_secret, conn->dh_secret_len,
327 			   conn->cred->dh_p, conn->cred->dh_p_len,
328 			   dh_ys, &dh_ys_len)) {
329 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
330 				   TLS_ALERT_INTERNAL_ERROR);
331 		os_free(dh_ys);
332 		return -1;
333 	}
334 
335 	wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)",
336 		    dh_ys, dh_ys_len);
337 
338 	/*
339 	 * struct {
340 	 *    select (KeyExchangeAlgorithm) {
341 	 *       case diffie_hellman:
342 	 *          ServerDHParams params;
343 	 *          Signature signed_params;
344 	 *       case rsa:
345 	 *          ServerRSAParams params;
346 	 *          Signature signed_params;
347 	 *    };
348 	 * } ServerKeyExchange;
349 	 *
350 	 * struct {
351 	 *    opaque dh_p<1..2^16-1>;
352 	 *    opaque dh_g<1..2^16-1>;
353 	 *    opaque dh_Ys<1..2^16-1>;
354 	 * } ServerDHParams;
355 	 */
356 
357 	pos = *msgpos;
358 
359 	wpa_printf(MSG_DEBUG, "TLSv1: Send ServerKeyExchange");
360 	rhdr = pos;
361 	pos += TLS_RECORD_HEADER_LEN;
362 
363 	/* opaque fragment[TLSPlaintext.length] */
364 
365 	/* Handshake */
366 	hs_start = pos;
367 	/* HandshakeType msg_type */
368 	*pos++ = TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE;
369 	/* uint24 length (to be filled) */
370 	hs_length = pos;
371 	pos += 3;
372 
373 	/* body - ServerDHParams */
374 	/* dh_p */
375 	if (pos + 2 + conn->cred->dh_p_len > end) {
376 		wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for "
377 			   "dh_p");
378 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
379 				   TLS_ALERT_INTERNAL_ERROR);
380 		os_free(dh_ys);
381 		return -1;
382 	}
383 	WPA_PUT_BE16(pos, conn->cred->dh_p_len);
384 	pos += 2;
385 	os_memcpy(pos, conn->cred->dh_p, conn->cred->dh_p_len);
386 	pos += conn->cred->dh_p_len;
387 
388 	/* dh_g */
389 	if (pos + 2 + conn->cred->dh_g_len > end) {
390 		wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for "
391 			   "dh_g");
392 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
393 				   TLS_ALERT_INTERNAL_ERROR);
394 		os_free(dh_ys);
395 		return -1;
396 	}
397 	WPA_PUT_BE16(pos, conn->cred->dh_g_len);
398 	pos += 2;
399 	os_memcpy(pos, conn->cred->dh_g, conn->cred->dh_g_len);
400 	pos += conn->cred->dh_g_len;
401 
402 	/* dh_Ys */
403 	if (pos + 2 + dh_ys_len > end) {
404 		wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space for "
405 			   "dh_Ys");
406 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
407 				   TLS_ALERT_INTERNAL_ERROR);
408 		os_free(dh_ys);
409 		return -1;
410 	}
411 	WPA_PUT_BE16(pos, dh_ys_len);
412 	pos += 2;
413 	os_memcpy(pos, dh_ys, dh_ys_len);
414 	pos += dh_ys_len;
415 	os_free(dh_ys);
416 
417 	WPA_PUT_BE24(hs_length, pos - hs_length - 3);
418 
419 	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
420 			      rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
421 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
422 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
423 				   TLS_ALERT_INTERNAL_ERROR);
424 		return -1;
425 	}
426 	pos = rhdr + rlen;
427 
428 	tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
429 
430 	*msgpos = pos;
431 
432 	return 0;
433 }
434 
435 
tls_write_server_certificate_request(struct tlsv1_server * conn,u8 ** msgpos,u8 * end)436 static int tls_write_server_certificate_request(struct tlsv1_server *conn,
437 						u8 **msgpos, u8 *end)
438 {
439 	u8 *pos, *rhdr, *hs_start, *hs_length;
440 	size_t rlen;
441 
442 	if (!conn->verify_peer) {
443 		wpa_printf(MSG_DEBUG, "TLSv1: No CertificateRequest needed");
444 		return 0;
445 	}
446 
447 	pos = *msgpos;
448 
449 	wpa_printf(MSG_DEBUG, "TLSv1: Send CertificateRequest");
450 	rhdr = pos;
451 	pos += TLS_RECORD_HEADER_LEN;
452 
453 	/* opaque fragment[TLSPlaintext.length] */
454 
455 	/* Handshake */
456 	hs_start = pos;
457 	/* HandshakeType msg_type */
458 	*pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST;
459 	/* uint24 length (to be filled) */
460 	hs_length = pos;
461 	pos += 3;
462 	/* body - CertificateRequest */
463 
464 	/*
465 	 * enum {
466 	 *   rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
467 	 *   (255)
468 	 * } ClientCertificateType;
469 	 * ClientCertificateType certificate_types<1..2^8-1>
470 	 */
471 	*pos++ = 1;
472 	*pos++ = 1; /* rsa_sign */
473 
474 	/*
475 	 * opaque DistinguishedName<1..2^16-1>
476 	 * DistinguishedName certificate_authorities<3..2^16-1>
477 	 */
478 	/* TODO: add support for listing DNs for trusted CAs */
479 	WPA_PUT_BE16(pos, 0);
480 	pos += 2;
481 
482 	WPA_PUT_BE24(hs_length, pos - hs_length - 3);
483 
484 	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
485 			      rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
486 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
487 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
488 				   TLS_ALERT_INTERNAL_ERROR);
489 		return -1;
490 	}
491 	pos = rhdr + rlen;
492 
493 	tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
494 
495 	*msgpos = pos;
496 
497 	return 0;
498 }
499 
500 
tls_write_server_hello_done(struct tlsv1_server * conn,u8 ** msgpos,u8 * end)501 static int tls_write_server_hello_done(struct tlsv1_server *conn,
502 				       u8 **msgpos, u8 *end)
503 {
504 	u8 *pos, *rhdr, *hs_start, *hs_length;
505 	size_t rlen;
506 
507 	pos = *msgpos;
508 
509 	wpa_printf(MSG_DEBUG, "TLSv1: Send ServerHelloDone");
510 	rhdr = pos;
511 	pos += TLS_RECORD_HEADER_LEN;
512 
513 	/* opaque fragment[TLSPlaintext.length] */
514 
515 	/* Handshake */
516 	hs_start = pos;
517 	/* HandshakeType msg_type */
518 	*pos++ = TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE;
519 	/* uint24 length (to be filled) */
520 	hs_length = pos;
521 	pos += 3;
522 	/* body - ServerHelloDone (empty) */
523 
524 	WPA_PUT_BE24(hs_length, pos - hs_length - 3);
525 
526 	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
527 			      rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
528 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
529 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
530 				   TLS_ALERT_INTERNAL_ERROR);
531 		return -1;
532 	}
533 	pos = rhdr + rlen;
534 
535 	tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
536 
537 	*msgpos = pos;
538 
539 	return 0;
540 }
541 
542 
tls_write_server_change_cipher_spec(struct tlsv1_server * conn,u8 ** msgpos,u8 * end)543 static int tls_write_server_change_cipher_spec(struct tlsv1_server *conn,
544 					       u8 **msgpos, u8 *end)
545 {
546 	u8 *pos, *rhdr;
547 	size_t rlen;
548 
549 	pos = *msgpos;
550 
551 	wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec");
552 	rhdr = pos;
553 	pos += TLS_RECORD_HEADER_LEN;
554 	*pos = TLS_CHANGE_CIPHER_SPEC;
555 	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC,
556 			      rhdr, end - rhdr, 1, &rlen) < 0) {
557 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
558 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
559 				   TLS_ALERT_INTERNAL_ERROR);
560 		return -1;
561 	}
562 
563 	if (tlsv1_record_change_write_cipher(&conn->rl) < 0) {
564 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to set write cipher for "
565 			   "record layer");
566 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
567 				   TLS_ALERT_INTERNAL_ERROR);
568 		return -1;
569 	}
570 
571 	*msgpos = rhdr + rlen;
572 
573 	return 0;
574 }
575 
576 
tls_write_server_finished(struct tlsv1_server * conn,u8 ** msgpos,u8 * end)577 static int tls_write_server_finished(struct tlsv1_server *conn,
578 				     u8 **msgpos, u8 *end)
579 {
580 	u8 *pos, *rhdr, *hs_start, *hs_length;
581 	size_t rlen, hlen;
582 	u8 verify_data[TLS_VERIFY_DATA_LEN];
583 	u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
584 
585 	pos = *msgpos;
586 
587 	wpa_printf(MSG_DEBUG, "TLSv1: Send Finished");
588 
589 	/* Encrypted Handshake Message: Finished */
590 
591 	hlen = MD5_MAC_LEN;
592 	if (conn->verify.md5_server == NULL ||
593 	    crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) {
594 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
595 				   TLS_ALERT_INTERNAL_ERROR);
596 		conn->verify.md5_server = NULL;
597 		crypto_hash_finish(conn->verify.sha1_server, NULL, NULL);
598 		conn->verify.sha1_server = NULL;
599 		return -1;
600 	}
601 	conn->verify.md5_server = NULL;
602 	hlen = SHA1_MAC_LEN;
603 	if (conn->verify.sha1_server == NULL ||
604 	    crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN,
605 			       &hlen) < 0) {
606 		conn->verify.sha1_server = NULL;
607 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
608 				   TLS_ALERT_INTERNAL_ERROR);
609 		return -1;
610 	}
611 	conn->verify.sha1_server = NULL;
612 
613 	if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
614 		    "server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
615 		    verify_data, TLS_VERIFY_DATA_LEN)) {
616 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data");
617 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
618 				   TLS_ALERT_INTERNAL_ERROR);
619 		return -1;
620 	}
621 	wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
622 			verify_data, TLS_VERIFY_DATA_LEN);
623 
624 	rhdr = pos;
625 	pos += TLS_RECORD_HEADER_LEN;
626 	/* Handshake */
627 	hs_start = pos;
628 	/* HandshakeType msg_type */
629 	*pos++ = TLS_HANDSHAKE_TYPE_FINISHED;
630 	/* uint24 length (to be filled) */
631 	hs_length = pos;
632 	pos += 3;
633 	os_memcpy(pos, verify_data, TLS_VERIFY_DATA_LEN);
634 	pos += TLS_VERIFY_DATA_LEN;
635 	WPA_PUT_BE24(hs_length, pos - hs_length - 3);
636 	tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
637 
638 	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
639 			      rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
640 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
641 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
642 				   TLS_ALERT_INTERNAL_ERROR);
643 		return -1;
644 	}
645 
646 	pos = rhdr + rlen;
647 
648 	*msgpos = pos;
649 
650 	return 0;
651 }
652 
653 
tls_send_server_hello(struct tlsv1_server * conn,size_t * out_len)654 static u8 * tls_send_server_hello(struct tlsv1_server *conn, size_t *out_len)
655 {
656 	u8 *msg, *end, *pos;
657 	size_t msglen;
658 
659 	*out_len = 0;
660 
661 	msglen = 1000 + tls_server_cert_chain_der_len(conn);
662 
663 	msg = os_malloc(msglen);
664 	if (msg == NULL)
665 		return NULL;
666 
667 	pos = msg;
668 	end = msg + msglen;
669 
670 	if (tls_write_server_hello(conn, &pos, end) < 0) {
671 		os_free(msg);
672 		return NULL;
673 	}
674 
675 	if (conn->use_session_ticket) {
676 		/* Abbreviated handshake using session ticket; RFC 4507 */
677 		if (tls_write_server_change_cipher_spec(conn, &pos, end) < 0 ||
678 		    tls_write_server_finished(conn, &pos, end) < 0) {
679 			os_free(msg);
680 			return NULL;
681 		}
682 
683 		*out_len = pos - msg;
684 
685 		conn->state = CHANGE_CIPHER_SPEC;
686 
687 		return msg;
688 	}
689 
690 	/* Full handshake */
691 	if (tls_write_server_certificate(conn, &pos, end) < 0 ||
692 	    tls_write_server_key_exchange(conn, &pos, end) < 0 ||
693 	    tls_write_server_certificate_request(conn, &pos, end) < 0 ||
694 	    tls_write_server_hello_done(conn, &pos, end) < 0) {
695 		os_free(msg);
696 		return NULL;
697 	}
698 
699 	*out_len = pos - msg;
700 
701 	conn->state = CLIENT_CERTIFICATE;
702 
703 	return msg;
704 }
705 
706 
tls_send_change_cipher_spec(struct tlsv1_server * conn,size_t * out_len)707 static u8 * tls_send_change_cipher_spec(struct tlsv1_server *conn,
708 					size_t *out_len)
709 {
710 	u8 *msg, *end, *pos;
711 
712 	*out_len = 0;
713 
714 	msg = os_malloc(1000);
715 	if (msg == NULL)
716 		return NULL;
717 
718 	pos = msg;
719 	end = msg + 1000;
720 
721 	if (tls_write_server_change_cipher_spec(conn, &pos, end) < 0 ||
722 	    tls_write_server_finished(conn, &pos, end) < 0) {
723 		os_free(msg);
724 		return NULL;
725 	}
726 
727 	*out_len = pos - msg;
728 
729 	wpa_printf(MSG_DEBUG, "TLSv1: Handshake completed successfully");
730 	conn->state = ESTABLISHED;
731 
732 	return msg;
733 }
734 
735 
tlsv1_server_handshake_write(struct tlsv1_server * conn,size_t * out_len)736 u8 * tlsv1_server_handshake_write(struct tlsv1_server *conn, size_t *out_len)
737 {
738 	switch (conn->state) {
739 	case SERVER_HELLO:
740 		return tls_send_server_hello(conn, out_len);
741 	case SERVER_CHANGE_CIPHER_SPEC:
742 		return tls_send_change_cipher_spec(conn, out_len);
743 	default:
744 		if (conn->state == ESTABLISHED && conn->use_session_ticket) {
745 			/* Abbreviated handshake was already completed. */
746 			return NULL;
747 		}
748 		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d while "
749 			   "generating reply", conn->state);
750 		return NULL;
751 	}
752 }
753 
754 
tlsv1_server_send_alert(struct tlsv1_server * conn,u8 level,u8 description,size_t * out_len)755 u8 * tlsv1_server_send_alert(struct tlsv1_server *conn, u8 level,
756 			     u8 description, size_t *out_len)
757 {
758 	u8 *alert, *pos, *length;
759 
760 	wpa_printf(MSG_DEBUG, "TLSv1: Send Alert(%d:%d)", level, description);
761 	*out_len = 0;
762 
763 	alert = os_malloc(10);
764 	if (alert == NULL)
765 		return NULL;
766 
767 	pos = alert;
768 
769 	/* TLSPlaintext */
770 	/* ContentType type */
771 	*pos++ = TLS_CONTENT_TYPE_ALERT;
772 	/* ProtocolVersion version */
773 	WPA_PUT_BE16(pos, TLS_VERSION);
774 	pos += 2;
775 	/* uint16 length (to be filled) */
776 	length = pos;
777 	pos += 2;
778 	/* opaque fragment[TLSPlaintext.length] */
779 
780 	/* Alert */
781 	/* AlertLevel level */
782 	*pos++ = level;
783 	/* AlertDescription description */
784 	*pos++ = description;
785 
786 	WPA_PUT_BE16(length, pos - length - 2);
787 	*out_len = pos - alert;
788 
789 	return alert;
790 }
791