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