/*
 * EAP peer method: EAP-FAST PAC file processing
 * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "eap_config.h"
#include "eap_i.h"
#include "eap_fast_pac.h"

/* TODO: encrypt PAC-Key in the PAC file */


/* Text data format */
static const char *pac_file_hdr =
	"wpa_supplicant EAP-FAST PAC file - version 1";

/*
 * Binary data format
 * 4-octet magic value: 6A E4 92 0C
 * 2-octet version (big endian)
 * <version specific data>
 *
 * version=0:
 * Sequence of PAC entries:
 *   2-octet PAC-Type (big endian)
 *   32-octet PAC-Key
 *   2-octet PAC-Opaque length (big endian)
 *   <variable len> PAC-Opaque data (length bytes)
 *   2-octet PAC-Info length (big endian)
 *   <variable len> PAC-Info data (length bytes)
 */

#define EAP_FAST_PAC_BINARY_MAGIC 0x6ae4920c
#define EAP_FAST_PAC_BINARY_FORMAT_VERSION 0


/**
 * eap_fast_free_pac - Free PAC data
 * @pac: Pointer to the PAC entry
 *
 * Note that the PAC entry must not be in a list since this function does not
 * remove the list links.
 */
void eap_fast_free_pac(struct eap_fast_pac *pac)
{
	os_free(pac->pac_opaque);
	os_free(pac->pac_info);
	os_free(pac->a_id);
	os_free(pac->i_id);
	os_free(pac->a_id_info);
	os_free(pac);
}


/**
 * eap_fast_get_pac - Get a PAC entry based on A-ID
 * @pac_root: Pointer to root of the PAC list
 * @a_id: A-ID to search for
 * @a_id_len: Length of A-ID
 * @pac_type: PAC-Type to search for
 * Returns: Pointer to the PAC entry, or %NULL if A-ID not found
 */
struct eap_fast_pac * eap_fast_get_pac(struct eap_fast_pac *pac_root,
				       const u8 *a_id, size_t a_id_len,
				       u16 pac_type)
{
	struct eap_fast_pac *pac = pac_root;

	while (pac) {
		if (pac->pac_type == pac_type && pac->a_id_len == a_id_len &&
		    os_memcmp(pac->a_id, a_id, a_id_len) == 0) {
			return pac;
		}
		pac = pac->next;
	}
	return NULL;
}


static void eap_fast_remove_pac(struct eap_fast_pac **pac_root,
				struct eap_fast_pac **pac_current,
				const u8 *a_id, size_t a_id_len, u16 pac_type)
{
	struct eap_fast_pac *pac, *prev;

	pac = *pac_root;
	prev = NULL;

	while (pac) {
		if (pac->pac_type == pac_type && pac->a_id_len == a_id_len &&
		    os_memcmp(pac->a_id, a_id, a_id_len) == 0) {
			if (prev == NULL)
				*pac_root = pac->next;
			else
				prev->next = pac->next;
			if (*pac_current == pac)
				*pac_current = NULL;
			eap_fast_free_pac(pac);
			break;
		}
		prev = pac;
		pac = pac->next;
	}
}


static int eap_fast_copy_buf(u8 **dst, size_t *dst_len,
			     const u8 *src, size_t src_len)
{
	if (src) {
		*dst = os_malloc(src_len);
		if (*dst == NULL)
			return -1;
		os_memcpy(*dst, src, src_len);
		*dst_len = src_len;
	}
	return 0;
}


/**
 * eap_fast_add_pac - Add a copy of a PAC entry to a list
 * @pac_root: Pointer to PAC list root pointer
 * @pac_current: Pointer to the current PAC pointer
 * @entry: New entry to clone and add to the list
 * Returns: 0 on success, -1 on failure
 *
 * This function makes a clone of the given PAC entry and adds this copied
 * entry to the list (pac_root). If an old entry for the same A-ID is found,
 * it will be removed from the PAC list and in this case, pac_current entry
 * is set to %NULL if it was the removed entry.
 */
int eap_fast_add_pac(struct eap_fast_pac **pac_root,
		     struct eap_fast_pac **pac_current,
		     struct eap_fast_pac *entry)
{
	struct eap_fast_pac *pac;

	if (entry == NULL || entry->a_id == NULL)
		return -1;

	/* Remove a possible old entry for the matching A-ID. */
	eap_fast_remove_pac(pac_root, pac_current,
			    entry->a_id, entry->a_id_len, entry->pac_type);

	/* Allocate a new entry and add it to the list of PACs. */
	pac = os_zalloc(sizeof(*pac));
	if (pac == NULL)
		return -1;

	pac->pac_type = entry->pac_type;
	os_memcpy(pac->pac_key, entry->pac_key, EAP_FAST_PAC_KEY_LEN);
	if (eap_fast_copy_buf(&pac->pac_opaque, &pac->pac_opaque_len,
			      entry->pac_opaque, entry->pac_opaque_len) < 0 ||
	    eap_fast_copy_buf(&pac->pac_info, &pac->pac_info_len,
			      entry->pac_info, entry->pac_info_len) < 0 ||
	    eap_fast_copy_buf(&pac->a_id, &pac->a_id_len,
			      entry->a_id, entry->a_id_len) < 0 ||
	    eap_fast_copy_buf(&pac->i_id, &pac->i_id_len,
			      entry->i_id, entry->i_id_len) < 0 ||
	    eap_fast_copy_buf(&pac->a_id_info, &pac->a_id_info_len,
			      entry->a_id_info, entry->a_id_info_len) < 0) {
		eap_fast_free_pac(pac);
		return -1;
	}

	pac->next = *pac_root;
	*pac_root = pac;

	return 0;
}


struct eap_fast_read_ctx {
	FILE *f;
	const char *pos;
	const char *end;
	int line;
	char *buf;
	size_t buf_len;
};

static int eap_fast_read_line(struct eap_fast_read_ctx *rc, char **value)
{
	char *pos;

	rc->line++;
	if (rc->f) {
		if (fgets(rc->buf, rc->buf_len, rc->f) == NULL)
			return -1;
	} else {
		const char *l_end;
		size_t len;
		if (rc->pos >= rc->end)
			return -1;
		l_end = rc->pos;
		while (l_end < rc->end && *l_end != '\n')
			l_end++;
		len = l_end - rc->pos;
		if (len >= rc->buf_len)
			len = rc->buf_len - 1;
		os_memcpy(rc->buf, rc->pos, len);
		rc->buf[len] = '\0';
		rc->pos = l_end + 1;
	}

	rc->buf[rc->buf_len - 1] = '\0';
	pos = rc->buf;
	while (*pos != '\0') {
		if (*pos == '\n' || *pos == '\r') {
			*pos = '\0';
			break;
		}
		pos++;
	}

	pos = os_strchr(rc->buf, '=');
	if (pos)
		*pos++ = '\0';
	*value = pos;

	return 0;
}


static u8 * eap_fast_parse_hex(const char *value, size_t *len)
{
	int hlen;
	u8 *buf;

	if (value == NULL)
		return NULL;
	hlen = os_strlen(value);
	if (hlen & 1)
		return NULL;
	*len = hlen / 2;
	buf = os_malloc(*len);
	if (buf == NULL)
		return NULL;
	if (hexstr2bin(value, buf, *len)) {
		os_free(buf);
		return NULL;
	}
	return buf;
}


static int eap_fast_init_pac_data(struct eap_sm *sm, const char *pac_file,
				  struct eap_fast_read_ctx *rc)
{
	os_memset(rc, 0, sizeof(*rc));

	rc->buf_len = 2048;
	rc->buf = os_malloc(rc->buf_len);
	if (rc->buf == NULL)
		return -1;

	if (os_strncmp(pac_file, "blob://", 7) == 0) {
		const struct wpa_config_blob *blob;
		blob = eap_get_config_blob(sm, pac_file + 7);
		if (blob == NULL) {
			wpa_printf(MSG_INFO, "EAP-FAST: No PAC blob '%s' - "
				   "assume no PAC entries have been "
				   "provisioned", pac_file + 7);
			os_free(rc->buf);
			return -1;
		}
		rc->pos = (char *) blob->data;
		rc->end = (char *) blob->data + blob->len;
	} else {
		rc->f = fopen(pac_file, "rb");
		if (rc->f == NULL) {
			wpa_printf(MSG_INFO, "EAP-FAST: No PAC file '%s' - "
				   "assume no PAC entries have been "
				   "provisioned", pac_file);
			os_free(rc->buf);
			return -1;
		}
	}

	return 0;
}


static void eap_fast_deinit_pac_data(struct eap_fast_read_ctx *rc)
{
	os_free(rc->buf);
	if (rc->f)
		fclose(rc->f);
}


static const char * eap_fast_parse_start(struct eap_fast_pac **pac)
{
	if (*pac)
		return "START line without END";

	*pac = os_zalloc(sizeof(struct eap_fast_pac));
	if (*pac == NULL)
		return "No memory for PAC entry";
	(*pac)->pac_type = PAC_TYPE_TUNNEL_PAC;
	return NULL;
}


static const char * eap_fast_parse_end(struct eap_fast_pac **pac_root,
				       struct eap_fast_pac **pac)
{
	if (*pac == NULL)
		return "END line without START";
	if (*pac_root) {
		struct eap_fast_pac *end = *pac_root;
		while (end->next)
			end = end->next;
		end->next = *pac;
	} else
		*pac_root = *pac;

	*pac = NULL;
	return NULL;
}


static const char * eap_fast_parse_pac_type(struct eap_fast_pac *pac,
					    char *pos)
{
	pac->pac_type = atoi(pos);
	if (pac->pac_type != PAC_TYPE_TUNNEL_PAC &&
	    pac->pac_type != PAC_TYPE_USER_AUTHORIZATION &&
	    pac->pac_type != PAC_TYPE_MACHINE_AUTHENTICATION)
		return "Unrecognized PAC-Type";

	return NULL;
}


static const char * eap_fast_parse_pac_key(struct eap_fast_pac *pac, char *pos)
{
	u8 *key;
	size_t key_len;

	key = eap_fast_parse_hex(pos, &key_len);
	if (key == NULL || key_len != EAP_FAST_PAC_KEY_LEN) {
		os_free(key);
		return "Invalid PAC-Key";
	}

	os_memcpy(pac->pac_key, key, EAP_FAST_PAC_KEY_LEN);
	os_free(key);

	return NULL;
}


static const char * eap_fast_parse_pac_opaque(struct eap_fast_pac *pac,
					      char *pos)
{
	os_free(pac->pac_opaque);
	pac->pac_opaque = eap_fast_parse_hex(pos, &pac->pac_opaque_len);
	if (pac->pac_opaque == NULL)
		return "Invalid PAC-Opaque";
	return NULL;
}


static const char * eap_fast_parse_a_id(struct eap_fast_pac *pac, char *pos)
{
	os_free(pac->a_id);
	pac->a_id = eap_fast_parse_hex(pos, &pac->a_id_len);
	if (pac->a_id == NULL)
		return "Invalid A-ID";
	return NULL;
}


static const char * eap_fast_parse_i_id(struct eap_fast_pac *pac, char *pos)
{
	os_free(pac->i_id);
	pac->i_id = eap_fast_parse_hex(pos, &pac->i_id_len);
	if (pac->i_id == NULL)
		return "Invalid I-ID";
	return NULL;
}


static const char * eap_fast_parse_a_id_info(struct eap_fast_pac *pac,
					     char *pos)
{
	os_free(pac->a_id_info);
	pac->a_id_info = eap_fast_parse_hex(pos, &pac->a_id_info_len);
	if (pac->a_id_info == NULL)
		return "Invalid A-ID-Info";
	return NULL;
}


/**
 * eap_fast_load_pac - Load PAC entries (text format)
 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
 * @pac_root: Pointer to root of the PAC list (to be filled)
 * @pac_file: Name of the PAC file/blob to load
 * Returns: 0 on success, -1 on failure
 */
int eap_fast_load_pac(struct eap_sm *sm, struct eap_fast_pac **pac_root,
		      const char *pac_file)
{
	struct eap_fast_read_ctx rc;
	struct eap_fast_pac *pac = NULL;
	int count = 0;
	char *pos;
	const char *err = NULL;

	if (pac_file == NULL)
		return -1;

	if (eap_fast_init_pac_data(sm, pac_file, &rc) < 0)
		return 0;

	if (eap_fast_read_line(&rc, &pos) < 0 ||
	    os_strcmp(pac_file_hdr, rc.buf) != 0)
		err = "Unrecognized header line";

	while (!err && eap_fast_read_line(&rc, &pos) == 0) {
		if (os_strcmp(rc.buf, "START") == 0)
			err = eap_fast_parse_start(&pac);
		else if (os_strcmp(rc.buf, "END") == 0) {
			err = eap_fast_parse_end(pac_root, &pac);
			count++;
		} else if (!pac)
			err = "Unexpected line outside START/END block";
		else if (os_strcmp(rc.buf, "PAC-Type") == 0)
			err = eap_fast_parse_pac_type(pac, pos);
		else if (os_strcmp(rc.buf, "PAC-Key") == 0)
			err = eap_fast_parse_pac_key(pac, pos);
		else if (os_strcmp(rc.buf, "PAC-Opaque") == 0)
			err = eap_fast_parse_pac_opaque(pac, pos);
		else if (os_strcmp(rc.buf, "A-ID") == 0)
			err = eap_fast_parse_a_id(pac, pos);
		else if (os_strcmp(rc.buf, "I-ID") == 0)
			err = eap_fast_parse_i_id(pac, pos);
		else if (os_strcmp(rc.buf, "A-ID-Info") == 0)
			err = eap_fast_parse_a_id_info(pac, pos);
	}

	if (pac) {
		err = "PAC block not terminated with END";
		eap_fast_free_pac(pac);
	}

	eap_fast_deinit_pac_data(&rc);

	if (err) {
		wpa_printf(MSG_INFO, "EAP-FAST: %s in '%s:%d'",
			   err, pac_file, rc.line);
		return -1;
	}

	wpa_printf(MSG_DEBUG, "EAP-FAST: Read %d PAC entries from '%s'",
		   count, pac_file);

	return 0;
}


static void eap_fast_write(char **buf, char **pos, size_t *buf_len,
			   const char *field, const u8 *data,
			   size_t len, int txt)
{
	size_t i, need;
	int ret;
	char *end;

	if (data == NULL || buf == NULL || *buf == NULL ||
	    pos == NULL || *pos == NULL || *pos < *buf)
		return;

	need = os_strlen(field) + len * 2 + 30;
	if (txt)
		need += os_strlen(field) + len + 20;

	if (*pos - *buf + need > *buf_len) {
		char *nbuf = os_realloc(*buf, *buf_len + need);
		if (nbuf == NULL) {
			os_free(*buf);
			*buf = NULL;
			return;
		}
		*pos = nbuf + (*pos - *buf);
		*buf = nbuf;
		*buf_len += need;
	}
	end = *buf + *buf_len;

	ret = os_snprintf(*pos, end - *pos, "%s=", field);
	if (ret < 0 || ret >= end - *pos)
		return;
	*pos += ret;
	*pos += wpa_snprintf_hex(*pos, end - *pos, data, len);
	ret = os_snprintf(*pos, end - *pos, "\n");
	if (ret < 0 || ret >= end - *pos)
		return;
	*pos += ret;

	if (txt) {
		ret = os_snprintf(*pos, end - *pos, "%s-txt=", field);
		if (ret < 0 || ret >= end - *pos)
			return;
		*pos += ret;
		for (i = 0; i < len; i++) {
			ret = os_snprintf(*pos, end - *pos, "%c", data[i]);
			if (ret < 0 || ret >= end - *pos)
				return;
			*pos += ret;
		}
		ret = os_snprintf(*pos, end - *pos, "\n");
		if (ret < 0 || ret >= end - *pos)
			return;
		*pos += ret;
	}
}


static int eap_fast_write_pac(struct eap_sm *sm, const char *pac_file,
			      char *buf, size_t len)
{
	if (os_strncmp(pac_file, "blob://", 7) == 0) {
		struct wpa_config_blob *blob;
		blob = os_zalloc(sizeof(*blob));
		if (blob == NULL)
			return -1;
		blob->data = (u8 *) buf;
		blob->len = len;
		buf = NULL;
		blob->name = os_strdup(pac_file + 7);
		if (blob->name == NULL) {
			os_free(blob);
			return -1;
		}
		eap_set_config_blob(sm, blob);
	} else {
		FILE *f;
		f = fopen(pac_file, "wb");
		if (f == NULL) {
			wpa_printf(MSG_INFO, "EAP-FAST: Failed to open PAC "
				   "file '%s' for writing", pac_file);
			return -1;
		}
		if (fwrite(buf, 1, len, f) != len) {
			wpa_printf(MSG_INFO, "EAP-FAST: Failed to write all "
				   "PACs into '%s'", pac_file);
			fclose(f);
			return -1;
		}
		os_free(buf);
		fclose(f);
	}

	return 0;
}


static int eap_fast_add_pac_data(struct eap_fast_pac *pac, char **buf,
				 char **pos, size_t *buf_len)
{
	int ret;

	ret = os_snprintf(*pos, *buf + *buf_len - *pos,
			  "START\nPAC-Type=%d\n", pac->pac_type);
	if (ret < 0 || ret >= *buf + *buf_len - *pos)
		return -1;

	*pos += ret;
	eap_fast_write(buf, pos, buf_len, "PAC-Key",
		       pac->pac_key, EAP_FAST_PAC_KEY_LEN, 0);
	eap_fast_write(buf, pos, buf_len, "PAC-Opaque",
		       pac->pac_opaque, pac->pac_opaque_len, 0);
	eap_fast_write(buf, pos, buf_len, "PAC-Info",
		       pac->pac_info, pac->pac_info_len, 0);
	eap_fast_write(buf, pos, buf_len, "A-ID",
		       pac->a_id, pac->a_id_len, 0);
	eap_fast_write(buf, pos, buf_len, "I-ID",
		       pac->i_id, pac->i_id_len, 1);
	eap_fast_write(buf, pos, buf_len, "A-ID-Info",
		       pac->a_id_info, pac->a_id_info_len, 1);
	if (*buf == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: No memory for PAC "
			   "data");
		return -1;
	}
	ret = os_snprintf(*pos, *buf + *buf_len - *pos, "END\n");
	if (ret < 0 || ret >= *buf + *buf_len - *pos)
		return -1;
	*pos += ret;

	return 0;
}


/**
 * eap_fast_save_pac - Save PAC entries (text format)
 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
 * @pac_root: Root of the PAC list
 * @pac_file: Name of the PAC file/blob
 * Returns: 0 on success, -1 on failure
 */
int eap_fast_save_pac(struct eap_sm *sm, struct eap_fast_pac *pac_root,
		      const char *pac_file)
{
	struct eap_fast_pac *pac;
	int ret, count = 0;
	char *buf, *pos;
	size_t buf_len;

	if (pac_file == NULL)
		return -1;

	buf_len = 1024;
	pos = buf = os_malloc(buf_len);
	if (buf == NULL)
		return -1;

	ret = os_snprintf(pos, buf + buf_len - pos, "%s\n", pac_file_hdr);
	if (ret < 0 || ret >= buf + buf_len - pos) {
		os_free(buf);
		return -1;
	}
	pos += ret;

	pac = pac_root;
	while (pac) {
		if (eap_fast_add_pac_data(pac, &buf, &pos, &buf_len)) {
			os_free(buf);
			return -1;
		}
		count++;
		pac = pac->next;
	}

	if (eap_fast_write_pac(sm, pac_file, buf, pos - buf)) {
		os_free(buf);
		return -1;
	}

	wpa_printf(MSG_DEBUG, "EAP-FAST: Wrote %d PAC entries into '%s'",
		   count, pac_file);

	return 0;
}


/**
 * eap_fast_pac_list_truncate - Truncate a PAC list to the given length
 * @pac_root: Root of the PAC list
 * @max_len: Maximum length of the list (>= 1)
 * Returns: Number of PAC entries removed
 */
size_t eap_fast_pac_list_truncate(struct eap_fast_pac *pac_root,
				  size_t max_len)
{
	struct eap_fast_pac *pac, *prev;
	size_t count;

	pac = pac_root;
	prev = NULL;
	count = 0;

	while (pac) {
		count++;
		if (count > max_len)
			break;
		prev = pac;
		pac = pac->next;
	}

	if (count <= max_len || prev == NULL)
		return 0;

	count = 0;
	prev->next = NULL;

	while (pac) {
		prev = pac;
		pac = pac->next;
		eap_fast_free_pac(prev);
		count++;
	}

	return count;
}


static void eap_fast_pac_get_a_id(struct eap_fast_pac *pac)
{
	u8 *pos, *end;
	u16 type, len;

	pos = pac->pac_info;
	end = pos + pac->pac_info_len;

	while (pos + 4 < end) {
		type = WPA_GET_BE16(pos);
		pos += 2;
		len = WPA_GET_BE16(pos);
		pos += 2;
		if (pos + len > end)
			break;

		if (type == PAC_TYPE_A_ID) {
			os_free(pac->a_id);
			pac->a_id = os_malloc(len);
			if (pac->a_id == NULL)
				break;
			os_memcpy(pac->a_id, pos, len);
			pac->a_id_len = len;
		}

		if (type == PAC_TYPE_A_ID_INFO) {
			os_free(pac->a_id_info);
			pac->a_id_info = os_malloc(len);
			if (pac->a_id_info == NULL)
				break;
			os_memcpy(pac->a_id_info, pos, len);
			pac->a_id_info_len = len;
		}

		pos += len;
	}
}


/**
 * eap_fast_load_pac_bin - Load PAC entries (binary format)
 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
 * @pac_root: Pointer to root of the PAC list (to be filled)
 * @pac_file: Name of the PAC file/blob to load
 * Returns: 0 on success, -1 on failure
 */
int eap_fast_load_pac_bin(struct eap_sm *sm, struct eap_fast_pac **pac_root,
			  const char *pac_file)
{
	const struct wpa_config_blob *blob = NULL;
	u8 *buf, *end, *pos;
	size_t len, count = 0;
	struct eap_fast_pac *pac, *prev;

	*pac_root = NULL;

	if (pac_file == NULL)
		return -1;

	if (os_strncmp(pac_file, "blob://", 7) == 0) {
		blob = eap_get_config_blob(sm, pac_file + 7);
		if (blob == NULL) {
			wpa_printf(MSG_INFO, "EAP-FAST: No PAC blob '%s' - "
				   "assume no PAC entries have been "
				   "provisioned", pac_file + 7);
			return 0;
		}
		buf = blob->data;
		len = blob->len;
	} else {
		buf = (u8 *) os_readfile(pac_file, &len);
		if (buf == NULL) {
			wpa_printf(MSG_INFO, "EAP-FAST: No PAC file '%s' - "
				   "assume no PAC entries have been "
				   "provisioned", pac_file);
			return 0;
		}
	}

	if (len == 0) {
		if (blob == NULL)
			os_free(buf);
		return 0;
	}

	if (len < 6 || WPA_GET_BE32(buf) != EAP_FAST_PAC_BINARY_MAGIC ||
	    WPA_GET_BE16(buf + 4) != EAP_FAST_PAC_BINARY_FORMAT_VERSION) {
		wpa_printf(MSG_INFO, "EAP-FAST: Invalid PAC file '%s' (bin)",
			   pac_file);
		if (blob == NULL)
			os_free(buf);
		return -1;
	}

	pac = prev = NULL;
	pos = buf + 6;
	end = buf + len;
	while (pos < end) {
		if (end - pos < 2 + 32 + 2 + 2)
			goto parse_fail;

		pac = os_zalloc(sizeof(*pac));
		if (pac == NULL)
			goto parse_fail;

		pac->pac_type = WPA_GET_BE16(pos);
		pos += 2;
		os_memcpy(pac->pac_key, pos, EAP_FAST_PAC_KEY_LEN);
		pos += EAP_FAST_PAC_KEY_LEN;
		pac->pac_opaque_len = WPA_GET_BE16(pos);
		pos += 2;
		if (pos + pac->pac_opaque_len + 2 > end)
			goto parse_fail;
		pac->pac_opaque = os_malloc(pac->pac_opaque_len);
		if (pac->pac_opaque == NULL)
			goto parse_fail;
		os_memcpy(pac->pac_opaque, pos, pac->pac_opaque_len);
		pos += pac->pac_opaque_len;
		pac->pac_info_len = WPA_GET_BE16(pos);
		pos += 2;
		if (pos + pac->pac_info_len > end)
			goto parse_fail;
		pac->pac_info = os_malloc(pac->pac_info_len);
		if (pac->pac_info == NULL)
			goto parse_fail;
		os_memcpy(pac->pac_info, pos, pac->pac_info_len);
		pos += pac->pac_info_len;
		eap_fast_pac_get_a_id(pac);

		count++;
		if (prev)
			prev->next = pac;
		else
			*pac_root = pac;
		prev = pac;
	}

	if (blob == NULL)
		os_free(buf);

	wpa_printf(MSG_DEBUG, "EAP-FAST: Read %lu PAC entries from '%s' (bin)",
		   (unsigned long) count, pac_file);

	return 0;

parse_fail:
	wpa_printf(MSG_INFO, "EAP-FAST: Failed to parse PAC file '%s' (bin)",
		   pac_file);
	if (blob == NULL)
		os_free(buf);
	if (pac)
		eap_fast_free_pac(pac);
	return -1;
}


/**
 * eap_fast_save_pac_bin - Save PAC entries (binary format)
 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
 * @pac_root: Root of the PAC list
 * @pac_file: Name of the PAC file/blob
 * Returns: 0 on success, -1 on failure
 */
int eap_fast_save_pac_bin(struct eap_sm *sm, struct eap_fast_pac *pac_root,
			  const char *pac_file)
{
	size_t len, count = 0;
	struct eap_fast_pac *pac;
	u8 *buf, *pos;

	len = 6;
	pac = pac_root;
	while (pac) {
		if (pac->pac_opaque_len > 65535 ||
		    pac->pac_info_len > 65535)
			return -1;
		len += 2 + EAP_FAST_PAC_KEY_LEN + 2 + pac->pac_opaque_len +
			2 + pac->pac_info_len;
		pac = pac->next;
	}

	buf = os_malloc(len);
	if (buf == NULL)
		return -1;

	pos = buf;
	WPA_PUT_BE32(pos, EAP_FAST_PAC_BINARY_MAGIC);
	pos += 4;
	WPA_PUT_BE16(pos, EAP_FAST_PAC_BINARY_FORMAT_VERSION);
	pos += 2;

	pac = pac_root;
	while (pac) {
		WPA_PUT_BE16(pos, pac->pac_type);
		pos += 2;
		os_memcpy(pos, pac->pac_key, EAP_FAST_PAC_KEY_LEN);
		pos += EAP_FAST_PAC_KEY_LEN;
		WPA_PUT_BE16(pos, pac->pac_opaque_len);
		pos += 2;
		os_memcpy(pos, pac->pac_opaque, pac->pac_opaque_len);
		pos += pac->pac_opaque_len;
		WPA_PUT_BE16(pos, pac->pac_info_len);
		pos += 2;
		os_memcpy(pos, pac->pac_info, pac->pac_info_len);
		pos += pac->pac_info_len;

		pac = pac->next;
		count++;
	}

	if (eap_fast_write_pac(sm, pac_file, (char *) buf, len)) {
		os_free(buf);
		return -1;
	}

	wpa_printf(MSG_DEBUG, "EAP-FAST: Wrote %lu PAC entries into '%s' "
		   "(bin)", (unsigned long) count, pac_file);

	return 0;
}
