tlsv1_client.c revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
1/*
2 * TLS v1.0/v1.1/v1.2 client (RFC 2246, RFC 4346, RFC 5246)
3 * Copyright (c) 2006-2011, 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/sha1.h"
19#include "crypto/tls.h"
20#include "tlsv1_common.h"
21#include "tlsv1_record.h"
22#include "tlsv1_client.h"
23#include "tlsv1_client_i.h"
24
25/* TODO:
26 * Support for a message fragmented across several records (RFC 2246, 6.2.1)
27 */
28
29
30void tls_alert(struct tlsv1_client *conn, u8 level, u8 description)
31{
32	conn->alert_level = level;
33	conn->alert_description = description;
34}
35
36
37void tlsv1_client_free_dh(struct tlsv1_client *conn)
38{
39	os_free(conn->dh_p);
40	os_free(conn->dh_g);
41	os_free(conn->dh_ys);
42	conn->dh_p = conn->dh_g = conn->dh_ys = NULL;
43}
44
45
46int tls_derive_pre_master_secret(u8 *pre_master_secret)
47{
48	WPA_PUT_BE16(pre_master_secret, TLS_VERSION);
49	if (os_get_random(pre_master_secret + 2,
50			  TLS_PRE_MASTER_SECRET_LEN - 2))
51		return -1;
52	return 0;
53}
54
55
56int tls_derive_keys(struct tlsv1_client *conn,
57		    const u8 *pre_master_secret, size_t pre_master_secret_len)
58{
59	u8 seed[2 * TLS_RANDOM_LEN];
60	u8 key_block[TLS_MAX_KEY_BLOCK_LEN];
61	u8 *pos;
62	size_t key_block_len;
63
64	if (pre_master_secret) {
65		wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: pre_master_secret",
66				pre_master_secret, pre_master_secret_len);
67		os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
68		os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
69			  TLS_RANDOM_LEN);
70		if (tls_prf(conn->rl.tls_version,
71			    pre_master_secret, pre_master_secret_len,
72			    "master secret", seed, 2 * TLS_RANDOM_LEN,
73			    conn->master_secret, TLS_MASTER_SECRET_LEN)) {
74			wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive "
75				   "master_secret");
76			return -1;
77		}
78		wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: master_secret",
79				conn->master_secret, TLS_MASTER_SECRET_LEN);
80	}
81
82	os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
83	os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, TLS_RANDOM_LEN);
84	key_block_len = 2 * (conn->rl.hash_size + conn->rl.key_material_len);
85	if (conn->rl.tls_version == TLS_VERSION_1)
86		key_block_len += 2 * conn->rl.iv_size;
87	if (tls_prf(conn->rl.tls_version,
88		    conn->master_secret, TLS_MASTER_SECRET_LEN,
89		    "key expansion", seed, 2 * TLS_RANDOM_LEN,
90		    key_block, key_block_len)) {
91		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive key_block");
92		return -1;
93	}
94	wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: key_block",
95			key_block, key_block_len);
96
97	pos = key_block;
98
99	/* client_write_MAC_secret */
100	os_memcpy(conn->rl.write_mac_secret, pos, conn->rl.hash_size);
101	pos += conn->rl.hash_size;
102	/* server_write_MAC_secret */
103	os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size);
104	pos += conn->rl.hash_size;
105
106	/* client_write_key */
107	os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len);
108	pos += conn->rl.key_material_len;
109	/* server_write_key */
110	os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len);
111	pos += conn->rl.key_material_len;
112
113	if (conn->rl.tls_version == TLS_VERSION_1) {
114		/* client_write_IV */
115		os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size);
116		pos += conn->rl.iv_size;
117		/* server_write_IV */
118		os_memcpy(conn->rl.read_iv, pos, conn->rl.iv_size);
119		pos += conn->rl.iv_size;
120	} else {
121		/*
122		 * Use IV field to set the mask value for TLS v1.1. A fixed
123		 * mask of zero is used per the RFC 4346, 6.2.3.2 CBC Block
124		 * Cipher option 2a.
125		 */
126		os_memset(conn->rl.write_iv, 0, conn->rl.iv_size);
127	}
128
129	return 0;
130}
131
132
133/**
134 * tlsv1_client_handshake - Process TLS handshake
135 * @conn: TLSv1 client connection data from tlsv1_client_init()
136 * @in_data: Input data from TLS peer
137 * @in_len: Input data length
138 * @out_len: Length of the output buffer.
139 * @appl_data: Pointer to application data pointer, or %NULL if dropped
140 * @appl_data_len: Pointer to variable that is set to appl_data length
141 * @need_more_data: Set to 1 if more data would be needed to complete
142 *	processing
143 * Returns: Pointer to output data, %NULL on failure
144 */
145u8 * tlsv1_client_handshake(struct tlsv1_client *conn,
146			    const u8 *in_data, size_t in_len,
147			    size_t *out_len, u8 **appl_data,
148			    size_t *appl_data_len, int *need_more_data)
149{
150	const u8 *pos, *end;
151	u8 *msg = NULL, *in_msg = NULL, *in_pos, *in_end, alert, ct;
152	size_t in_msg_len;
153	int no_appl_data;
154	int used;
155
156	if (need_more_data)
157		*need_more_data = 0;
158
159	if (conn->state == CLIENT_HELLO) {
160		if (in_len)
161			return NULL;
162		return tls_send_client_hello(conn, out_len);
163	}
164
165	if (conn->partial_input) {
166		if (wpabuf_resize(&conn->partial_input, in_len) < 0) {
167			wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate "
168				   "memory for pending record");
169			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
170				  TLS_ALERT_INTERNAL_ERROR);
171			goto failed;
172		}
173		wpabuf_put_data(conn->partial_input, in_data, in_len);
174		in_data = wpabuf_head(conn->partial_input);
175		in_len = wpabuf_len(conn->partial_input);
176	}
177
178	if (in_data == NULL || in_len == 0)
179		return NULL;
180
181	pos = in_data;
182	end = in_data + in_len;
183	in_msg = os_malloc(in_len);
184	if (in_msg == NULL)
185		return NULL;
186
187	/* Each received packet may include multiple records */
188	while (pos < end) {
189		in_msg_len = in_len;
190		used = tlsv1_record_receive(&conn->rl, pos, end - pos,
191					    in_msg, &in_msg_len, &alert);
192		if (used < 0) {
193			wpa_printf(MSG_DEBUG, "TLSv1: Processing received "
194				   "record failed");
195			tls_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
196			goto failed;
197		}
198		if (used == 0) {
199			struct wpabuf *partial;
200			wpa_printf(MSG_DEBUG, "TLSv1: Need more data");
201			partial = wpabuf_alloc_copy(pos, end - pos);
202			wpabuf_free(conn->partial_input);
203			conn->partial_input = partial;
204			if (conn->partial_input == NULL) {
205				wpa_printf(MSG_DEBUG, "TLSv1: Failed to "
206					   "allocate memory for pending "
207					   "record");
208				tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
209					  TLS_ALERT_INTERNAL_ERROR);
210				goto failed;
211			}
212			os_free(in_msg);
213			if (need_more_data)
214				*need_more_data = 1;
215			return NULL;
216		}
217		ct = pos[0];
218
219		in_pos = in_msg;
220		in_end = in_msg + in_msg_len;
221
222		/* Each received record may include multiple messages of the
223		 * same ContentType. */
224		while (in_pos < in_end) {
225			in_msg_len = in_end - in_pos;
226			if (tlsv1_client_process_handshake(conn, ct, in_pos,
227							   &in_msg_len,
228							   appl_data,
229							   appl_data_len) < 0)
230				goto failed;
231			in_pos += in_msg_len;
232		}
233
234		pos += used;
235	}
236
237	os_free(in_msg);
238	in_msg = NULL;
239
240	no_appl_data = appl_data == NULL || *appl_data == NULL;
241	msg = tlsv1_client_handshake_write(conn, out_len, no_appl_data);
242
243failed:
244	os_free(in_msg);
245	if (conn->alert_level) {
246		wpabuf_free(conn->partial_input);
247		conn->partial_input = NULL;
248		conn->state = FAILED;
249		os_free(msg);
250		msg = tlsv1_client_send_alert(conn, conn->alert_level,
251					      conn->alert_description,
252					      out_len);
253	} else if (msg == NULL) {
254		msg = os_zalloc(1);
255		*out_len = 0;
256	}
257
258	if (need_more_data == NULL || !(*need_more_data)) {
259		wpabuf_free(conn->partial_input);
260		conn->partial_input = NULL;
261	}
262
263	return msg;
264}
265
266
267/**
268 * tlsv1_client_encrypt - Encrypt data into TLS tunnel
269 * @conn: TLSv1 client connection data from tlsv1_client_init()
270 * @in_data: Pointer to plaintext data to be encrypted
271 * @in_len: Input buffer length
272 * @out_data: Pointer to output buffer (encrypted TLS data)
273 * @out_len: Maximum out_data length
274 * Returns: Number of bytes written to out_data, -1 on failure
275 *
276 * This function is used after TLS handshake has been completed successfully to
277 * send data in the encrypted tunnel.
278 */
279int tlsv1_client_encrypt(struct tlsv1_client *conn,
280			 const u8 *in_data, size_t in_len,
281			 u8 *out_data, size_t out_len)
282{
283	size_t rlen;
284
285	wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
286			in_data, in_len);
287
288	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
289			      out_data, out_len, in_data, in_len, &rlen) < 0) {
290		wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
291		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
292			  TLS_ALERT_INTERNAL_ERROR);
293		return -1;
294	}
295
296	return rlen;
297}
298
299
300/**
301 * tlsv1_client_decrypt - Decrypt data from TLS tunnel
302 * @conn: TLSv1 client connection data from tlsv1_client_init()
303 * @in_data: Pointer to input buffer (encrypted TLS data)
304 * @in_len: Input buffer length
305 * @need_more_data: Set to 1 if more data would be needed to complete
306 *	processing
307 * Returns: Decrypted data or %NULL on failure
308 *
309 * This function is used after TLS handshake has been completed successfully to
310 * receive data from the encrypted tunnel.
311 */
312struct wpabuf * tlsv1_client_decrypt(struct tlsv1_client *conn,
313				     const u8 *in_data, size_t in_len,
314				     int *need_more_data)
315{
316	const u8 *in_end, *pos;
317	int used;
318	u8 alert, *out_pos, ct;
319	size_t olen;
320	struct wpabuf *buf = NULL;
321
322	if (need_more_data)
323		*need_more_data = 0;
324
325	if (conn->partial_input) {
326		if (wpabuf_resize(&conn->partial_input, in_len) < 0) {
327			wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate "
328				   "memory for pending record");
329			alert = TLS_ALERT_INTERNAL_ERROR;
330			goto fail;
331		}
332		wpabuf_put_data(conn->partial_input, in_data, in_len);
333		in_data = wpabuf_head(conn->partial_input);
334		in_len = wpabuf_len(conn->partial_input);
335	}
336
337	pos = in_data;
338	in_end = in_data + in_len;
339
340	while (pos < in_end) {
341		ct = pos[0];
342		if (wpabuf_resize(&buf, in_end - pos) < 0) {
343			alert = TLS_ALERT_INTERNAL_ERROR;
344			goto fail;
345		}
346		out_pos = wpabuf_put(buf, 0);
347		olen = wpabuf_tailroom(buf);
348		used = tlsv1_record_receive(&conn->rl, pos, in_end - pos,
349					    out_pos, &olen, &alert);
350		if (used < 0) {
351			wpa_printf(MSG_DEBUG, "TLSv1: Record layer processing "
352				   "failed");
353			goto fail;
354		}
355		if (used == 0) {
356			struct wpabuf *partial;
357			wpa_printf(MSG_DEBUG, "TLSv1: Need more data");
358			partial = wpabuf_alloc_copy(pos, in_end - pos);
359			wpabuf_free(conn->partial_input);
360			conn->partial_input = partial;
361			if (conn->partial_input == NULL) {
362				wpa_printf(MSG_DEBUG, "TLSv1: Failed to "
363					   "allocate memory for pending "
364					   "record");
365				alert = TLS_ALERT_INTERNAL_ERROR;
366				goto fail;
367			}
368			if (need_more_data)
369				*need_more_data = 1;
370			return buf;
371		}
372
373		if (ct == TLS_CONTENT_TYPE_ALERT) {
374			if (olen < 2) {
375				wpa_printf(MSG_DEBUG, "TLSv1: Alert "
376					   "underflow");
377				alert = TLS_ALERT_DECODE_ERROR;
378				goto fail;
379			}
380			wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",
381				   out_pos[0], out_pos[1]);
382			if (out_pos[0] == TLS_ALERT_LEVEL_WARNING) {
383				/* Continue processing */
384				pos += used;
385				continue;
386			}
387
388			alert = out_pos[1];
389			goto fail;
390		}
391
392		if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
393			wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type "
394				   "0x%x when decrypting application data",
395				   pos[0]);
396			alert = TLS_ALERT_UNEXPECTED_MESSAGE;
397			goto fail;
398		}
399
400		wpabuf_put(buf, olen);
401
402		pos += used;
403	}
404
405	wpabuf_free(conn->partial_input);
406	conn->partial_input = NULL;
407	return buf;
408
409fail:
410	wpabuf_free(buf);
411	wpabuf_free(conn->partial_input);
412	conn->partial_input = NULL;
413	tls_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
414	return NULL;
415}
416
417
418/**
419 * tlsv1_client_global_init - Initialize TLSv1 client
420 * Returns: 0 on success, -1 on failure
421 *
422 * This function must be called before using any other TLSv1 client functions.
423 */
424int tlsv1_client_global_init(void)
425{
426	return crypto_global_init();
427}
428
429
430/**
431 * tlsv1_client_global_deinit - Deinitialize TLSv1 client
432 *
433 * This function can be used to deinitialize the TLSv1 client that was
434 * initialized by calling tlsv1_client_global_init(). No TLSv1 client functions
435 * can be called after this before calling tlsv1_client_global_init() again.
436 */
437void tlsv1_client_global_deinit(void)
438{
439	crypto_global_deinit();
440}
441
442
443/**
444 * tlsv1_client_init - Initialize TLSv1 client connection
445 * Returns: Pointer to TLSv1 client connection data or %NULL on failure
446 */
447struct tlsv1_client * tlsv1_client_init(void)
448{
449	struct tlsv1_client *conn;
450	size_t count;
451	u16 *suites;
452
453	conn = os_zalloc(sizeof(*conn));
454	if (conn == NULL)
455		return NULL;
456
457	conn->state = CLIENT_HELLO;
458
459	if (tls_verify_hash_init(&conn->verify) < 0) {
460		wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize verify "
461			   "hash");
462		os_free(conn);
463		return NULL;
464	}
465
466	count = 0;
467	suites = conn->cipher_suites;
468#ifndef CONFIG_CRYPTO_INTERNAL
469	suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
470	suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
471#endif /* CONFIG_CRYPTO_INTERNAL */
472	suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
473	suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
474	suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
475	suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
476	suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
477	conn->num_cipher_suites = count;
478
479	conn->rl.tls_version = TLS_VERSION;
480
481	return conn;
482}
483
484
485/**
486 * tlsv1_client_deinit - Deinitialize TLSv1 client connection
487 * @conn: TLSv1 client connection data from tlsv1_client_init()
488 */
489void tlsv1_client_deinit(struct tlsv1_client *conn)
490{
491	crypto_public_key_free(conn->server_rsa_key);
492	tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL);
493	tlsv1_record_change_write_cipher(&conn->rl);
494	tlsv1_record_change_read_cipher(&conn->rl);
495	tls_verify_hash_free(&conn->verify);
496	os_free(conn->client_hello_ext);
497	tlsv1_client_free_dh(conn);
498	tlsv1_cred_free(conn->cred);
499	wpabuf_free(conn->partial_input);
500	os_free(conn);
501}
502
503
504/**
505 * tlsv1_client_established - Check whether connection has been established
506 * @conn: TLSv1 client connection data from tlsv1_client_init()
507 * Returns: 1 if connection is established, 0 if not
508 */
509int tlsv1_client_established(struct tlsv1_client *conn)
510{
511	return conn->state == ESTABLISHED;
512}
513
514
515/**
516 * tlsv1_client_prf - Use TLS-PRF to derive keying material
517 * @conn: TLSv1 client connection data from tlsv1_client_init()
518 * @label: Label (e.g., description of the key) for PRF
519 * @server_random_first: seed is 0 = client_random|server_random,
520 * 1 = server_random|client_random
521 * @out: Buffer for output data from TLS-PRF
522 * @out_len: Length of the output buffer
523 * Returns: 0 on success, -1 on failure
524 */
525int tlsv1_client_prf(struct tlsv1_client *conn, const char *label,
526		     int server_random_first, u8 *out, size_t out_len)
527{
528	u8 seed[2 * TLS_RANDOM_LEN];
529
530	if (conn->state != ESTABLISHED)
531		return -1;
532
533	if (server_random_first) {
534		os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
535		os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random,
536			  TLS_RANDOM_LEN);
537	} else {
538		os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
539		os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
540			  TLS_RANDOM_LEN);
541	}
542
543	return tls_prf(conn->rl.tls_version,
544		       conn->master_secret, TLS_MASTER_SECRET_LEN,
545		       label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
546}
547
548
549/**
550 * tlsv1_client_get_cipher - Get current cipher name
551 * @conn: TLSv1 client connection data from tlsv1_client_init()
552 * @buf: Buffer for the cipher name
553 * @buflen: buf size
554 * Returns: 0 on success, -1 on failure
555 *
556 * Get the name of the currently used cipher.
557 */
558int tlsv1_client_get_cipher(struct tlsv1_client *conn, char *buf,
559			    size_t buflen)
560{
561	char *cipher;
562
563	switch (conn->rl.cipher_suite) {
564	case TLS_RSA_WITH_RC4_128_MD5:
565		cipher = "RC4-MD5";
566		break;
567	case TLS_RSA_WITH_RC4_128_SHA:
568		cipher = "RC4-SHA";
569		break;
570	case TLS_RSA_WITH_DES_CBC_SHA:
571		cipher = "DES-CBC-SHA";
572		break;
573	case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
574		cipher = "DES-CBC3-SHA";
575		break;
576	case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
577		cipher = "ADH-AES-128-SHA256";
578		break;
579	case TLS_DH_anon_WITH_AES_128_CBC_SHA:
580		cipher = "ADH-AES-128-SHA";
581		break;
582	case TLS_RSA_WITH_AES_256_CBC_SHA:
583		cipher = "AES-256-SHA";
584		break;
585	case TLS_RSA_WITH_AES_256_CBC_SHA256:
586		cipher = "AES-256-SHA256";
587		break;
588	case TLS_RSA_WITH_AES_128_CBC_SHA:
589		cipher = "AES-128-SHA";
590		break;
591	case TLS_RSA_WITH_AES_128_CBC_SHA256:
592		cipher = "AES-128-SHA256";
593		break;
594	default:
595		return -1;
596	}
597
598	if (os_strlcpy(buf, cipher, buflen) >= buflen)
599		return -1;
600	return 0;
601}
602
603
604/**
605 * tlsv1_client_shutdown - Shutdown TLS connection
606 * @conn: TLSv1 client connection data from tlsv1_client_init()
607 * Returns: 0 on success, -1 on failure
608 */
609int tlsv1_client_shutdown(struct tlsv1_client *conn)
610{
611	conn->state = CLIENT_HELLO;
612
613	if (tls_verify_hash_init(&conn->verify) < 0) {
614		wpa_printf(MSG_DEBUG, "TLSv1: Failed to re-initialize verify "
615			   "hash");
616		return -1;
617	}
618
619	tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL);
620	tlsv1_record_change_write_cipher(&conn->rl);
621	tlsv1_record_change_read_cipher(&conn->rl);
622
623	conn->certificate_requested = 0;
624	crypto_public_key_free(conn->server_rsa_key);
625	conn->server_rsa_key = NULL;
626	conn->session_resumed = 0;
627
628	return 0;
629}
630
631
632/**
633 * tlsv1_client_resumed - Was session resumption used
634 * @conn: TLSv1 client connection data from tlsv1_client_init()
635 * Returns: 1 if current session used session resumption, 0 if not
636 */
637int tlsv1_client_resumed(struct tlsv1_client *conn)
638{
639	return !!conn->session_resumed;
640}
641
642
643/**
644 * tlsv1_client_hello_ext - Set TLS extension for ClientHello
645 * @conn: TLSv1 client connection data from tlsv1_client_init()
646 * @ext_type: Extension type
647 * @data: Extension payload (%NULL to remove extension)
648 * @data_len: Extension payload length
649 * Returns: 0 on success, -1 on failure
650 */
651int tlsv1_client_hello_ext(struct tlsv1_client *conn, int ext_type,
652			   const u8 *data, size_t data_len)
653{
654	u8 *pos;
655
656	conn->session_ticket_included = 0;
657	os_free(conn->client_hello_ext);
658	conn->client_hello_ext = NULL;
659	conn->client_hello_ext_len = 0;
660
661	if (data == NULL || data_len == 0)
662		return 0;
663
664	pos = conn->client_hello_ext = os_malloc(6 + data_len);
665	if (pos == NULL)
666		return -1;
667
668	WPA_PUT_BE16(pos, 4 + data_len);
669	pos += 2;
670	WPA_PUT_BE16(pos, ext_type);
671	pos += 2;
672	WPA_PUT_BE16(pos, data_len);
673	pos += 2;
674	os_memcpy(pos, data, data_len);
675	conn->client_hello_ext_len = 6 + data_len;
676
677	if (ext_type == TLS_EXT_PAC_OPAQUE) {
678		conn->session_ticket_included = 1;
679		wpa_printf(MSG_DEBUG, "TLSv1: Using session ticket");
680	}
681
682	return 0;
683}
684
685
686/**
687 * tlsv1_client_get_keys - Get master key and random data from TLS connection
688 * @conn: TLSv1 client connection data from tlsv1_client_init()
689 * @keys: Structure of key/random data (filled on success)
690 * Returns: 0 on success, -1 on failure
691 */
692int tlsv1_client_get_keys(struct tlsv1_client *conn, struct tls_keys *keys)
693{
694	os_memset(keys, 0, sizeof(*keys));
695	if (conn->state == CLIENT_HELLO)
696		return -1;
697
698	keys->client_random = conn->client_random;
699	keys->client_random_len = TLS_RANDOM_LEN;
700
701	if (conn->state != SERVER_HELLO) {
702		keys->server_random = conn->server_random;
703		keys->server_random_len = TLS_RANDOM_LEN;
704		keys->master_key = conn->master_secret;
705		keys->master_key_len = TLS_MASTER_SECRET_LEN;
706	}
707
708	return 0;
709}
710
711
712/**
713 * tlsv1_client_get_keyblock_size - Get TLS key_block size
714 * @conn: TLSv1 client connection data from tlsv1_client_init()
715 * Returns: Size of the key_block for the negotiated cipher suite or -1 on
716 * failure
717 */
718int tlsv1_client_get_keyblock_size(struct tlsv1_client *conn)
719{
720	if (conn->state == CLIENT_HELLO || conn->state == SERVER_HELLO)
721		return -1;
722
723	return 2 * (conn->rl.hash_size + conn->rl.key_material_len +
724		    conn->rl.iv_size);
725}
726
727
728/**
729 * tlsv1_client_set_cipher_list - Configure acceptable cipher suites
730 * @conn: TLSv1 client connection data from tlsv1_client_init()
731 * @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers
732 * (TLS_CIPHER_*).
733 * Returns: 0 on success, -1 on failure
734 */
735int tlsv1_client_set_cipher_list(struct tlsv1_client *conn, u8 *ciphers)
736{
737	size_t count;
738	u16 *suites;
739
740	/* TODO: implement proper configuration of cipher suites */
741	if (ciphers[0] == TLS_CIPHER_ANON_DH_AES128_SHA) {
742		count = 0;
743		suites = conn->cipher_suites;
744#ifndef CONFIG_CRYPTO_INTERNAL
745		suites[count++] = TLS_DH_anon_WITH_AES_256_CBC_SHA256;
746		suites[count++] = TLS_DH_anon_WITH_AES_256_CBC_SHA;
747#endif /* CONFIG_CRYPTO_INTERNAL */
748		suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA256;
749		suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
750		suites[count++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
751		suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5;
752		suites[count++] = TLS_DH_anon_WITH_DES_CBC_SHA;
753
754		/*
755		 * Cisco AP (at least 350 and 1200 series) local authentication
756		 * server does not know how to search cipher suites from the
757		 * list and seem to require that the last entry in the list is
758		 * the one that it wants to use. However, TLS specification
759		 * requires the list to be in the client preference order. As a
760		 * workaround, add anon-DH AES-128-SHA1 again at the end of the
761		 * list to allow the Cisco code to find it.
762		 */
763		suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
764		conn->num_cipher_suites = count;
765	}
766
767	return 0;
768}
769
770
771/**
772 * tlsv1_client_set_cred - Set client credentials
773 * @conn: TLSv1 client connection data from tlsv1_client_init()
774 * @cred: Credentials from tlsv1_cred_alloc()
775 * Returns: 0 on success, -1 on failure
776 *
777 * On success, the client takes ownership of the credentials block and caller
778 * must not free it. On failure, caller is responsible for freeing the
779 * credential block.
780 */
781int tlsv1_client_set_cred(struct tlsv1_client *conn,
782			  struct tlsv1_credentials *cred)
783{
784	tlsv1_cred_free(conn->cred);
785	conn->cred = cred;
786	return 0;
787}
788
789
790void tlsv1_client_set_time_checks(struct tlsv1_client *conn, int enabled)
791{
792	conn->disable_time_checks = !enabled;
793}
794
795
796void tlsv1_client_set_session_ticket_cb(struct tlsv1_client *conn,
797					tlsv1_client_session_ticket_cb cb,
798					void *ctx)
799{
800	wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback set %p (ctx %p)",
801		   cb, ctx);
802	conn->session_ticket_cb = cb;
803	conn->session_ticket_cb_ctx = ctx;
804}
805