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