tlsv1_server.c revision c5ec7f57ead87efa365800228aa0b09a12d9e6c4
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TLS v1.0/v1.1/v1.2 server (RFC 2246, RFC 4346, RFC 5246)
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This software may be distributed under the terms of the BSD license.
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * See README for more details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "includes.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "common.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "crypto/sha1.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "crypto/tls.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tlsv1_common.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tlsv1_record.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tlsv1_server.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tlsv1_server_i.h"
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* TODO:
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Support for a message fragmented across several records (RFC 2246, 6.2.1)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void tlsv1_server_alert(struct tlsv1_server *conn, u8 level, u8 description)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->alert_level = level;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->alert_description = description;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int tlsv1_server_derive_keys(struct tlsv1_server *conn,
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			     const u8 *pre_master_secret,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     size_t pre_master_secret_len)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u8 seed[2 * TLS_RANDOM_LEN];
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u8 key_block[TLS_MAX_KEY_BLOCK_LEN];
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u8 *pos;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size_t key_block_len;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (pre_master_secret) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: pre_master_secret",
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				pre_master_secret, pre_master_secret_len);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  TLS_RANDOM_LEN);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (tls_prf(conn->rl.tls_version,
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			    pre_master_secret, pre_master_secret_len,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    "master secret", seed, 2 * TLS_RANDOM_LEN,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    conn->master_secret, TLS_MASTER_SECRET_LEN)) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive "
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   "master_secret");
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return -1;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: master_secret",
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				conn->master_secret, TLS_MASTER_SECRET_LEN);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch	os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, TLS_RANDOM_LEN);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	key_block_len = 2 * (conn->rl.hash_size + conn->rl.key_material_len +
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     conn->rl.iv_size);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tls_prf(conn->rl.tls_version,
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		    conn->master_secret, TLS_MASTER_SECRET_LEN,
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		    "key expansion", seed, 2 * TLS_RANDOM_LEN,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    key_block, key_block_len)) {
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive key_block");
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return -1;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: key_block",
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			key_block, key_block_len);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos = key_block;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* client_write_MAC_secret */
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos += conn->rl.hash_size;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* server_write_MAC_secret */
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_memcpy(conn->rl.write_mac_secret, pos, conn->rl.hash_size);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos += conn->rl.hash_size;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* client_write_key */
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos += conn->rl.key_material_len;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* server_write_key */
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos += conn->rl.key_material_len;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* client_write_IV */
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_memcpy(conn->rl.read_iv, pos, conn->rl.iv_size);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos += conn->rl.iv_size;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* server_write_IV */
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos += conn->rl.iv_size;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_handshake - Process TLS handshake
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @in_data: Input data from TLS peer
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @in_len: Input data length
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @out_len: Length of the output buffer.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: Pointer to output data, %NULL on failure
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)u8 * tlsv1_server_handshake(struct tlsv1_server *conn,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    const u8 *in_data, size_t in_len,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    size_t *out_len)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const u8 *pos, *end;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u8 *msg = NULL, *in_msg, *in_pos, *in_end, alert, ct;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size_t in_msg_len;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int used;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (in_data == NULL || in_len == 0) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		wpa_printf(MSG_DEBUG, "TLSv1: No input data to server");
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return NULL;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos = in_data;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	end = in_data + in_len;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	in_msg = os_malloc(in_len);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (in_msg == NULL)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return NULL;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Each received packet may include multiple records */
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (pos < end) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		in_msg_len = in_len;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		used = tlsv1_record_receive(&conn->rl, pos, end - pos,
131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch					    in_msg, &in_msg_len, &alert);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (used < 0) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wpa_printf(MSG_DEBUG, "TLSv1: Processing received "
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   "record failed");
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto failed;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (used == 0) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/* need more data */
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   "yet supported");
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto failed;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ct = pos[0];
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		in_pos = in_msg;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		in_end = in_msg + in_msg_len;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Each received record may include multiple messages of the
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * same ContentType. */
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		while (in_pos < in_end) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			in_msg_len = in_end - in_pos;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (tlsv1_server_process_handshake(conn, ct, in_pos,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)							   &in_msg_len) < 0)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				goto failed;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			in_pos += in_msg_len;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pos += used;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_free(in_msg);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	in_msg = NULL;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	msg = tlsv1_server_handshake_write(conn, out_len);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)failed:
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_free(in_msg);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (conn->alert_level) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (conn->state == FAILED) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/* Avoid alert loops */
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wpa_printf(MSG_DEBUG, "TLSv1: Drop alert loop");
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			os_free(msg);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return NULL;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		conn->state = FAILED;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		os_free(msg);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		msg = tlsv1_server_send_alert(conn, conn->alert_level,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					      conn->alert_description,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					      out_len);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return msg;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_encrypt - Encrypt data into TLS tunnel
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @in_data: Pointer to plaintext data to be encrypted
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @in_len: Input buffer length
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @out_data: Pointer to output buffer (encrypted TLS data)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @out_len: Maximum out_data length
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: Number of bytes written to out_data, -1 on failure
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function is used after TLS handshake has been completed successfully to
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * send data in the encrypted tunnel.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int tlsv1_server_encrypt(struct tlsv1_server *conn,
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 const u8 *in_data, size_t in_len,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 u8 *out_data, size_t out_len)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size_t rlen;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			in_data, in_len);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			      out_data, out_len, in_data, in_len, &rlen) < 0) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   TLS_ALERT_INTERNAL_ERROR);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return -1;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rlen;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * tlsv1_server_decrypt - Decrypt data from TLS tunnel
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @in_data: Pointer to input buffer (encrypted TLS data)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @in_len: Input buffer length
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @out_data: Pointer to output buffer (decrypted data from TLS tunnel)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @out_len: Maximum out_data length
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: Number of bytes written to out_data, -1 on failure
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function is used after TLS handshake has been completed successfully to
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * receive data from the encrypted tunnel.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int tlsv1_server_decrypt(struct tlsv1_server *conn,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 const u8 *in_data, size_t in_len,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 u8 *out_data, size_t out_len)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const u8 *in_end, *pos;
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	int used;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u8 alert, *out_end, *out_pos, ct;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size_t olen;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos = in_data;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	in_end = in_data + in_len;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	out_pos = out_data;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	out_end = out_data + out_len;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (pos < in_end) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ct = pos[0];
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		olen = out_end - out_pos;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		used = tlsv1_record_receive(&conn->rl, pos, in_end - pos,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    out_pos, &olen, &alert);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (used < 0) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wpa_printf(MSG_DEBUG, "TLSv1: Record layer processing "
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   "failed");
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return -1;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (used == 0) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/* need more data */
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   "yet supported");
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return -1;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (ct == TLS_CONTENT_TYPE_ALERT) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (olen < 2) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				wpa_printf(MSG_DEBUG, "TLSv1: Alert "
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   "underflow");
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)						   TLS_ALERT_DECODE_ERROR);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				return -1;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   out_pos[0], out_pos[1]);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (out_pos[0] == TLS_ALERT_LEVEL_WARNING) {
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch				/* Continue processing */
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				pos += used;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				continue;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   out_pos[1]);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return -1;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type "
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   "0x%x", pos[0]);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch					   TLS_ALERT_UNEXPECTED_MESSAGE);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return -1;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		out_pos += olen;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (out_pos > out_end) {
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			wpa_printf(MSG_DEBUG, "TLSv1: Buffer not large enough "
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   "for processing the received record");
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   TLS_ALERT_INTERNAL_ERROR);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return -1;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pos += used;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	return out_pos - out_data;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * tlsv1_server_global_init - Initialize TLSv1 server
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Returns: 0 on success, -1 on failure
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This function must be called before using any other TLSv1 server functions.
31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) */
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int tlsv1_server_global_init(void)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return crypto_global_init();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_global_deinit - Deinitialize TLSv1 server
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function can be used to deinitialize the TLSv1 server that was
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * initialized by calling tlsv1_server_global_init(). No TLSv1 server functions
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * can be called after this before calling tlsv1_server_global_init() again.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void tlsv1_server_global_deinit(void)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	crypto_global_deinit();
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_init - Initialize TLSv1 server connection
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cred: Pointer to server credentials from tlsv1_server_cred_alloc()
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: Pointer to TLSv1 server connection data or %NULL on failure
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct tlsv1_server * tlsv1_server_init(struct tlsv1_credentials *cred)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct tlsv1_server *conn;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size_t count;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u16 *suites;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	conn = os_zalloc(sizeof(*conn));
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (conn == NULL)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return NULL;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->cred = cred;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->state = CLIENT_HELLO;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tls_verify_hash_init(&conn->verify) < 0) {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize verify "
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   "hash");
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		os_free(conn);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return NULL;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	count = 0;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	suites = conn->cipher_suites;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONFIG_CRYPTO_INTERNAL
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* CONFIG_CRYPTO_INTERNAL */
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->num_cipher_suites = count;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return conn;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void tlsv1_server_clear_data(struct tlsv1_server *conn)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tlsv1_record_change_write_cipher(&conn->rl);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tlsv1_record_change_read_cipher(&conn->rl);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tls_verify_hash_free(&conn->verify);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	crypto_public_key_free(conn->client_rsa_key);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->client_rsa_key = NULL;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_free(conn->session_ticket);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->session_ticket = NULL;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->session_ticket_len = 0;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->use_session_ticket = 0;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_free(conn->dh_secret);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->dh_secret = NULL;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->dh_secret_len = 0;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_deinit - Deinitialize TLSv1 server connection
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void tlsv1_server_deinit(struct tlsv1_server *conn)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tlsv1_server_clear_data(conn);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_free(conn);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_established - Check whether connection has been established
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 1 if connection is established, 0 if not
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int tlsv1_server_established(struct tlsv1_server *conn)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return conn->state == ESTABLISHED;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_prf - Use TLS-PRF to derive keying material
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @label: Label (e.g., description of the key) for PRF
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @server_random_first: seed is 0 = client_random|server_random,
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1 = server_random|client_random
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @out: Buffer for output data from TLS-PRF
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @out_len: Length of the output buffer
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 on success, -1 on failure
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int tlsv1_server_prf(struct tlsv1_server *conn, const char *label,
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     int server_random_first, u8 *out, size_t out_len)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u8 seed[2 * TLS_RANDOM_LEN];
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (conn->state != ESTABLISHED)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return -1;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (server_random_first) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  TLS_RANDOM_LEN);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  TLS_RANDOM_LEN);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return tls_prf(conn->rl.tls_version,
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       conn->master_secret, TLS_MASTER_SECRET_LEN,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_get_cipher - Get current cipher name
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @buf: Buffer for the cipher name
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @buflen: buf size
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 on success, -1 on failure
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the name of the currently used cipher.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int tlsv1_server_get_cipher(struct tlsv1_server *conn, char *buf,
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    size_t buflen)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char *cipher;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (conn->rl.cipher_suite) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case TLS_RSA_WITH_RC4_128_MD5:
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		cipher = "RC4-MD5";
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		break;
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	case TLS_RSA_WITH_RC4_128_SHA:
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		cipher = "RC4-SHA";
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		break;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case TLS_RSA_WITH_DES_CBC_SHA:
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		cipher = "DES-CBC-SHA";
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		break;
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		cipher = "DES-CBC3-SHA";
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case TLS_DH_anon_WITH_AES_128_CBC_SHA:
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		cipher = "ADH-AES-128-SHA";
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case TLS_RSA_WITH_AES_256_CBC_SHA:
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		cipher = "AES-256-SHA";
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case TLS_RSA_WITH_AES_128_CBC_SHA:
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		cipher = "AES-128-SHA";
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return -1;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (os_strlcpy(buf, cipher, buflen) >= buflen)
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		return -1;
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	return 0;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_shutdown - Shutdown TLS connection
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 on success, -1 on failure
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int tlsv1_server_shutdown(struct tlsv1_server *conn)
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	conn->state = CLIENT_HELLO;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)	if (tls_verify_hash_init(&conn->verify) < 0) {
51058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)		wpa_printf(MSG_DEBUG, "TLSv1: Failed to re-initialize verify "
51158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)			   "hash");
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		return -1;
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	}
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	tlsv1_server_clear_data(conn);
51658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
51758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)	return 0;
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_resumed - Was session resumption used
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Returns: 1 if current session used session resumption, 0 if not
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int tlsv1_server_resumed(struct tlsv1_server *conn)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	return 0;
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * tlsv1_server_get_keys - Get master key and random data from TLS connection
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @keys: Structure of key/random data (filled on success)
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Returns: 0 on success, -1 on failure
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int tlsv1_server_get_keys(struct tlsv1_server *conn, struct tls_keys *keys)
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	os_memset(keys, 0, sizeof(*keys));
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if (conn->state == CLIENT_HELLO)
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		return -1;
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	keys->client_random = conn->client_random;
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	keys->client_random_len = TLS_RANDOM_LEN;
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if (conn->state != SERVER_HELLO) {
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		keys->server_random = conn->server_random;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		keys->server_random_len = TLS_RANDOM_LEN;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		keys->master_key = conn->master_secret;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		keys->master_key_len = TLS_MASTER_SECRET_LEN;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_get_keyblock_size - Get TLS key_block size
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: Size of the key_block for the negotiated cipher suite or -1 on
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * failure
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int tlsv1_server_get_keyblock_size(struct tlsv1_server *conn)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (conn->state == CLIENT_HELLO || conn->state == SERVER_HELLO)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return -1;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 2 * (conn->rl.hash_size + conn->rl.key_material_len +
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    conn->rl.iv_size);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tlsv1_server_set_cipher_list - Configure acceptable cipher suites
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @conn: TLSv1 server connection data from tlsv1_server_init()
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (TLS_CIPHER_*).
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 on success, -1 on failure
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int tlsv1_server_set_cipher_list(struct tlsv1_server *conn, u8 *ciphers)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size_t count;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u16 *suites;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* TODO: implement proper configuration of cipher suites */
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ciphers[0] == TLS_CIPHER_ANON_DH_AES128_SHA) {
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		count = 0;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		suites = conn->cipher_suites;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONFIG_CRYPTO_INTERNAL
591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif /* CONFIG_CRYPTO_INTERNAL */
593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef CONFIG_CRYPTO_INTERNAL
598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		suites[count++] = TLS_DH_anon_WITH_AES_256_CBC_SHA;
599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif /* CONFIG_CRYPTO_INTERNAL */
600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		suites[count++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5;
603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		suites[count++] = TLS_DH_anon_WITH_DES_CBC_SHA;
604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		conn->num_cipher_suites = count;
605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	}
606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return 0;
608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int tlsv1_server_set_verify(struct tlsv1_server *conn, int verify_peer)
612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){
613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	conn->verify_peer = verify_peer;
614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return 0;
615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void tlsv1_server_set_session_ticket_cb(struct tlsv1_server *conn,
619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)					tlsv1_server_session_ticket_cb cb,
620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)					void *ctx)
621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){
622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback set %p (ctx %p)",
623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		   cb, ctx);
624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	conn->session_ticket_cb = cb;
625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	conn->session_ticket_cb_ctx = ctx;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)