aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorSam Leffler <sam@FreeBSD.org>2008-03-24 19:46:53 +0000
committerSam Leffler <sam@FreeBSD.org>2008-03-24 19:46:53 +0000
commitf2afa83e728168e47c37af2a32a3b32afec888ec (patch)
treef77bae77287d18eaa89acc25e38b5acccca132fe /contrib
parent7700b89cce864f82dbd9cf54979c59dd06ca9356 (diff)
downloadsrc-f2afa83e728168e47c37af2a32a3b32afec888ec.tar.gz
src-f2afa83e728168e47c37af2a32a3b32afec888ec.zip
Import of WPA supplicant 0.5.10
Notes
Notes: svn path=/vendor/wpa_supplicant/dist/; revision=177568
Diffstat (limited to 'contrib')
-rw-r--r--contrib/wpa_supplicant/ChangeLog41
-rw-r--r--contrib/wpa_supplicant/Makefile25
-rw-r--r--contrib/wpa_supplicant/README5
-rw-r--r--contrib/wpa_supplicant/aes_wrap.c77
-rw-r--r--contrib/wpa_supplicant/aes_wrap.h4
-rw-r--r--contrib/wpa_supplicant/asn1.c6
-rw-r--r--contrib/wpa_supplicant/common.c28
-rw-r--r--contrib/wpa_supplicant/common.h4
-rw-r--r--contrib/wpa_supplicant/config.c13
-rw-r--r--contrib/wpa_supplicant/config_ssid.h12
-rw-r--r--contrib/wpa_supplicant/ctrl_iface.c7
-rw-r--r--contrib/wpa_supplicant/ctrl_iface_dbus.c25
-rw-r--r--contrib/wpa_supplicant/ctrl_iface_dbus_handlers.c126
-rw-r--r--contrib/wpa_supplicant/ctrl_iface_dbus_handlers.h6
-rw-r--r--contrib/wpa_supplicant/ctrl_iface_unix.c39
-rw-r--r--contrib/wpa_supplicant/dbus-wpa_supplicant.conf4
-rw-r--r--contrib/wpa_supplicant/dbus-wpa_supplicant.service4
-rw-r--r--contrib/wpa_supplicant/defconfig7
-rw-r--r--contrib/wpa_supplicant/doc/ctrl_iface.doxygen9
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_background.82
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_cli.84
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_cli.sgml2
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_passphrase.82
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_supplicant.87
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.52
-rw-r--r--contrib/wpa_supplicant/doc/docbook/wpa_supplicant.sgml10
-rw-r--r--contrib/wpa_supplicant/driver_ndis.c2
-rw-r--r--contrib/wpa_supplicant/eap_gpsk.c415
-rw-r--r--contrib/wpa_supplicant/eap_gpsk_common.c304
-rw-r--r--contrib/wpa_supplicant/eap_gpsk_common.h6
-rw-r--r--contrib/wpa_supplicant/eap_peap.c21
-rw-r--r--contrib/wpa_supplicant/eap_sim.c18
-rw-r--r--contrib/wpa_supplicant/eap_sim_common.c11
-rw-r--r--contrib/wpa_supplicant/eap_tlv.c16
-rw-r--r--contrib/wpa_supplicant/eap_tlv.h5
-rw-r--r--contrib/wpa_supplicant/eapol_sm.c12
-rw-r--r--contrib/wpa_supplicant/eapol_test.c6
-rw-r--r--contrib/wpa_supplicant/events.c13
-rw-r--r--contrib/wpa_supplicant/main.c15
-rw-r--r--contrib/wpa_supplicant/os.h3
-rw-r--r--contrib/wpa_supplicant/os_unix.c21
-rw-r--r--contrib/wpa_supplicant/pcsc_funcs.c32
-rw-r--r--contrib/wpa_supplicant/radius.c29
-rw-r--r--contrib/wpa_supplicant/radius.h1
-rw-r--r--contrib/wpa_supplicant/radius_client.c17
-rw-r--r--contrib/wpa_supplicant/tests/test_aes.c306
-rw-r--r--contrib/wpa_supplicant/tests/test_eap_sim_common.c53
-rw-r--r--contrib/wpa_supplicant/tests/test_md4.c99
-rw-r--r--contrib/wpa_supplicant/tests/test_md5.c99
-rw-r--r--contrib/wpa_supplicant/tests/test_ms_funcs.c119
-rw-r--r--contrib/wpa_supplicant/tests/test_sha1.c328
-rw-r--r--contrib/wpa_supplicant/tests/test_sha256.c330
-rw-r--r--contrib/wpa_supplicant/tests/test_x509v3.c69
-rw-r--r--contrib/wpa_supplicant/tls_openssl.c16
-rw-r--r--contrib/wpa_supplicant/version.h2
-rw-r--r--contrib/wpa_supplicant/wpa.c4
-rw-r--r--contrib/wpa_supplicant/wpa_cli.c122
-rw-r--r--contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp2
-rw-r--r--contrib/wpa_supplicant/wpa_gui-qt4/wpagui.cpp4
-rw-r--r--contrib/wpa_supplicant/wpa_gui/networkconfig.ui.h2
-rwxr-xr-xcontrib/wpa_supplicant/wpa_gui/setup-mingw-cross-compiling6
-rw-r--r--contrib/wpa_supplicant/wpa_gui/wpagui.ui.h2
-rw-r--r--contrib/wpa_supplicant/wpa_supplicant.c25
-rw-r--r--contrib/wpa_supplicant/wpa_supplicant.conf8
-rw-r--r--contrib/wpa_supplicant/wpa_supplicant_i.h4
-rw-r--r--contrib/wpa_supplicant/x509v3.c96
66 files changed, 2609 insertions, 505 deletions
diff --git a/contrib/wpa_supplicant/ChangeLog b/contrib/wpa_supplicant/ChangeLog
index 5bf3660a05c9..1ba2e1c8b2e2 100644
--- a/contrib/wpa_supplicant/ChangeLog
+++ b/contrib/wpa_supplicant/ChangeLog
@@ -1,5 +1,46 @@
ChangeLog for wpa_supplicant
+2008-02-19 - v0.5.10
+ * added support for Makefile builds to include debug-log-to-a-file
+ functionality (CONFIG_DEBUG_FILE=y and -f<path> on command line)
+ * added network configuration parameter 'frequency' for setting
+ initial channel for IBSS (adhoc) networks
+ * fixed EAP-SIM and EAP-AKA message parser to validate attribute
+ lengths properly to avoid potential crash caused by invalid messages
+ * added driver_wext workaround for race condition between scanning and
+ association with drivers that take very long time to scan all
+ channels (e.g., madwifi with dual-band cards); wpa_supplicant is now
+ using a longer hardcoded timeout for the scan if the driver supports
+ notifications for scan completion (SIOCGIWSCAN event); this helps,
+ e.g., in cases where wpa_supplicant and madwifi driver ended up in
+ loop where the driver did not even try to associate
+ * fixed EAP-SIM not to include AT_NONCE_MT and AT_SELECTED_VERSION
+ attributes in EAP-SIM Start/Response when using fast reauthentication
+ * fixed problems in getting NDIS events from WMI on Windows 2000
+
+2007-12-02 - v0.5.9
+ * fixed an integer overflow issue in the ASN.1 parser used by the
+ (experimental) internal TLS implementation to avoid a potential
+ buffer read overflow
+ * fixed a race condition with -W option (wait for a control interface
+ monitor before starting) that could have caused the first messages to
+ be lost
+ * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
+ draft (draft-ietf-emu-eap-gpsk-07.txt)
+ * added ctrl_iface RECONNECT (wpa_cli reconnect) command
+ (like reassociate, but only takes effect if already associated)
+ * fixed a possible race condition between wpa_cli reassociate and
+ wpa_cli disconnect
+ * return a non-zero exit code from non-interactive wpa_cli if the
+ command is not recognized or fails
+ * fixed 0.5.8 regressions in BSS selection that prevented wildcard SSID
+ from being used with non-WPA networks and disabled workaround for
+ ignoring bogus WPA/RSN IE in non-WPA configuration
+ * fixed OpenSSL TLS wrapper to clear trusted CA list to allow
+ network blocks to use different trusted CA configurations
+ * fixed a potential EAP state machine loop when mloving from PSK to EAP
+ configuration without restarting wpa_supplicant
+
2007-05-28 - v0.5.8
* updated driver_wext.c to build with the current wireless-dev.git tree
and net/d80211 changes
diff --git a/contrib/wpa_supplicant/Makefile b/contrib/wpa_supplicant/Makefile
index f29eb693a7e3..51114fa57a97 100644
--- a/contrib/wpa_supplicant/Makefile
+++ b/contrib/wpa_supplicant/Makefile
@@ -654,8 +654,25 @@ endif
ifdef CONFIG_CTRL_IFACE_DBUS
CFLAGS += -DCONFIG_CTRL_IFACE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE
OBJS += ctrl_iface_dbus.o ctrl_iface_dbus_handlers.o dbus_dict_helpers.o
-LIBS += `pkg-config --libs dbus-1`
-CFLAGS += `pkg-config --cflags dbus-1`
+ifndef DBUS_LIBS
+DBUS_LIBS := $(shell pkg-config --libs dbus-1)
+endif
+LIBS += $(DBUS_LIBS)
+ifndef DBUS_INCLUDE
+DBUS_INCLUDE := $(shell pkg-config --cflags dbus-1)
+endif
+dbus_version=$(subst ., ,$(shell pkg-config --modversion dbus-1))
+DBUS_VERSION_MAJOR=$(word 1,$(dbus_version))
+DBUS_VERSION_MINOR=$(word 2,$(dbus_version))
+ifeq ($(DBUS_VERSION_MAJOR),)
+DBUS_VERSION_MAJOR=0
+endif
+ifeq ($(DBUS_VERSION_MINOR),)
+DBUS_VERSION_MINOR=0
+endif
+DBUS_INCLUDE += -DDBUS_VERSION_MAJOR=$(DBUS_VERSION_MAJOR)
+DBUS_INCLUDE += -DDBUS_VERSION_MINOR=$(DBUS_VERSION_MINOR)
+CFLAGS += $(DBUS_INCLUDE)
endif
ifdef CONFIG_READLINE
@@ -724,6 +741,10 @@ ifndef CONFIG_MAIN
CONFIG_MAIN=main
endif
+ifdef CONFIG_DEBUG_FILE
+CFLAGS += -DCONFIG_DEBUG_FILE
+endif
+
OBJS += wpa_supplicant.o events.o
OBJS_t := $(OBJS) eapol_test.o radius.o radius_client.o
OBJS_t2 := $(OBJS) preauth_test.o
diff --git a/contrib/wpa_supplicant/README b/contrib/wpa_supplicant/README
index be0757420efd..0b3c5858c43e 100644
--- a/contrib/wpa_supplicant/README
+++ b/contrib/wpa_supplicant/README
@@ -1,7 +1,7 @@
WPA Supplicant
==============
-Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> and contributors
+Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> and contributors
All Rights Reserved.
This program is dual-licensed under both the GPL version 2 and BSD
@@ -481,7 +481,7 @@ Command line options
--------------------
usage:
- wpa_supplicant [-BddehLqqvwW] [-P<pid file>] [-g<global ctrl>] \
+ wpa_supplicant [-BddfhKLqqtuvwW] [-P<pid file>] [-g<global ctrl>] \
-i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] [-p<driver_param>] \
[-b<br_ifname> [-N -i<ifname> -c<conf> [-C<ctrl>] [-D<driver>] \
[-p<driver_param>] [-b<br_ifname>] ...]
@@ -494,6 +494,7 @@ options:
-i = interface name
-d = increase debugging verbosity (-dd even more)
-D = driver name
+ -f = Log output to default log location (normally /tmp)
-g = global ctrl_interface
-K = include keys (passwords, etc.) in debug output
-t = include timestamp in debug messages
diff --git a/contrib/wpa_supplicant/aes_wrap.c b/contrib/wpa_supplicant/aes_wrap.c
index c52e45af27c5..765b1ca871ad 100644
--- a/contrib/wpa_supplicant/aes_wrap.c
+++ b/contrib/wpa_supplicant/aes_wrap.c
@@ -7,7 +7,7 @@
* - AES-128 EAX mode encryption/decryption
* - AES-128 CBC
*
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -34,10 +34,11 @@
/**
* aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
- * @kek: Key encryption key (KEK)
- * @n: Length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
- * @plain: Plaintext key to be wrapped, n * 64 bit
- * @cipher: Wrapped key, (n + 1) * 64 bit
+ * @kek: 16-octet Key encryption key (KEK)
+ * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
+ * bytes
+ * @plain: Plaintext key to be wrapped, n * 64 bits
+ * @cipher: Wrapped key, (n + 1) * 64 bits
* Returns: 0 on success, -1 on failure
*/
int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher)
@@ -93,9 +94,10 @@ int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher)
/**
* aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
* @kek: Key encryption key (KEK)
- * @n: Length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
- * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bit
- * @plain: Plaintext key, n * 64 bit
+ * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
+ * bytes
+ * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits
+ * @plain: Plaintext key, n * 64 bits
* Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
*/
int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain)
@@ -167,28 +169,45 @@ static void gf_mulx(u8 *pad)
/**
- * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
+ * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
* @key: 128-bit key for the hash operation
- * @data: Data buffer for which a MAC is determined
- * @data: Length of data buffer in bytes
+ * @num_elem: Number of elements in the data vector
+ * @addr: Pointers to the data areas
+ * @len: Lengths of the data blocks
* @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
* Returns: 0 on success, -1 on failure
*/
-int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
+int omac1_aes_128_vector(const u8 *key, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac)
{
void *ctx;
u8 cbc[BLOCK_SIZE], pad[BLOCK_SIZE];
- const u8 *pos = data;
- size_t i, left = data_len;
+ const u8 *pos, *end;
+ size_t i, e, left, total_len;
ctx = aes_encrypt_init(key, 16);
if (ctx == NULL)
return -1;
os_memset(cbc, 0, BLOCK_SIZE);
+ total_len = 0;
+ for (e = 0; e < num_elem; e++)
+ total_len += len[e];
+ left = total_len;
+
+ e = 0;
+ pos = addr[0];
+ end = pos + len[0];
+
while (left >= BLOCK_SIZE) {
- for (i = 0; i < BLOCK_SIZE; i++)
+ for (i = 0; i < BLOCK_SIZE; i++) {
cbc[i] ^= *pos++;
+ if (pos >= end) {
+ e++;
+ pos = addr[e];
+ end = pos + len[e];
+ }
+ }
if (left > BLOCK_SIZE)
aes_encrypt(ctx, cbc, cbc);
left -= BLOCK_SIZE;
@@ -198,9 +217,15 @@ int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
aes_encrypt(ctx, pad, pad);
gf_mulx(pad);
- if (left || data_len == 0) {
- for (i = 0; i < left; i++)
+ if (left || total_len == 0) {
+ for (i = 0; i < left; i++) {
cbc[i] ^= *pos++;
+ if (pos >= end) {
+ e++;
+ pos = addr[e];
+ end = pos + len[e];
+ }
+ }
cbc[left] ^= 0x80;
gf_mulx(pad);
}
@@ -212,6 +237,24 @@ int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
return 0;
}
+
+/**
+ * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
+ * @key: 128-bit key for the hash operation
+ * @data: Data buffer for which a MAC is determined
+ * @data_len: Length of data buffer in bytes
+ * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
+ * Returns: 0 on success, -1 on failure
+ *
+ * This is a mode for using block cipher (AES in this case) for authentication.
+ * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
+ * (SP) 800-38B.
+ */
+int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
+{
+ return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
+}
+
#endif /* CONFIG_NO_AES_OMAC1 */
diff --git a/contrib/wpa_supplicant/aes_wrap.h b/contrib/wpa_supplicant/aes_wrap.h
index 1bc6971eff8e..5eb4342a5bf9 100644
--- a/contrib/wpa_supplicant/aes_wrap.h
+++ b/contrib/wpa_supplicant/aes_wrap.h
@@ -7,7 +7,7 @@
* - AES-128 EAX mode encryption/decryption
* - AES-128 CBC
*
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -24,6 +24,8 @@
int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher);
int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain);
+int omac1_aes_128_vector(const u8 *key, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac);
int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac);
int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out);
int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
diff --git a/contrib/wpa_supplicant/asn1.c b/contrib/wpa_supplicant/asn1.c
index ff3db7dc73c0..96bc1ac78a9d 100644
--- a/contrib/wpa_supplicant/asn1.c
+++ b/contrib/wpa_supplicant/asn1.c
@@ -58,6 +58,10 @@ int asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr)
}
tmp &= 0x7f; /* number of subsequent octets */
hdr->length = 0;
+ if (tmp > 4) {
+ wpa_printf(MSG_DEBUG, "ASN.1: Too long length field");
+ return -1;
+ }
while (tmp--) {
if (pos >= end) {
wpa_printf(MSG_DEBUG, "ASN.1: Length "
@@ -71,7 +75,7 @@ int asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr)
hdr->length = tmp;
}
- if (pos + hdr->length > end) {
+ if (end < pos || hdr->length > (unsigned int) (end - pos)) {
wpa_printf(MSG_DEBUG, "ASN.1: Contents underflow");
return -1;
}
diff --git a/contrib/wpa_supplicant/common.c b/contrib/wpa_supplicant/common.c
index c8d6f130a960..f226c68631b8 100644
--- a/contrib/wpa_supplicant/common.c
+++ b/contrib/wpa_supplicant/common.c
@@ -20,7 +20,6 @@
#ifdef CONFIG_DEBUG_FILE
static FILE *out_file = NULL;
#endif /* CONFIG_DEBUG_FILE */
-int wpa_debug_use_file = 0;
int wpa_debug_level = MSG_INFO;
int wpa_debug_show_keys = 0;
int wpa_debug_timestamp = 0;
@@ -344,32 +343,29 @@ void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
}
-int wpa_debug_open_file(void)
+int wpa_debug_open_file(const char *path)
{
#ifdef CONFIG_DEBUG_FILE
- static int count = 0;
- char fname[64];
- if (!wpa_debug_use_file)
+ if (!path)
return 0;
-#ifdef _WIN32
- os_snprintf(fname, sizeof(fname), "\\Temp\\wpa_supplicant-log-%d.txt",
- count++);
-#else /* _WIN32 */
- os_snprintf(fname, sizeof(fname), "/tmp/wpa_supplicant-log-%d.txt",
- count++);
+ out_file = fopen(path, "a");
+ if (out_file == NULL) {
+ wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
+ "output file, using standard output");
+ return -1;
+ }
+#ifndef _WIN32
+ setvbuf(out_file, NULL, _IOLBF, 0);
#endif /* _WIN32 */
- out_file = fopen(fname, "w");
- return out_file == NULL ? -1 : 0;
-#else /* CONFIG_DEBUG_FILE */
- return 0;
#endif /* CONFIG_DEBUG_FILE */
+ return 0;
}
void wpa_debug_close_file(void)
{
#ifdef CONFIG_DEBUG_FILE
- if (!wpa_debug_use_file)
+ if (!out_file)
return;
fclose(out_file);
out_file = NULL;
diff --git a/contrib/wpa_supplicant/common.h b/contrib/wpa_supplicant/common.h
index b200b580d5df..eda328af345d 100644
--- a/contrib/wpa_supplicant/common.h
+++ b/contrib/wpa_supplicant/common.h
@@ -264,12 +264,12 @@ enum { MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR };
#define wpa_hexdump_key(l,t,b,le) do { } while (0)
#define wpa_hexdump_ascii(l,t,b,le) do { } while (0)
#define wpa_hexdump_ascii_key(l,t,b,le) do { } while (0)
-#define wpa_debug_open_file() do { } while (0)
+#define wpa_debug_open_file(p) do { } while (0)
#define wpa_debug_close_file() do { } while (0)
#else /* CONFIG_NO_STDOUT_DEBUG */
-int wpa_debug_open_file(void);
+int wpa_debug_open_file(const char *path);
void wpa_debug_close_file(void);
/**
diff --git a/contrib/wpa_supplicant/config.c b/contrib/wpa_supplicant/config.c
index 171970dc210f..6ea66de34eec 100644
--- a/contrib/wpa_supplicant/config.c
+++ b/contrib/wpa_supplicant/config.c
@@ -66,17 +66,19 @@ static char * wpa_config_parse_string(const char *value, size_t *len)
return os_strdup(value);
} else {
u8 *str;
- size_t hlen = os_strlen(value);
+ size_t tlen, hlen = os_strlen(value);
if (hlen & 1)
return NULL;
- *len = hlen / 2;
- str = os_malloc(*len);
+ tlen = hlen / 2;
+ str = os_malloc(tlen + 1);
if (str == NULL)
return NULL;
- if (hexstr2bin(value, str, *len)) {
+ if (hexstr2bin(value, str, tlen)) {
os_free(str);
return NULL;
}
+ str[tlen] = '\0';
+ *len = tlen;
return (char *) str;
}
}
@@ -1157,7 +1159,8 @@ static const struct parse_data ssid_fields[] = {
{ INT_RANGE(ieee80211w, 0, 2) },
#endif /* CONFIG_IEEE80211W */
{ INT_RANGE(peerkey, 0, 1) },
- { INT_RANGE(mixed_cell, 0, 1) }
+ { INT_RANGE(mixed_cell, 0, 1) },
+ { INT_RANGE(frequency, 0, 10000) }
};
#undef OFFSET
diff --git a/contrib/wpa_supplicant/config_ssid.h b/contrib/wpa_supplicant/config_ssid.h
index d4c36541194d..393f7506ce39 100644
--- a/contrib/wpa_supplicant/config_ssid.h
+++ b/contrib/wpa_supplicant/config_ssid.h
@@ -851,6 +851,18 @@ struct wpa_ssid {
IEEE80211W_REQUIRED = 2
} ieee80211w;
#endif /* CONFIG_IEEE80211W */
+
+ /**
+ * frequency - Channel frequency in megahertz (MHz) for IBSS
+ *
+ * This value is used to configure the initial channel for IBSS (adhoc)
+ * networks, e.g., 2412 = IEEE 802.11b/g channel 1. It is ignored in
+ * the infrastructure mode. In addition, this value is only used by the
+ * station that creates the IBSS. If an IBSS network with the
+ * configured SSID is already present, the frequency of the network
+ * will be used instead of this configured value.
+ */
+ int frequency;
};
int wpa_config_allowed_eap_method(struct wpa_ssid *ssid, int vendor,
diff --git a/contrib/wpa_supplicant/ctrl_iface.c b/contrib/wpa_supplicant/ctrl_iface.c
index c864c91c5e03..c84a9f9d75aa 100644
--- a/contrib/wpa_supplicant/ctrl_iface.c
+++ b/contrib/wpa_supplicant/ctrl_iface.c
@@ -1120,6 +1120,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
wpa_s->disconnected = 0;
wpa_s->reassociate = 1;
wpa_supplicant_req_scan(wpa_s, 0, 0);
+ } else if (os_strcmp(buf, "RECONNECT") == 0) {
+ if (wpa_s->disconnected) {
+ wpa_s->disconnected = 0;
+ wpa_s->reassociate = 1;
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
+ }
} else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
reply_len = -1;
@@ -1147,6 +1153,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
reply_len = wpa_supplicant_ctrl_iface_list_networks(
wpa_s, reply, reply_size);
} else if (os_strcmp(buf, "DISCONNECT") == 0) {
+ wpa_s->reassociate = 0;
wpa_s->disconnected = 1;
wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
} else if (os_strcmp(buf, "SCAN") == 0) {
diff --git a/contrib/wpa_supplicant/ctrl_iface_dbus.c b/contrib/wpa_supplicant/ctrl_iface_dbus.c
index 1d66c9633d5c..ba7851694ba4 100644
--- a/contrib/wpa_supplicant/ctrl_iface_dbus.c
+++ b/contrib/wpa_supplicant/ctrl_iface_dbus.c
@@ -30,6 +30,14 @@
#include "wpa_ctrl.h"
#include "eap.h"
+#define DBUS_VERSION (DBUS_VERSION_MAJOR << 8 | DBUS_VERSION_MINOR)
+#define DBUS_VER(major, minor) ((major) << 8 | (minor))
+
+#if DBUS_VERSION < DBUS_VER(1,1)
+#define dbus_watch_get_unix_fd dbus_watch_get_fd
+#endif
+
+
struct ctrl_iface_dbus_priv {
DBusConnection *con;
int should_dispatch;
@@ -92,7 +100,7 @@ static void connection_setup_add_watch(struct ctrl_iface_dbus_priv *iface,
return;
flags = dbus_watch_get_flags(watch);
- fd = dbus_watch_get_fd(watch);
+ fd = dbus_watch_get_unix_fd(watch);
eloop_register_sock(fd, EVENT_TYPE_EXCEPTION, process_watch_exception,
iface, watch);
@@ -117,7 +125,7 @@ static void connection_setup_remove_watch(struct ctrl_iface_dbus_priv *iface,
int fd;
flags = dbus_watch_get_flags(watch);
- fd = dbus_watch_get_fd(watch);
+ fd = dbus_watch_get_unix_fd(watch);
eloop_unregister_sock(fd, EVENT_TYPE_EXCEPTION);
@@ -536,6 +544,10 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
reply = wpas_dbus_iface_set_ap_scan(message, wpa_s);
else if (!strcmp(method, "state"))
reply = wpas_dbus_iface_get_state(message, wpa_s);
+ else if (!strcmp(method, "setBlobs"))
+ reply = wpas_dbus_iface_set_blobs(message, wpa_s);
+ else if (!strcmp(method, "removeBlobs"))
+ reply = wpas_dbus_iface_remove_blobs(message, wpa_s);
}
/* If the message was handled, send back the reply */
@@ -645,6 +657,7 @@ void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s)
return;
}
dbus_connection_send(iface->con, signal, NULL);
+ dbus_message_unref(signal);
}
@@ -662,7 +675,7 @@ void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
wpa_states old_state)
{
struct ctrl_iface_dbus_priv *iface;
- DBusMessage *signal;
+ DBusMessage *signal = NULL;
const char *path;
const char *new_state_str, *old_state_str;
@@ -707,7 +720,7 @@ void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_ERROR,
"wpa_supplicant_dbus_notify_state_change[dbus]: "
"couldn't convert state strings.");
- return;
+ goto out;
}
if (!dbus_message_append_args(signal,
@@ -720,8 +733,12 @@ void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
"wpa_supplicant_dbus_notify_state_change[dbus]: "
"not enough memory to construct state change "
"signal.");
+ goto out;
}
dbus_connection_send(iface->con, signal, NULL);
+
+out:
+ dbus_message_unref(signal);
}
diff --git a/contrib/wpa_supplicant/ctrl_iface_dbus_handlers.c b/contrib/wpa_supplicant/ctrl_iface_dbus_handlers.c
index 5e952ec5ffa9..19972c008045 100644
--- a/contrib/wpa_supplicant/ctrl_iface_dbus_handlers.c
+++ b/contrib/wpa_supplicant/ctrl_iface_dbus_handlers.c
@@ -1203,3 +1203,129 @@ DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
return reply;
}
+
+
+/**
+ * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates)
+ * @message: Pointer to incoming dbus message
+ * @global: %wpa_supplicant global data structure
+ * Returns: A dbus message containing a UINT32 indicating success (1) or
+ * failure (0)
+ *
+ * Asks wpa_supplicant to internally store a one or more binary blobs.
+ */
+DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessage *reply = NULL;
+ struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
+ DBusMessageIter iter, iter_dict;
+
+ dbus_message_iter_init(message, &iter);
+
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ return wpas_dbus_new_invalid_opts_error(message, NULL);
+
+ while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+ struct wpa_config_blob *blob;
+
+ if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
+ reply = wpas_dbus_new_invalid_opts_error(message,
+ NULL);
+ break;
+ }
+
+ if (entry.type != DBUS_TYPE_ARRAY ||
+ entry.array_type != DBUS_TYPE_BYTE) {
+ reply = wpas_dbus_new_invalid_opts_error(
+ message, "Byte array expected.");
+ break;
+ }
+
+ if ((entry.array_len <= 0) || (entry.array_len > 65536) ||
+ !strlen(entry.key)) {
+ reply = wpas_dbus_new_invalid_opts_error(
+ message, "Invalid array size.");
+ break;
+ }
+
+ blob = os_zalloc(sizeof(*blob));
+ if (blob == NULL) {
+ reply = dbus_message_new_error(
+ message, WPAS_ERROR_ADD_ERROR,
+ "Not enough memory to add blob.");
+ break;
+ }
+ blob->data = os_zalloc(entry.array_len);
+ if (blob->data == NULL) {
+ reply = dbus_message_new_error(
+ message, WPAS_ERROR_ADD_ERROR,
+ "Not enough memory to add blob data.");
+ os_free(blob);
+ break;
+ }
+
+ blob->name = os_strdup(entry.key);
+ blob->len = entry.array_len;
+ os_memcpy(blob->data, (u8 *) entry.bytearray_value,
+ entry.array_len);
+ if (blob->name == NULL || blob->data == NULL) {
+ wpa_config_free_blob(blob);
+ reply = dbus_message_new_error(
+ message, WPAS_ERROR_ADD_ERROR,
+ "Error adding blob.");
+ break;
+ }
+
+ /* Success */
+ wpa_config_remove_blob(wpa_s->conf, blob->name);
+ wpa_config_set_blob(wpa_s->conf, blob);
+ wpa_dbus_dict_entry_clear(&entry);
+ }
+ wpa_dbus_dict_entry_clear(&entry);
+
+ return reply ? reply : wpas_dbus_new_success_reply(message);
+}
+
+
+/**
+ * wpas_dbus_iface_remove_blob - Remove named binary blobs
+ * @message: Pointer to incoming dbus message
+ * @global: %wpa_supplicant global data structure
+ * Returns: A dbus message containing a UINT32 indicating success (1) or
+ * failure (0)
+ *
+ * Asks wpa_supplicant to remove one or more previously stored binary blobs.
+ */
+DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessageIter iter, array;
+ char *err_msg = NULL;
+
+ dbus_message_iter_init(message, &iter);
+
+ if ((dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) ||
+ (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRING))
+ return wpas_dbus_new_invalid_opts_error(message, NULL);
+
+ dbus_message_iter_recurse(&iter, &array);
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
+ const char *name;
+
+ dbus_message_iter_get_basic(&array, &name);
+ if (!strlen(name))
+ err_msg = "Invalid blob name.";
+
+ if (wpa_config_remove_blob(wpa_s->conf, name) != 0)
+ err_msg = "Error removing blob.";
+ dbus_message_iter_next(&array);
+ }
+
+ if (err_msg) {
+ return dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR,
+ err_msg);
+ }
+
+ return wpas_dbus_new_success_reply(message);
+}
diff --git a/contrib/wpa_supplicant/ctrl_iface_dbus_handlers.h b/contrib/wpa_supplicant/ctrl_iface_dbus_handlers.h
index 0fd1d3164267..0ae94c41b7ce 100644
--- a/contrib/wpa_supplicant/ctrl_iface_dbus_handlers.h
+++ b/contrib/wpa_supplicant/ctrl_iface_dbus_handlers.h
@@ -71,6 +71,12 @@ DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message,
DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
#endif /* CONFIG_CTRL_IFACE_DBUS */
#endif /* CTRL_IFACE_DBUS_HANDLERS_H */
diff --git a/contrib/wpa_supplicant/ctrl_iface_unix.c b/contrib/wpa_supplicant/ctrl_iface_unix.c
index e9bc47239c63..9e4f85fabaad 100644
--- a/contrib/wpa_supplicant/ctrl_iface_unix.c
+++ b/contrib/wpa_supplicant/ctrl_iface_unix.c
@@ -522,9 +522,42 @@ static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
{
- wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor",
- priv->wpa_s->ifname);
- eloop_wait_for_read_sock(priv->sock);
+ char buf[256];
+ int res;
+ struct sockaddr_un from;
+ socklen_t fromlen = sizeof(from);
+
+ for (;;) {
+ wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to "
+ "attach", priv->wpa_s->ifname);
+ eloop_wait_for_read_sock(priv->sock);
+
+ res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0,
+ (struct sockaddr *) &from, &fromlen);
+ if (res < 0) {
+ perror("recvfrom(ctrl_iface)");
+ continue;
+ }
+ buf[res] = '\0';
+
+ if (os_strcmp(buf, "ATTACH") == 0) {
+ /* handle ATTACH signal of first monitor interface */
+ if (!wpa_supplicant_ctrl_iface_attach(priv, &from,
+ fromlen)) {
+ sendto(priv->sock, "OK\n", 3, 0,
+ (struct sockaddr *) &from, fromlen);
+ /* OK to continue */
+ return;
+ } else {
+ sendto(priv->sock, "FAIL\n", 5, 0,
+ (struct sockaddr *) &from, fromlen);
+ }
+ } else {
+ /* return FAIL for all other signals */
+ sendto(priv->sock, "FAIL\n", 5, 0,
+ (struct sockaddr *) &from, fromlen);
+ }
+ }
}
diff --git a/contrib/wpa_supplicant/dbus-wpa_supplicant.conf b/contrib/wpa_supplicant/dbus-wpa_supplicant.conf
index 1622af579030..51a29e3a89c0 100644
--- a/contrib/wpa_supplicant/dbus-wpa_supplicant.conf
+++ b/contrib/wpa_supplicant/dbus-wpa_supplicant.conf
@@ -8,10 +8,6 @@
<allow send_destination="fi.epitest.hostap.WPASupplicant"/>
<allow send_interface="fi.epitest.hostap.WPASupplicant"/>
</policy>
- <policy at_console="true">
- <allow send_destination="fi.epitest.hostap.WPASupplicant"/>
- <allow send_interface="fi.epitest.hostap.WPASupplicant"/>
- </policy>
<policy context="default">
<deny own="fi.epitest.hostap.WPASupplicant"/>
<deny send_destination="fi.epitest.hostap.WPASupplicant"/>
diff --git a/contrib/wpa_supplicant/dbus-wpa_supplicant.service b/contrib/wpa_supplicant/dbus-wpa_supplicant.service
new file mode 100644
index 000000000000..a9ce1ecda63f
--- /dev/null
+++ b/contrib/wpa_supplicant/dbus-wpa_supplicant.service
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=fi.epitest.hostap.WPASupplicant
+Exec=/sbin/wpa_supplicant -u
+User=root
diff --git a/contrib/wpa_supplicant/defconfig b/contrib/wpa_supplicant/defconfig
index d9526efd73f4..52165988a883 100644
--- a/contrib/wpa_supplicant/defconfig
+++ b/contrib/wpa_supplicant/defconfig
@@ -209,7 +209,9 @@ CONFIG_CTRL_IFACE=y
#CONFIG_NO_AES_EXTRAS=y
# Select configuration backend:
-# file = text file (e.g., wpa_supplicant.conf)
+# file = text file (e.g., wpa_supplicant.conf; note: the configuration file
+# path is given on command line, not here; this option is just used to
+# select the backend that allows configuration files to be used)
# winreg = Windows registry (see win_example.reg for an example)
CONFIG_BACKEND=file
@@ -316,3 +318,6 @@ CONFIG_PEERKEY=y
# wireless-dev.git tree).
#WIRELESS_DEV=/usr/src/wireless-dev
#CFLAGS += -I$(WIRELESS_DEV)/net/mac80211
+
+# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
+#CONFIG_DEBUG_FILE=y
diff --git a/contrib/wpa_supplicant/doc/ctrl_iface.doxygen b/contrib/wpa_supplicant/doc/ctrl_iface.doxygen
index f9e7d0e73b44..d64978664e14 100644
--- a/contrib/wpa_supplicant/doc/ctrl_iface.doxygen
+++ b/contrib/wpa_supplicant/doc/ctrl_iface.doxygen
@@ -203,6 +203,12 @@ IEEE 802.1X EAPOL state machine logoff.
Force reassociation.
+\subsection ctrl_iface_RECONNECT RECONNECT
+
+Connect if disconnected (i.e., like \c REASSOCIATE, but only connect
+if in disconnected state).
+
+
\subsection ctrl_iface_PREAUTH PREAUTH <BSSID>
Start pre-authentication with the given BSSID.
@@ -255,7 +261,8 @@ network id / ssid / bssid / flags
\subsection ctrl_iface_DISCONNECT DISCONNECT
-Disconnect and wait for \c REASSOCIATE command before connecting.
+Disconnect and wait for \c REASSOCIATE or \c RECONNECT command before
+connecting.
\subsection ctrl_iface_SCAN SCAN
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_background.8 b/contrib/wpa_supplicant/doc/docbook/wpa_background.8
index 7f9d637ba771..6244529e69a9 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_background.8
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_background.8
@@ -3,7 +3,7 @@
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "WPA_BACKGROUND" "8" "28 May 2007" "" ""
+.TH "WPA_BACKGROUND" "8" "19 February 2008" "" ""
.SH NAME
wpa_background \- Background information on Wi-Fi Protected Access and IEEE 802.11i
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_cli.8 b/contrib/wpa_supplicant/doc/docbook/wpa_cli.8
index 6d32260e17ba..0865264a69a2 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_cli.8
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_cli.8
@@ -3,7 +3,7 @@
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "WPA_CLI" "8" "28 May 2007" "" ""
+.TH "WPA_CLI" "8" "19 February 2008" "" ""
.SH NAME
wpa_cli \- WPA command line client
@@ -112,7 +112,7 @@ Run as a daemon in the background.
Run in daemon mode executing the action file
based on events from wpa_supplicant. The specified file will
be executed with the first argument set to interface name and
-second to "CONNECT" or "DISCONNECT" depending on the event.
+second to "CONNECTED" or "DISCONNECTED" depending on the event.
This can be used to execute networking tools required to configure
the interface.
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_cli.sgml b/contrib/wpa_supplicant/doc/docbook/wpa_cli.sgml
index 140c365b9242..8430599efb73 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_cli.sgml
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_cli.sgml
@@ -140,7 +140,7 @@ CTRL-REQ-OTP-2:Challenge 1235663 needed for SSID foobar
<listitem><para>Run in daemon mode executing the action file
based on events from wpa_supplicant. The specified file will
be executed with the first argument set to interface name and
- second to "CONNECT" or "DISCONNECT" depending on the event.
+ second to "CONNECTED" or "DISCONNECTED" depending on the event.
This can be used to execute networking tools required to configure
the interface.</para>
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_passphrase.8 b/contrib/wpa_supplicant/doc/docbook/wpa_passphrase.8
index c883777fc486..a0f5c7039863 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_passphrase.8
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_passphrase.8
@@ -3,7 +3,7 @@
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "WPA_PASSPHRASE" "8" "28 May 2007" "" ""
+.TH "WPA_PASSPHRASE" "8" "19 February 2008" "" ""
.SH NAME
wpa_passphrase \- Generate a WPA PSK from an ASCII passphrase for a SSID
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.8 b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.8
index 502000d3754c..1a5697d84229 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.8
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.8
@@ -3,13 +3,13 @@
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "WPA_SUPPLICANT" "8" "28 May 2007" "" ""
+.TH "WPA_SUPPLICANT" "8" "19 February 2008" "" ""
.SH NAME
wpa_supplicant \- Wi-Fi Protected Access client and IEEE 802.1X supplicant
.SH SYNOPSIS
-\fBwpa_supplicant\fR [ \fB-BddehLqqvw\fR ] [ \fB-i\fIifname\fB\fR ] [ \fB-c\fIconfig file\fB\fR ] [ \fB-D\fIdriver\fB\fR ] [ \fB-P\fIPID_file\fB\fR ]
+\fBwpa_supplicant\fR [ \fB-BddfhKLqqtuvwW\fR ] [ \fB-i\fIifname\fB\fR ] [ \fB-c\fIconfig file\fB\fR ] [ \fB-D\fIdriver\fB\fR ] [ \fB-P\fIPID_file\fB\fR ] [ \fB-f\fIoutput file\fB\fR ]
.SH "OVERVIEW"
.PP
@@ -272,6 +272,9 @@ Path to global ctrl_interface socket.
\fB-D driver\fR
Driver to use. See the available options below.
.TP
+\fB-f output file\fR
+Log output to specified file instead of stdout.
+.TP
\fB-d\fR
Increase debugging verbosity (-dd even more).
.TP
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5 b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5
index c7e4c6fa744c..efe17cc8762b 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5
@@ -3,7 +3,7 @@
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
.\" Please send any bug reports, improvements, comments, patches,
.\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "WPA_SUPPLICANT.CONF" "5" "28 May 2007" "" ""
+.TH "WPA_SUPPLICANT.CONF" "5" "19 February 2008" "" ""
.SH NAME
wpa_supplicant.conf \- configuration file for wpa_supplicant
diff --git a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
index d19e5463a930..b46d13c1f9ef 100644
--- a/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+++ b/contrib/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
@@ -12,11 +12,12 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>wpa_supplicant</command>
- <arg>-BddehLqqvw</arg>
+ <arg>-BddfhKLqqtuvwW</arg>
<arg>-i<replaceable>ifname</replaceable></arg>
<arg>-c<replaceable>config file</replaceable></arg>
<arg>-D<replaceable>driver</replaceable></arg>
<arg>-P<replaceable>PID_file</replaceable></arg>
+ <arg>-f<replaceable>output file</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
@@ -376,6 +377,13 @@
</varlistentry>
<varlistentry>
+ <term>-f output file</term>
+ <listitem>
+ <para>Log output to specified file instead of stdout.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-d</term>
<listitem>
<para>Increase debugging verbosity (-dd even more).</para>
diff --git a/contrib/wpa_supplicant/driver_ndis.c b/contrib/wpa_supplicant/driver_ndis.c
index 16e051e94a3e..570b4ca1a183 100644
--- a/contrib/wpa_supplicant/driver_ndis.c
+++ b/contrib/wpa_supplicant/driver_ndis.c
@@ -725,6 +725,7 @@ static int wpa_driver_ndis_scan(void *priv, const u8 *ssid, size_t ssid_len)
}
res = ndis_set_oid(drv, OID_802_11_BSSID_LIST_SCAN, " ", 4);
+ eloop_cancel_timeout(wpa_driver_ndis_scan_timeout, drv, drv->ctx);
eloop_register_timeout(7, 0, wpa_driver_ndis_scan_timeout, drv,
drv->ctx);
return res;
@@ -1169,7 +1170,6 @@ static int wpa_driver_ndis_remove_pmkid(void *priv, const u8 *bssid,
entry = drv->pmkid;
prev = NULL;
- drv->pmkid = NULL;
while (entry) {
if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0 &&
os_memcmp(entry->pmkid, pmkid, 16) == 0) {
diff --git a/contrib/wpa_supplicant/eap_gpsk.c b/contrib/wpa_supplicant/eap_gpsk.c
index 1366d4335986..81b03ede5991 100644
--- a/contrib/wpa_supplicant/eap_gpsk.c
+++ b/contrib/wpa_supplicant/eap_gpsk.c
@@ -1,5 +1,5 @@
/*
- * EAP peer method: EAP-GPSK (draft-ietf-emu-eap-gpsk-03.txt)
+ * EAP peer method: EAP-GPSK (draft-ietf-emu-eap-gpsk-08.txt)
* Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
@@ -22,7 +22,7 @@
struct eap_gpsk_data {
enum { GPSK_1, GPSK_3, SUCCESS, FAILURE } state;
u8 rand_server[EAP_GPSK_RAND_LEN];
- u8 rand_client[EAP_GPSK_RAND_LEN];
+ u8 rand_peer[EAP_GPSK_RAND_LEN];
u8 msk[EAP_MSK_LEN];
u8 emsk[EAP_EMSK_LEN];
u8 sk[EAP_GPSK_MAX_SK_LEN];
@@ -31,8 +31,8 @@ struct eap_gpsk_data {
size_t pk_len;
u8 session_id;
int session_id_set;
- u8 *id_client;
- size_t id_client_len;
+ u8 *id_peer;
+ size_t id_peer_len;
u8 *id_server;
size_t id_server_len;
int vendor; /* CSuite/Specifier */
@@ -42,6 +42,13 @@ struct eap_gpsk_data {
};
+static u8 * eap_gpsk_send_gpsk_2(struct eap_gpsk_data *data, u8 identifier,
+ const u8 *csuite_list, size_t csuite_list_len,
+ size_t *respDataLen);
+static u8 * eap_gpsk_send_gpsk_4(struct eap_gpsk_data *data, u8 identifier,
+ size_t *respDataLen);
+
+
#ifndef CONFIG_NO_STDOUT_DEBUG
static const char * eap_gpsk_state_txt(int state)
{
@@ -94,13 +101,13 @@ static void * eap_gpsk_init(struct eap_sm *sm)
data->state = GPSK_1;
if (config->nai) {
- data->id_client = os_malloc(config->nai_len);
- if (data->id_client == NULL) {
+ data->id_peer = os_malloc(config->nai_len);
+ if (data->id_peer == NULL) {
eap_gpsk_deinit(sm, data);
return NULL;
}
- os_memcpy(data->id_client, config->nai, config->nai_len);
- data->id_client_len = config->nai_len;
+ os_memcpy(data->id_peer, config->nai, config->nai_len);
+ data->id_peer_len = config->nai_len;
}
data->psk = os_malloc(config->eappsk_len);
@@ -119,38 +126,16 @@ static void eap_gpsk_deinit(struct eap_sm *sm, void *priv)
{
struct eap_gpsk_data *data = priv;
os_free(data->id_server);
- os_free(data->id_client);
+ os_free(data->id_peer);
os_free(data->psk);
os_free(data);
}
-static u8 * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
- struct eap_gpsk_data *data,
- struct eap_method_ret *ret,
- const u8 *reqData, size_t reqDataLen,
- const u8 *payload, size_t payload_len,
- size_t *respDataLen)
+const u8 * eap_gpsk_process_id_server(struct eap_gpsk_data *data,
+ const u8 *pos, const u8 *end)
{
- size_t len, csuite_list_len, miclen;
- struct eap_hdr *resp;
- u8 *rpos, *start;
- const u8 *csuite_list, *pos, *end;
- const struct eap_hdr *req;
- struct eap_gpsk_csuite *csuite;
u16 alen;
- int i, count;
-
- if (data->state != GPSK_1) {
- ret->ignore = TRUE;
- return NULL;
- }
-
- wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Request/GPSK-1");
-
- req = (const struct eap_hdr *) reqData;
- pos = payload;
- end = payload + payload_len;
if (end - pos < 2) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short GPSK-1 packet");
@@ -174,6 +159,16 @@ static u8 * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
data->id_server, data->id_server_len);
pos += alen;
+ return pos;
+}
+
+
+const u8 * eap_gpsk_process_rand_server(struct eap_gpsk_data *data,
+ const u8 *pos, const u8 *end)
+{
+ if (pos == NULL)
+ return NULL;
+
if (end - pos < EAP_GPSK_RAND_LEN) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Server overflow");
return NULL;
@@ -183,32 +178,26 @@ static u8 * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
data->rand_server, EAP_GPSK_RAND_LEN);
pos += EAP_GPSK_RAND_LEN;
- if (end - pos < 2) {
- wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short GPSK-1 packet");
- return NULL;
- }
- csuite_list_len = WPA_GET_BE16(pos);
- pos += 2;
- if (end - pos < (int) csuite_list_len) {
- wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_List overflow");
- return NULL;
- }
- csuite_list = pos;
+ return pos;
+}
+
+
+static int eap_gpsk_select_csuite(struct eap_sm *sm,
+ struct eap_gpsk_data *data,
+ const u8 *csuite_list,
+ size_t csuite_list_len)
+{
+ struct eap_gpsk_csuite *csuite;
+ int i, count;
- if (csuite_list_len == 0 ||
- csuite_list_len % sizeof(struct eap_gpsk_csuite)) {
- wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid CSuite_List len %d",
- csuite_list_len);
- return NULL;
- }
count = csuite_list_len / sizeof(struct eap_gpsk_csuite);
data->vendor = EAP_GPSK_VENDOR_IETF;
data->specifier = EAP_GPSK_CIPHER_RESERVED;
csuite = (struct eap_gpsk_csuite *) csuite_list;
for (i = 0; i < count; i++) {
int vendor, specifier;
- vendor = WPA_GET_BE24(csuite->vendor);
- specifier = WPA_GET_BE24(csuite->specifier);
+ vendor = WPA_GET_BE32(csuite->vendor);
+ specifier = WPA_GET_BE16(csuite->specifier);
wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite[%d]: %d:%d",
i, vendor, specifier);
if (data->vendor == EAP_GPSK_VENDOR_IETF &&
@@ -223,34 +212,122 @@ static u8 * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
data->specifier == EAP_GPSK_CIPHER_RESERVED) {
wpa_msg(sm->msg_ctx, MSG_INFO, "EAP-GPSK: No supported "
"ciphersuite found");
- eap_gpsk_state(data, FAILURE);
- return NULL;
+ return -1;
}
wpa_printf(MSG_DEBUG, "EAP-GPSK: Selected ciphersuite %d:%d",
data->vendor, data->specifier);
+ return 0;
+}
+
+
+const u8 * eap_gpsk_process_csuite_list(struct eap_sm *sm,
+ struct eap_gpsk_data *data,
+ const u8 **list, size_t *list_len,
+ const u8 *pos, const u8 *end)
+{
+ if (pos == NULL)
+ return NULL;
+
+ if (end - pos < 2) {
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short GPSK-1 packet");
+ return NULL;
+ }
+ *list_len = WPA_GET_BE16(pos);
+ pos += 2;
+ if (end - pos < (int) *list_len) {
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_List overflow");
+ return NULL;
+ }
+ if (*list_len == 0 || (*list_len % sizeof(struct eap_gpsk_csuite))) {
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid CSuite_List len %d",
+ *list_len);
+ return NULL;
+ }
+ *list = pos;
+ pos += *list_len;
+
+ if (eap_gpsk_select_csuite(sm, data, *list, *list_len) < 0)
+ return NULL;
+
+ return pos;
+}
+
+
+static u8 * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
+ struct eap_gpsk_data *data,
+ struct eap_method_ret *ret,
+ const u8 *reqData, size_t reqDataLen,
+ const u8 *payload, size_t payload_len,
+ size_t *respDataLen)
+{
+ size_t csuite_list_len;
+ const u8 *csuite_list, *pos, *end;
+ const struct eap_hdr *req;
+ u8 *resp;
+
+ if (data->state != GPSK_1) {
+ ret->ignore = TRUE;
+ return NULL;
+ }
+
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Request/GPSK-1");
+
+ end = payload + payload_len;
+
+ pos = eap_gpsk_process_id_server(data, payload, end);
+ pos = eap_gpsk_process_rand_server(data, pos, end);
+ pos = eap_gpsk_process_csuite_list(sm, data, &csuite_list,
+ &csuite_list_len, pos, end);
+ if (pos == NULL) {
+ eap_gpsk_state(data, FAILURE);
+ return NULL;
+ }
+
+ req = (const struct eap_hdr *) reqData;
+ resp = eap_gpsk_send_gpsk_2(data, req->identifier,
+ csuite_list, csuite_list_len,
+ respDataLen);
+ if (resp == NULL)
+ return NULL;
+
+ eap_gpsk_state(data, GPSK_3);
+
+ return (u8 *) resp;
+}
+
+
+static u8 * eap_gpsk_send_gpsk_2(struct eap_gpsk_data *data, u8 identifier,
+ const u8 *csuite_list, size_t csuite_list_len,
+ size_t *respDataLen)
+{
+ struct eap_hdr *resp;
+ size_t len, miclen;
+ u8 *rpos, *start;
+ struct eap_gpsk_csuite *csuite;
+
wpa_printf(MSG_DEBUG, "EAP-GPSK: Sending Response/GPSK-2");
miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
- len = 1 + 2 + data->id_client_len + 2 + data->id_server_len +
+ len = 1 + 2 + data->id_peer_len + 2 + data->id_server_len +
2 * EAP_GPSK_RAND_LEN + 2 + csuite_list_len +
sizeof(struct eap_gpsk_csuite) + 2 + miclen;
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respDataLen, len,
- EAP_CODE_RESPONSE, req->identifier, &rpos);
+ EAP_CODE_RESPONSE, identifier, &rpos);
if (resp == NULL)
return NULL;
*rpos++ = EAP_GPSK_OPCODE_GPSK_2;
start = rpos;
- wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Client",
- data->id_client, data->id_client_len);
- WPA_PUT_BE16(rpos, data->id_client_len);
+ wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Peer",
+ data->id_peer, data->id_peer_len);
+ WPA_PUT_BE16(rpos, data->id_peer_len);
rpos += 2;
- if (data->id_client)
- os_memcpy(rpos, data->id_client, data->id_client_len);
- rpos += data->id_client_len;
+ if (data->id_peer)
+ os_memcpy(rpos, data->id_peer, data->id_peer_len);
+ rpos += data->id_peer_len;
WPA_PUT_BE16(rpos, data->id_server_len);
rpos += 2;
@@ -258,16 +335,16 @@ static u8 * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
os_memcpy(rpos, data->id_server, data->id_server_len);
rpos += data->id_server_len;
- if (os_get_random(data->rand_client, EAP_GPSK_RAND_LEN)) {
+ if (os_get_random(data->rand_peer, EAP_GPSK_RAND_LEN)) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to get random data "
- "for RAND_Client");
+ "for RAND_Peer");
eap_gpsk_state(data, FAILURE);
os_free(resp);
return NULL;
}
- wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Client",
- data->rand_client, EAP_GPSK_RAND_LEN);
- os_memcpy(rpos, data->rand_client, EAP_GPSK_RAND_LEN);
+ wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer",
+ data->rand_peer, EAP_GPSK_RAND_LEN);
+ os_memcpy(rpos, data->rand_peer, EAP_GPSK_RAND_LEN);
rpos += EAP_GPSK_RAND_LEN;
os_memcpy(rpos, data->rand_server, EAP_GPSK_RAND_LEN);
@@ -279,14 +356,14 @@ static u8 * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
rpos += csuite_list_len;
csuite = (struct eap_gpsk_csuite *) rpos;
- WPA_PUT_BE24(csuite->vendor, data->vendor);
- WPA_PUT_BE24(csuite->specifier, data->specifier);
+ WPA_PUT_BE32(csuite->vendor, data->vendor);
+ WPA_PUT_BE16(csuite->specifier, data->specifier);
rpos = (u8 *) (csuite + 1);
if (eap_gpsk_derive_keys(data->psk, data->psk_len,
data->vendor, data->specifier,
- data->rand_client, data->rand_server,
- data->id_client, data->id_client_len,
+ data->rand_peer, data->rand_server,
+ data->id_peer, data->id_peer_len,
data->id_server, data->id_server_len,
data->msk, data->emsk,
data->sk, &data->sk_len,
@@ -309,53 +386,25 @@ static u8 * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
return NULL;
}
- eap_gpsk_state(data, GPSK_3);
-
return (u8 *) resp;
}
-static u8 * eap_gpsk_process_gpsk_3(struct eap_sm *sm,
- struct eap_gpsk_data *data,
- struct eap_method_ret *ret,
- const u8 *reqData, size_t reqDataLen,
- const u8 *payload, size_t payload_len,
- size_t *respDataLen)
+const u8 * eap_gpsk_validate_rand(struct eap_gpsk_data *data, const u8 *pos,
+ const u8 *end)
{
- size_t len, miclen;
- struct eap_hdr *resp;
- u8 *rpos, *start;
- const struct eap_hdr *req;
- const u8 *pos, *end;
- u16 alen;
- int vendor, specifier;
- const struct eap_gpsk_csuite *csuite;
- u8 mic[EAP_GPSK_MAX_MIC_LEN];
-
- if (data->state != GPSK_3) {
- ret->ignore = TRUE;
- return NULL;
- }
-
- wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Request/GPSK-3");
-
- req = (const struct eap_hdr *) reqData;
- pos = payload;
- end = payload + payload_len;
-
if (end - pos < EAP_GPSK_RAND_LEN) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for "
- "RAND_Client");
+ "RAND_Peer");
return NULL;
}
- if (os_memcmp(pos, data->rand_client, EAP_GPSK_RAND_LEN) != 0) {
- wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Client in GPSK-2 and "
+ if (os_memcmp(pos, data->rand_peer, EAP_GPSK_RAND_LEN) != 0) {
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Peer in GPSK-2 and "
"GPSK-3 did not match");
- wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Client in GPSK-2",
- data->rand_client, EAP_GPSK_RAND_LEN);
- wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Client in GPSK-3",
+ wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer in GPSK-2",
+ data->rand_peer, EAP_GPSK_RAND_LEN);
+ wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer in GPSK-3",
pos, EAP_GPSK_RAND_LEN);
- eap_gpsk_state(data, FAILURE);
return NULL;
}
pos += EAP_GPSK_RAND_LEN;
@@ -372,32 +421,93 @@ static u8 * eap_gpsk_process_gpsk_3(struct eap_sm *sm,
data->rand_server, EAP_GPSK_RAND_LEN);
wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-3",
pos, EAP_GPSK_RAND_LEN);
- eap_gpsk_state(data, FAILURE);
return NULL;
}
pos += EAP_GPSK_RAND_LEN;
+ return pos;
+}
+
+
+const u8 * eap_gpsk_validate_id_server(struct eap_gpsk_data *data,
+ const u8 *pos, const u8 *end)
+{
+ size_t len;
+
+ if (pos == NULL)
+ return NULL;
+
+ if (end - pos < (int) 2) {
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for "
+ "length(ID_Server)");
+ return NULL;
+ }
+
+ len = WPA_GET_BE16(pos);
+ pos += 2;
+
+ if (end - pos < (int) len) {
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for "
+ "ID_Server");
+ return NULL;
+ }
+
+ if (len != data->id_server_len ||
+ os_memcmp(pos, data->id_server, len) != 0) {
+ wpa_printf(MSG_INFO, "EAP-GPSK: ID_Server did not match with "
+ "the one used in GPSK-1");
+ wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-1",
+ data->id_server, data->id_server_len);
+ wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-3",
+ pos, len);
+ }
+
+ pos += len;
+
+ return pos;
+}
+
+
+const u8 * eap_gpsk_validate_csuite(struct eap_gpsk_data *data, const u8 *pos,
+ const u8 *end)
+{
+ int vendor, specifier;
+ const struct eap_gpsk_csuite *csuite;
+
+ if (pos == NULL)
+ return NULL;
+
if (end - pos < (int) sizeof(*csuite)) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for "
"CSuite_Sel");
return NULL;
}
csuite = (const struct eap_gpsk_csuite *) pos;
- vendor = WPA_GET_BE24(csuite->vendor);
- specifier = WPA_GET_BE24(csuite->specifier);
+ vendor = WPA_GET_BE32(csuite->vendor);
+ specifier = WPA_GET_BE16(csuite->specifier);
pos += sizeof(*csuite);
if (vendor != data->vendor || specifier != data->specifier) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_Sel (%d:%d) does not "
"match with the one sent in GPSK-2 (%d:%d)",
vendor, specifier, data->vendor, data->specifier);
- eap_gpsk_state(data, FAILURE);
return NULL;
}
+ return pos;
+}
+
+
+const u8 * eap_gpsk_validate_pd_payload_2(struct eap_gpsk_data *data,
+ const u8 *pos, const u8 *end)
+{
+ u16 alen;
+
+ if (pos == NULL)
+ return NULL;
+
if (end - pos < 2) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for "
"PD_Payload_2 length");
- eap_gpsk_state(data, FAILURE);
return NULL;
}
alen = WPA_GET_BE16(pos);
@@ -405,45 +515,110 @@ static u8 * eap_gpsk_process_gpsk_3(struct eap_sm *sm,
if (end - pos < alen) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for "
"%d-octet PD_Payload_2", alen);
- eap_gpsk_state(data, FAILURE);
return NULL;
}
wpa_hexdump(MSG_DEBUG, "EAP-GPSK: PD_Payload_2", pos, alen);
pos += alen;
+
+ return pos;
+}
+
+
+const u8 * eap_gpsk_validate_gpsk_3_mic(struct eap_gpsk_data *data,
+ const u8 *payload,
+ const u8 *pos, const u8 *end)
+{
+ size_t miclen;
+ u8 mic[EAP_GPSK_MAX_MIC_LEN];
+
+ if (pos == NULL)
+ return NULL;
+
miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
if (end - pos < (int) miclen) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC "
"(left=%d miclen=%d)", end - pos, miclen);
- eap_gpsk_state(data, FAILURE);
return NULL;
}
if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
data->specifier, payload, pos - payload, mic)
< 0) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to compute MIC");
- eap_gpsk_state(data, FAILURE);
return NULL;
}
if (os_memcmp(mic, pos, miclen) != 0) {
wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-3");
wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen);
wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen);
- eap_gpsk_state(data, FAILURE);
return NULL;
}
pos += miclen;
+ return pos;
+}
+
+
+static u8 * eap_gpsk_process_gpsk_3(struct eap_sm *sm,
+ struct eap_gpsk_data *data,
+ struct eap_method_ret *ret,
+ const u8 *reqData, size_t reqDataLen,
+ const u8 *payload, size_t payload_len,
+ size_t *respDataLen)
+{
+ u8 *resp;
+ const struct eap_hdr *req;
+ const u8 *pos, *end;
+
+ if (data->state != GPSK_3) {
+ ret->ignore = TRUE;
+ return NULL;
+ }
+
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Request/GPSK-3");
+
+ end = payload + payload_len;
+
+ pos = eap_gpsk_validate_rand(data, payload, end);
+ pos = eap_gpsk_validate_id_server(data, pos, end);
+ pos = eap_gpsk_validate_csuite(data, pos, end);
+ pos = eap_gpsk_validate_pd_payload_2(data, pos, end);
+ pos = eap_gpsk_validate_gpsk_3_mic(data, payload, pos, end);
+
+ if (pos == NULL) {
+ eap_gpsk_state(data, FAILURE);
+ return NULL;
+ }
if (pos != end) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %d bytes of extra "
"data in the end of GPSK-2", end - pos);
}
+ req = (const struct eap_hdr *) reqData;
+ resp = eap_gpsk_send_gpsk_4(data, req->identifier, respDataLen);
+ if (resp == NULL)
+ return NULL;
+
+ eap_gpsk_state(data, SUCCESS);
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_UNCOND_SUCC;
+
+ return (u8 *) resp;
+}
+
+
+static u8 * eap_gpsk_send_gpsk_4(struct eap_gpsk_data *data, u8 identifier,
+ size_t *respDataLen)
+{
+ struct eap_hdr *resp;
+ u8 *rpos, *start;
+ size_t len;
+
wpa_printf(MSG_DEBUG, "EAP-GPSK: Sending Response/GPSK-4");
- len = 1 + 2 + miclen;
+ len = 1 + 2 + eap_gpsk_mic_len(data->vendor, data->specifier);
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respDataLen, len,
- EAP_CODE_RESPONSE, req->identifier, &rpos);
+ EAP_CODE_RESPONSE, identifier, &rpos);
if (resp == NULL)
return NULL;
@@ -462,10 +637,6 @@ static u8 * eap_gpsk_process_gpsk_3(struct eap_sm *sm,
return NULL;
}
- eap_gpsk_state(data, SUCCESS);
- ret->methodState = METHOD_DONE;
- ret->decision = DECISION_UNCOND_SUCC;
-
return (u8 *) resp;
}
diff --git a/contrib/wpa_supplicant/eap_gpsk_common.c b/contrib/wpa_supplicant/eap_gpsk_common.c
index a72b5f3da15f..7422fa6c48f9 100644
--- a/contrib/wpa_supplicant/eap_gpsk_common.c
+++ b/contrib/wpa_supplicant/eap_gpsk_common.c
@@ -18,8 +18,9 @@
#include "eap_defs.h"
#include "aes_wrap.h"
#include "crypto.h"
-#include "sha1.h"
+#ifdef EAP_GPSK_SHA256
#include "sha256.h"
+#endif /* EAP_GPSK_SHA256 */
#include "eap_gpsk_common.h"
@@ -43,31 +44,29 @@ int eap_gpsk_supported_ciphersuite(int vendor, int specifier)
}
-static int eap_gpsk_gkdf(const u8 *psk /* Y */, size_t psk_len,
- const u8 *data /* Z */, size_t data_len,
- u8 *buf, size_t len /* X */)
+static int eap_gpsk_gkdf_cmac(const u8 *psk /* Y */,
+ const u8 *data /* Z */, size_t data_len,
+ u8 *buf, size_t len /* X */)
{
u8 *opos;
size_t i, n, hashlen, left, clen;
- u8 ibuf[2], hash[SHA1_MAC_LEN];
- const u8 *addr[3];
- size_t vlen[3];
+ u8 ibuf[2], hash[16];
+ const u8 *addr[2];
+ size_t vlen[2];
- hashlen = SHA1_MAC_LEN;
- /* M_i = Hash-Function (i || Y || Z); */
+ hashlen = sizeof(hash);
+ /* M_i = MAC_Y (i || Z); (MAC = AES-CMAC-128) */
addr[0] = ibuf;
vlen[0] = sizeof(ibuf);
- addr[1] = psk;
- vlen[1] = psk_len;
- addr[2] = data;
- vlen[2] = data_len;
+ addr[1] = data;
+ vlen[1] = data_len;
opos = buf;
left = len;
n = (len + hashlen - 1) / hashlen;
for (i = 1; i <= n; i++) {
WPA_PUT_BE16(ibuf, i);
- sha1_vector(3, addr, vlen, hash);
+ omac1_aes_128_vector(psk, 2, addr, vlen, hash);
clen = left > hashlen ? hashlen : left;
os_memcpy(opos, hash, clen);
opos += clen;
@@ -78,112 +77,30 @@ static int eap_gpsk_gkdf(const u8 *psk /* Y */, size_t psk_len,
}
-static int eap_gpsk_derive_keys_aes(const u8 *psk, size_t psk_len,
- const u8 *seed, size_t seed_len,
- u8 *msk, u8 *emsk, u8 *sk, size_t *sk_len,
- u8 *pk, size_t *pk_len)
-{
-#define EAP_GPSK_SK_LEN_AES 16
-#define EAP_GPSK_PK_LEN_AES 16
- u8 zero_string[1], mk[32], *pos, *data;
- u8 kdf_out[EAP_MSK_LEN + EAP_EMSK_LEN + EAP_GPSK_SK_LEN_AES +
- EAP_GPSK_PK_LEN_AES];
- size_t data_len;
-
- /*
- * inputString = RAND_Client || ID_Client || RAND_Server || ID_Server
- * (= seed)
- * KS = 16, PL = psk_len, CSuite_Sel = 0x000000 0x000001
- * MK = GKDF-32 (0x00, PL || PSK || CSuite_Sel || inputString)
- * MSK = GKDF-160 (MK, inputString)[0..63]
- * EMSK = GKDF-160 (MK, inputString)[64..127]
- * SK = GKDF-160 (MK, inputString)[128..143]
- * PK = GKDF-160 (MK, inputString)[144..159]
- * MID = GKDF-16(0x00, "Method ID" || EAP_Method_Type || CSuite_Sel ||
- * inputString)
- * Hash-Function = SHA-1 (see [RFC3174])
- * hashlen = 20 octets (160 bits)
- */
-
- os_memset(zero_string, 0, sizeof(zero_string));
-
- data_len = 2 + psk_len + 6 + seed_len;
- data = os_malloc(data_len);
- if (data == NULL)
- return -1;
- pos = data;
- WPA_PUT_BE16(pos, psk_len);
- pos += 2;
- os_memcpy(pos, psk, psk_len);
- pos += psk_len;
- WPA_PUT_BE24(pos, 0); /* CSuite/Vendor = IETF */
- pos += 3;
- WPA_PUT_BE24(pos, EAP_GPSK_CIPHER_AES); /* CSuite/Specifier */
- pos += 3;
- os_memcpy(pos, seed, seed_len); /* inputString */
- wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: Data to MK derivation (AES)",
- data, data_len);
-
- if (eap_gpsk_gkdf(zero_string, sizeof(zero_string), data, data_len,
- mk, sizeof(mk)) < 0) {
- os_free(data);
- return -1;
- }
- os_free(data);
- wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: MK", mk, sizeof(mk));
-
- if (eap_gpsk_gkdf(mk, sizeof(mk), seed, seed_len,
- kdf_out, sizeof(kdf_out)) < 0)
- return -1;
-
- pos = kdf_out;
- wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: MSK", pos, EAP_MSK_LEN);
- os_memcpy(msk, pos, EAP_MSK_LEN);
- pos += EAP_MSK_LEN;
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: EMSK", pos, EAP_EMSK_LEN);
- os_memcpy(emsk, pos, EAP_EMSK_LEN);
- pos += EAP_EMSK_LEN;
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: SK", pos, EAP_GPSK_SK_LEN_AES);
- os_memcpy(sk, pos, EAP_GPSK_SK_LEN_AES);
- *sk_len = EAP_GPSK_SK_LEN_AES;
- pos += EAP_GPSK_SK_LEN_AES;
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: PK", pos, EAP_GPSK_PK_LEN_AES);
- os_memcpy(pk, pos, EAP_GPSK_PK_LEN_AES);
- *pk_len = EAP_GPSK_PK_LEN_AES;
-
- return 0;
-}
-
-
#ifdef EAP_GPSK_SHA256
-static int eap_gpsk_gkdf_sha256(const u8 *psk /* Y */, size_t psk_len,
+static int eap_gpsk_gkdf_sha256(const u8 *psk /* Y */,
const u8 *data /* Z */, size_t data_len,
u8 *buf, size_t len /* X */)
{
u8 *opos;
size_t i, n, hashlen, left, clen;
u8 ibuf[2], hash[SHA256_MAC_LEN];
- const u8 *addr[3];
- size_t vlen[3];
+ const u8 *addr[2];
+ size_t vlen[2];
hashlen = SHA256_MAC_LEN;
- /* M_i = Hash-Function (i || Y || Z); */
+ /* M_i = MAC_Y (i || Z); (MAC = HMAC-SHA256) */
addr[0] = ibuf;
vlen[0] = sizeof(ibuf);
- addr[1] = psk;
- vlen[1] = psk_len;
- addr[2] = data;
- vlen[2] = data_len;
+ addr[1] = data;
+ vlen[1] = data_len;
opos = buf;
left = len;
n = (len + hashlen - 1) / hashlen;
for (i = 1; i <= n; i++) {
WPA_PUT_BE16(ibuf, i);
- sha256_vector(3, addr, vlen, hash);
+ hmac_sha256_vector(psk, 32, 2, addr, vlen, hash);
clen = left > hashlen ? hashlen : left;
os_memcpy(opos, hash, clen);
opos += clen;
@@ -192,37 +109,40 @@ static int eap_gpsk_gkdf_sha256(const u8 *psk /* Y */, size_t psk_len,
return 0;
}
+#endif /* EAP_GPSK_SHA256 */
-static int eap_gpsk_derive_keys_sha256(const u8 *psk, size_t psk_len,
+static int eap_gpsk_derive_keys_helper(u32 csuite_specifier,
+ u8 *kdf_out, size_t kdf_out_len,
+ const u8 *psk, size_t psk_len,
const u8 *seed, size_t seed_len,
u8 *msk, u8 *emsk,
- u8 *sk, size_t *sk_len,
- u8 *pk, size_t *pk_len)
+ u8 *sk, size_t sk_len,
+ u8 *pk, size_t pk_len)
{
-#define EAP_GPSK_SK_LEN_SHA256 SHA256_MAC_LEN
-#define EAP_GPSK_PK_LEN_SHA256 SHA256_MAC_LEN
- u8 mk[SHA256_MAC_LEN], zero_string[1], *pos, *data;
- u8 kdf_out[EAP_MSK_LEN + EAP_EMSK_LEN + EAP_GPSK_SK_LEN_SHA256 +
- EAP_GPSK_PK_LEN_SHA256];
- size_t data_len;
+ u8 mk[32], *pos, *data;
+ size_t data_len, mk_len;
+ int (*gkdf)(const u8 *psk, const u8 *data, size_t data_len,
+ u8 *buf, size_t len);
- /*
- * inputString = RAND_Client || ID_Client || RAND_Server || ID_Server
- * (= seed)
- * KS = 32, PL = psk_len, CSuite_Sel = 0x000000 0x000002
- * MK = GKDF-32 (0x00, PL || PSK || CSuite_Sel || inputString)
- * MSK = GKDF-192 (MK, inputString)[0..63]
- * EMSK = GKDF-192 (MK, inputString)[64..127]
- * SK = GKDF-192 (MK, inputString)[128..159]
- * PK = GKDF-192 (MK, inputString)[160..191]
- * MID = GKDF-16(0x00, "Method ID" || EAP_Method_Type || CSuite_Sel ||
- * inputString)
- * Hash-Function = SHA256 (see [RFC4634])
- * hashlen = 32 octets (256 bits)
- */
+ gkdf = NULL;
+ switch (csuite_specifier) {
+ case EAP_GPSK_CIPHER_AES:
+ gkdf = eap_gpsk_gkdf_cmac;
+ mk_len = 16;
+ break;
+#ifdef EAP_GPSK_SHA256
+ case EAP_GPSK_CIPHER_SHA256:
+ gkdf = eap_gpsk_gkdf_sha256;
+ mk_len = SHA256_MAC_LEN;
+ break;
+#endif /* EAP_GPSK_SHA256 */
+ default:
+ return -1;
+ }
- os_memset(zero_string, 0, sizeof(zero_string));
+ if (psk_len < mk_len)
+ return -1;
data_len = 2 + psk_len + 6 + seed_len;
data = os_malloc(data_len);
@@ -233,24 +153,22 @@ static int eap_gpsk_derive_keys_sha256(const u8 *psk, size_t psk_len,
pos += 2;
os_memcpy(pos, psk, psk_len);
pos += psk_len;
- WPA_PUT_BE24(pos, 0); /* CSuite/Vendor = IETF */
- pos += 3;
- WPA_PUT_BE24(pos, EAP_GPSK_CIPHER_SHA256); /* CSuite/Specifier */
- pos += 3;
+ WPA_PUT_BE32(pos, EAP_GPSK_VENDOR_IETF); /* CSuite/Vendor = IETF */
+ pos += 4;
+ WPA_PUT_BE16(pos, csuite_specifier); /* CSuite/Specifier */
+ pos += 2;
os_memcpy(pos, seed, seed_len); /* inputString */
- wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: Data to MK derivation (SHA256)",
+ wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: Data to MK derivation",
data, data_len);
- if (eap_gpsk_gkdf_sha256(zero_string, sizeof(zero_string),
- data, data_len, mk, sizeof(mk)) < 0) {
+ if (gkdf(psk, data, data_len, mk, mk_len) < 0) {
os_free(data);
return -1;
}
os_free(data);
- wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: MK", mk, sizeof(mk));
+ wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: MK", mk, mk_len);
- if (eap_gpsk_gkdf_sha256(mk, sizeof(mk), seed, seed_len,
- kdf_out, sizeof(kdf_out)) < 0)
+ if (gkdf(mk, seed, seed_len, kdf_out, kdf_out_len) < 0)
return -1;
pos = kdf_out;
@@ -262,46 +180,113 @@ static int eap_gpsk_derive_keys_sha256(const u8 *psk, size_t psk_len,
os_memcpy(emsk, pos, EAP_EMSK_LEN);
pos += EAP_EMSK_LEN;
- wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: SK",
- pos, EAP_GPSK_SK_LEN_SHA256);
- os_memcpy(sk, pos, EAP_GPSK_SK_LEN_SHA256);
- *sk_len = EAP_GPSK_SK_LEN_AES;
- pos += EAP_GPSK_SK_LEN_AES;
+ wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: SK", pos, sk_len);
+ os_memcpy(sk, pos, sk_len);
+ pos += sk_len;
- wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: PK",
- pos, EAP_GPSK_PK_LEN_SHA256);
- os_memcpy(pk, pos, EAP_GPSK_PK_LEN_SHA256);
- *pk_len = EAP_GPSK_PK_LEN_SHA256;
+ if (pk) {
+ wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: PK", pos, pk_len);
+ os_memcpy(pk, pos, pk_len);
+ }
return 0;
}
+
+
+static int eap_gpsk_derive_keys_aes(const u8 *psk, size_t psk_len,
+ const u8 *seed, size_t seed_len,
+ u8 *msk, u8 *emsk, u8 *sk, size_t *sk_len,
+ u8 *pk, size_t *pk_len)
+{
+#define EAP_GPSK_SK_LEN_AES 16
+#define EAP_GPSK_PK_LEN_AES 16
+ u8 kdf_out[EAP_MSK_LEN + EAP_EMSK_LEN + EAP_GPSK_SK_LEN_AES +
+ EAP_GPSK_PK_LEN_AES];
+
+ /*
+ * inputString = RAND_Peer || ID_Peer || RAND_Server || ID_Server
+ * (= seed)
+ * KS = 16, PL = psk_len, CSuite_Sel = 0x00000000 0x0001
+ * MK = GKDF-16 (PSK[0..15], PL || PSK || CSuite_Sel || inputString)
+ * MSK = GKDF-160 (MK, inputString)[0..63]
+ * EMSK = GKDF-160 (MK, inputString)[64..127]
+ * SK = GKDF-160 (MK, inputString)[128..143]
+ * PK = GKDF-160 (MK, inputString)[144..159]
+ * zero = 0x00 || 0x00 || ... || 0x00 (16 times)
+ * Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type ||
+ * CSuite_Sel || inputString)
+ */
+
+ *sk_len = EAP_GPSK_SK_LEN_AES;
+ *pk_len = EAP_GPSK_PK_LEN_AES;
+
+ return eap_gpsk_derive_keys_helper(EAP_GPSK_CIPHER_AES,
+ kdf_out, sizeof(kdf_out),
+ psk, psk_len, seed, seed_len,
+ msk, emsk, sk, *sk_len,
+ pk, *pk_len);
+}
+
+
+#ifdef EAP_GPSK_SHA256
+static int eap_gpsk_derive_keys_sha256(const u8 *psk, size_t psk_len,
+ const u8 *seed, size_t seed_len,
+ u8 *msk, u8 *emsk,
+ u8 *sk, size_t *sk_len)
+{
+#define EAP_GPSK_SK_LEN_SHA256 SHA256_MAC_LEN
+#define EAP_GPSK_PK_LEN_SHA256 SHA256_MAC_LEN
+ u8 kdf_out[EAP_MSK_LEN + EAP_EMSK_LEN + EAP_GPSK_SK_LEN_SHA256 +
+ EAP_GPSK_PK_LEN_SHA256];
+
+ /*
+ * inputString = RAND_Peer || ID_Peer || RAND_Server || ID_Server
+ * (= seed)
+ * KS = 32, PL = psk_len, CSuite_Sel = 0x00000000 0x0002
+ * MK = GKDF-32 (PSK[0..31], PL || PSK || CSuite_Sel || inputString)
+ * MSK = GKDF-160 (MK, inputString)[0..63]
+ * EMSK = GKDF-160 (MK, inputString)[64..127]
+ * SK = GKDF-160 (MK, inputString)[128..159]
+ * zero = 0x00 || 0x00 || ... || 0x00 (32 times)
+ * Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type ||
+ * CSuite_Sel || inputString)
+ */
+
+ *sk_len = EAP_GPSK_SK_LEN_SHA256;
+
+ return eap_gpsk_derive_keys_helper(EAP_GPSK_CIPHER_SHA256,
+ kdf_out, sizeof(kdf_out),
+ psk, psk_len, seed, seed_len,
+ msk, emsk, sk, *sk_len,
+ NULL, 0);
+}
#endif /* EAP_GPSK_SHA256 */
/**
* eap_gpsk_derive_keys - Derive EAP-GPSK keys
- * @psk: Pre-shared key (at least 16 bytes if AES is used)
+ * @psk: Pre-shared key
* @psk_len: Length of psk in bytes
* @vendor: CSuite/Vendor
* @specifier: CSuite/Specifier
- * @rand_client: 32-byte RAND_Client
+ * @rand_peer: 32-byte RAND_Peer
* @rand_server: 32-byte RAND_Server
- * @id_client: ID_Client
- * @id_client_len: Length of ID_Client
+ * @id_peer: ID_Peer
+ * @id_peer_len: Length of ID_Peer
* @id_server: ID_Server
* @id_server_len: Length of ID_Server
* @msk: Buffer for 64-byte MSK
* @emsk: Buffer for 64-byte EMSK
* @sk: Buffer for SK (at least EAP_GPSK_MAX_SK_LEN bytes)
* @sk_len: Buffer for returning length of SK
- * @pk: Buffer for SK (at least EAP_GPSK_MAX_PK_LEN bytes)
+ * @pk: Buffer for PK (at least EAP_GPSK_MAX_PK_LEN bytes)
* @pk_len: Buffer for returning length of PK
* Returns: 0 on success, -1 on failure
*/
int eap_gpsk_derive_keys(const u8 *psk, size_t psk_len, int vendor,
int specifier,
- const u8 *rand_client, const u8 *rand_server,
- const u8 *id_client, size_t id_client_len,
+ const u8 *rand_peer, const u8 *rand_server,
+ const u8 *id_peer, size_t id_peer_len,
const u8 *id_server, size_t id_server_len,
u8 *msk, u8 *emsk, u8 *sk, size_t *sk_len,
u8 *pk, size_t *pk_len)
@@ -318,8 +303,8 @@ int eap_gpsk_derive_keys(const u8 *psk, size_t psk_len, int vendor,
wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: PSK", psk, psk_len);
- /* Seed = RAND_Client || ID_Client || RAND_Server || ID_Server */
- seed_len = 2 * EAP_GPSK_RAND_LEN + id_server_len + id_client_len;
+ /* Seed = RAND_Peer || ID_Peer || RAND_Server || ID_Server */
+ seed_len = 2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len;
seed = os_malloc(seed_len);
if (seed == NULL) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to allocate memory "
@@ -328,10 +313,10 @@ int eap_gpsk_derive_keys(const u8 *psk, size_t psk_len, int vendor,
}
pos = seed;
- os_memcpy(pos, rand_client, EAP_GPSK_RAND_LEN);
+ os_memcpy(pos, rand_peer, EAP_GPSK_RAND_LEN);
pos += EAP_GPSK_RAND_LEN;
- os_memcpy(pos, id_client, id_client_len);
- pos += id_client_len;
+ os_memcpy(pos, id_peer, id_peer_len);
+ pos += id_peer_len;
os_memcpy(pos, rand_server, EAP_GPSK_RAND_LEN);
pos += EAP_GPSK_RAND_LEN;
os_memcpy(pos, id_server, id_server_len);
@@ -347,8 +332,7 @@ int eap_gpsk_derive_keys(const u8 *psk, size_t psk_len, int vendor,
#ifdef EAP_GPSK_SHA256
case EAP_GPSK_CIPHER_SHA256:
ret = eap_gpsk_derive_keys_sha256(psk, psk_len, seed, seed_len,
- msk, emsk, sk, sk_len,
- pk, pk_len);
+ msk, emsk, sk, sk_len);
break;
#endif /* EAP_GPSK_SHA256 */
default:
diff --git a/contrib/wpa_supplicant/eap_gpsk_common.h b/contrib/wpa_supplicant/eap_gpsk_common.h
index c806b7f85217..a30ab97ffa07 100644
--- a/contrib/wpa_supplicant/eap_gpsk_common.h
+++ b/contrib/wpa_supplicant/eap_gpsk_common.h
@@ -32,7 +32,7 @@
#define EAP_GPSK_MAX_PK_LEN 32
#define EAP_GPSK_MAX_MIC_LEN 32
-#define EAP_GPSK_VENDOR_IETF 0x000000
+#define EAP_GPSK_VENDOR_IETF 0x00000000
#define EAP_GPSK_CIPHER_RESERVED 0x000000
#define EAP_GPSK_CIPHER_AES 0x000001
#define EAP_GPSK_CIPHER_SHA256 0x000002
@@ -43,8 +43,8 @@
#endif /* _MSC_VER */
struct eap_gpsk_csuite {
- u8 vendor[3];
- u8 specifier[3];
+ u8 vendor[4];
+ u8 specifier[2];
} STRUCT_PACKED;
#ifdef _MSC_VER
diff --git a/contrib/wpa_supplicant/eap_peap.c b/contrib/wpa_supplicant/eap_peap.c
index 7f23e5be2ed6..12bd8d8e2f9e 100644
--- a/contrib/wpa_supplicant/eap_peap.c
+++ b/contrib/wpa_supplicant/eap_peap.c
@@ -41,6 +41,8 @@ struct eap_peap_data {
const struct eap_method *phase2_method;
void *phase2_priv;
int phase2_success;
+ int phase2_eap_success;
+ int phase2_eap_started;
struct eap_method_type phase2_type;
struct eap_method_type *phase2_types;
@@ -296,7 +298,9 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
break;
case EAP_TYPE_TLV:
os_memset(&iret, 0, sizeof(iret));
- if (eap_tlv_process(sm, &iret, hdr, resp, resp_len)) {
+ if (eap_tlv_process(sm, &iret, hdr, resp, resp_len,
+ data->phase2_eap_started &&
+ !data->phase2_eap_success)) {
ret->methodState = METHOD_DONE;
ret->decision = DECISION_FAIL;
return -1;
@@ -354,6 +358,7 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
ret->decision = DECISION_FAIL;
return -1;
}
+ data->phase2_eap_started = 1;
os_memset(&iret, 0, sizeof(iret));
*resp = data->phase2_method->process(sm, data->phase2_priv,
&iret, (u8 *) hdr, len,
@@ -362,6 +367,7 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
iret.methodState == METHOD_MAY_CONT) &&
(iret.decision == DECISION_UNCOND_SUCC ||
iret.decision == DECISION_COND_SUCC)) {
+ data->phase2_eap_success = 1;
data->phase2_success = 1;
}
break;
@@ -550,6 +556,17 @@ continue_req:
/* EAP-Success within TLS tunnel is used to indicate
* shutdown of the TLS channel. The authentication has
* been completed. */
+ if (data->phase2_eap_started &&
+ !data->phase2_eap_success) {
+ wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 "
+ "Success used to indicate success, "
+ "but Phase 2 EAP was not yet "
+ "completed successfully");
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
+ os_free(in_decrypted);
+ return 0;
+ }
wpa_printf(MSG_DEBUG, "EAP-PEAP: Version 1 - "
"EAP-Success within TLS tunnel - "
"authentication completed");
@@ -797,6 +814,8 @@ static void * eap_peap_init_for_reauth(struct eap_sm *sm, void *priv)
data->phase2_method->init_for_reauth)
data->phase2_method->init_for_reauth(sm, data->phase2_priv);
data->phase2_success = 0;
+ data->phase2_eap_success = 0;
+ data->phase2_eap_started = 0;
data->resuming = 1;
sm->peap_done = FALSE;
return priv;
diff --git a/contrib/wpa_supplicant/eap_sim.c b/contrib/wpa_supplicant/eap_sim.c
index 545f0ae31d66..53c198734980 100644
--- a/contrib/wpa_supplicant/eap_sim.c
+++ b/contrib/wpa_supplicant/eap_sim.c
@@ -280,14 +280,16 @@ static u8 * eap_sim_response_start(struct eap_sm *sm,
req->identifier);
msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START);
- wpa_hexdump(MSG_DEBUG, " AT_NONCE_MT",
- data->nonce_mt, EAP_SIM_NONCE_MT_LEN);
- eap_sim_msg_add(msg, EAP_SIM_AT_NONCE_MT, 0,
- data->nonce_mt, EAP_SIM_NONCE_MT_LEN);
- wpa_printf(MSG_DEBUG, " AT_SELECTED_VERSION %d",
- data->selected_version);
- eap_sim_msg_add(msg, EAP_SIM_AT_SELECTED_VERSION,
- data->selected_version, NULL, 0);
+ if (!data->reauth) {
+ wpa_hexdump(MSG_DEBUG, " AT_NONCE_MT",
+ data->nonce_mt, EAP_SIM_NONCE_MT_LEN);
+ eap_sim_msg_add(msg, EAP_SIM_AT_NONCE_MT, 0,
+ data->nonce_mt, EAP_SIM_NONCE_MT_LEN);
+ wpa_printf(MSG_DEBUG, " AT_SELECTED_VERSION %d",
+ data->selected_version);
+ eap_sim_msg_add(msg, EAP_SIM_AT_SELECTED_VERSION,
+ data->selected_version, NULL, 0);
+ }
if (identity) {
wpa_hexdump_ascii(MSG_DEBUG, " AT_IDENTITY",
diff --git a/contrib/wpa_supplicant/eap_sim_common.c b/contrib/wpa_supplicant/eap_sim_common.c
index dc8b2f6f4b10..cc430239ab97 100644
--- a/contrib/wpa_supplicant/eap_sim_common.c
+++ b/contrib/wpa_supplicant/eap_sim_common.c
@@ -1,6 +1,6 @@
/*
* EAP peer: EAP-SIM/AKA shared routines
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -118,6 +118,11 @@ int eap_sim_derive_keys_reauth(u16 _counter,
const u8 *addr[4];
size_t len[4];
+ while (identity_len > 0 && identity[identity_len - 1] == 0) {
+ wpa_printf(MSG_DEBUG, "EAP-SIM: Workaround - drop null "
+ "character from the end of identity");
+ identity_len--;
+ }
addr[0] = identity;
len[0] = identity_len;
addr[1] = counter;
@@ -250,6 +255,10 @@ int eap_sim_parse_attr(const u8 *start, const u8 *end,
pos, pos[1] * 4, end);
return -1;
}
+ if (pos[1] == 0) {
+ wpa_printf(MSG_INFO, "EAP-SIM: Attribute underflow");
+ return -1;
+ }
apos = pos + 2;
alen = pos[1] * 4 - 2;
wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Attribute data",
diff --git a/contrib/wpa_supplicant/eap_tlv.c b/contrib/wpa_supplicant/eap_tlv.c
index df328de6b487..e5f29b630301 100644
--- a/contrib/wpa_supplicant/eap_tlv.c
+++ b/contrib/wpa_supplicant/eap_tlv.c
@@ -1,6 +1,6 @@
/*
* EAP peer method: EAP-TLV (draft-josefsson-pppext-eap-tls-eap-07.txt)
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -103,7 +103,8 @@ u8 * eap_tlv_build_result(int id, u16 status, size_t *resp_len)
* Returns: 0 on success, -1 on failure
*/
int eap_tlv_process(struct eap_sm *sm, struct eap_method_ret *ret,
- const struct eap_hdr *hdr, u8 **resp, size_t *resp_len)
+ const struct eap_hdr *hdr, u8 **resp, size_t *resp_len,
+ int force_failure)
{
size_t left, tlv_len;
const u8 *pos;
@@ -174,8 +175,15 @@ int eap_tlv_process(struct eap_sm *sm, struct eap_method_ret *ret,
if (status == EAP_TLV_RESULT_SUCCESS) {
wpa_printf(MSG_INFO, "EAP-TLV: TLV Result - Success "
"- EAP-TLV/Phase2 Completed");
- resp_status = EAP_TLV_RESULT_SUCCESS;
- ret->decision = DECISION_UNCOND_SUCC;
+ if (force_failure) {
+ wpa_printf(MSG_INFO, "EAP-TLV: Earlier failure"
+ " - force failed Phase 2");
+ resp_status = EAP_TLV_RESULT_FAILURE;
+ ret->decision = DECISION_FAIL;
+ } else {
+ resp_status = EAP_TLV_RESULT_SUCCESS;
+ ret->decision = DECISION_UNCOND_SUCC;
+ }
} else if (status == EAP_TLV_RESULT_FAILURE) {
wpa_printf(MSG_INFO, "EAP-TLV: TLV Result - Failure");
resp_status = EAP_TLV_RESULT_FAILURE;
diff --git a/contrib/wpa_supplicant/eap_tlv.h b/contrib/wpa_supplicant/eap_tlv.h
index 0525a60b183e..789eeaadb1b8 100644
--- a/contrib/wpa_supplicant/eap_tlv.h
+++ b/contrib/wpa_supplicant/eap_tlv.h
@@ -1,6 +1,6 @@
/*
* EAP peer method: EAP-TLV (draft-josefsson-pppext-eap-tls-eap-07.txt)
- * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -90,6 +90,7 @@ struct eap_tlv_pac_ack_tlv {
u8 * eap_tlv_build_nak(int id, u16 nak_type, size_t *resp_len);
u8 * eap_tlv_build_result(int id, u16 status, size_t *resp_len);
int eap_tlv_process(struct eap_sm *sm, struct eap_method_ret *ret,
- const struct eap_hdr *hdr, u8 **resp, size_t *resp_len);
+ const struct eap_hdr *hdr, u8 **resp, size_t *resp_len,
+ int force_failure);
#endif /* EAP_TLV_H */
diff --git a/contrib/wpa_supplicant/eapol_sm.c b/contrib/wpa_supplicant/eapol_sm.c
index 899e2ce096a9..b76a75dc783e 100644
--- a/contrib/wpa_supplicant/eapol_sm.c
+++ b/contrib/wpa_supplicant/eapol_sm.c
@@ -1214,7 +1214,7 @@ int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf,
* eapol_sm_notify_tx_eapol_key - Notification about transmitted EAPOL packet
* @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
*
- * Notify EAPOL station machine about transmitted EAPOL packet from an external
+ * Notify EAPOL state machine about transmitted EAPOL packet from an external
* component, e.g., WPA. This will update the statistics.
*/
void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm)
@@ -1229,7 +1229,7 @@ void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm)
* @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
* @enabled: New portEnabled value
*
- * Notify EAPOL station machine about new portEnabled value.
+ * Notify EAPOL state machine about new portEnabled value.
*/
void eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled)
{
@@ -1247,7 +1247,7 @@ void eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled)
* @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
* @valid: New portValid value
*
- * Notify EAPOL station machine about new portValid value.
+ * Notify EAPOL state machine about new portValid value.
*/
void eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid)
{
@@ -1265,7 +1265,7 @@ void eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid)
* @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
* @success: %TRUE = set success, %FALSE = clear success
*
- * Notify EAPOL station machine that external event has forced EAP state to
+ * Notify the EAPOL state machine that external event has forced EAP state to
* success (success = %TRUE). This can be cleared by setting success = %FALSE.
*
* This function is called to update EAP state when WPA-PSK key handshake has
@@ -1290,7 +1290,7 @@ void eapol_sm_notify_eap_success(struct eapol_sm *sm, Boolean success)
* @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
* @fail: %TRUE = set failure, %FALSE = clear failure
*
- * Notify EAPOL station machine that external event has forced EAP state to
+ * Notify EAPOL state machine that external event has forced EAP state to
* failure (fail = %TRUE). This can be cleared by setting fail = %FALSE.
*/
void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail)
@@ -1311,7 +1311,7 @@ void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail)
* @config: Pointer to current network configuration
* @conf: Pointer to EAPOL configuration data
*
- * Notify EAPOL station machine that configuration has changed. config will be
+ * Notify EAPOL state machine that configuration has changed. config will be
* stored as a backpointer to network configuration. This can be %NULL to clear
* the stored pointed. conf will be copied to local EAPOL/EAP configuration
* data. If conf is %NULL, this part of the configuration change will be
diff --git a/contrib/wpa_supplicant/eapol_test.c b/contrib/wpa_supplicant/eapol_test.c
index ac3213b19274..52cba3615b17 100644
--- a/contrib/wpa_supplicant/eapol_test.c
+++ b/contrib/wpa_supplicant/eapol_test.c
@@ -248,7 +248,8 @@ static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf,
size_t len)
{
/* struct wpa_supplicant *wpa_s = ctx; */
- printf("WPA: eapol_test_eapol_send(type=%d len=%d)\n", type, len);
+ printf("WPA: eapol_test_eapol_send(type=%d len=%lu)\n",
+ type, (unsigned long) len);
if (type == IEEE802_1X_TYPE_EAP_PACKET) {
wpa_hexdump(MSG_DEBUG, "TX EAP -> RADIUS", buf, len);
ieee802_1x_encapsulate_radius(&eapol_test, buf, len);
@@ -1052,6 +1053,9 @@ int main(int argc, char *argv[])
eloop_register_signal_reconfig(eapol_test_terminate, NULL);
eloop_run();
+ eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL);
+ eloop_cancel_timeout(eapol_sm_reauth, &eapol_test, NULL);
+
if (eapol_test_compare_pmk(&eapol_test) == 0 ||
eapol_test.no_mppe_keys)
ret = 0;
diff --git a/contrib/wpa_supplicant/events.c b/contrib/wpa_supplicant/events.c
index c0f4210afa0f..7fa74359e809 100644
--- a/contrib/wpa_supplicant/events.c
+++ b/contrib/wpa_supplicant/events.c
@@ -439,9 +439,10 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
wpa_printf(MSG_DEBUG, " skip - disabled");
continue;
}
- if (bss->ssid_len != ssid->ssid_len ||
- os_memcmp(bss->ssid, ssid->ssid,
- bss->ssid_len) != 0) {
+ if (ssid->ssid_len != 0 &&
+ (bss->ssid_len != ssid->ssid_len ||
+ os_memcmp(bss->ssid, ssid->ssid,
+ bss->ssid_len) != 0)) {
wpa_printf(MSG_DEBUG, " skip - "
"SSID mismatch");
continue;
@@ -464,8 +465,8 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
}
if ((ssid->key_mgmt &
- (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK)) ||
- bss->wpa_ie_len != 0 || bss->rsn_ie_len != 0) {
+ (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK)) &&
+ (bss->wpa_ie_len != 0 || bss->rsn_ie_len != 0)) {
wpa_printf(MSG_DEBUG, " skip - "
"WPA network");
continue;
@@ -515,7 +516,7 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
wpa_supplicant_dbus_notify_scan_results(wpa_s);
- if (wpa_s->conf->ap_scan == 2)
+ if (wpa_s->conf->ap_scan == 2 || wpa_s->disconnected)
return;
results = wpa_s->scan_results;
num = wpa_s->num_scan_results;
diff --git a/contrib/wpa_supplicant/main.c b/contrib/wpa_supplicant/main.c
index fdce7c51452b..f371561cde66 100644
--- a/contrib/wpa_supplicant/main.c
+++ b/contrib/wpa_supplicant/main.c
@@ -39,11 +39,12 @@ static void usage(void)
int i;
printf("%s\n\n%s\n"
"usage:\n"
- " wpa_supplicant [-BddehLqquvwW] [-P<pid file>] "
+ " wpa_supplicant [-BddhKLqqtuvwW] [-P<pid file>] "
"[-g<global ctrl>] \\\n"
" -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
"[-p<driver_param>] \\\n"
- " [-b<br_ifname> [-N -i<ifname> -c<conf> [-C<ctrl>] "
+ " [-b<br_ifname>] [-f<debug file>] \\\n"
+ " [-N -i<ifname> -c<conf> [-C<ctrl>] "
"[-D<driver>] \\\n"
" [-p<driver_param>] [-b<br_ifname>] ...]\n"
"\n"
@@ -65,6 +66,9 @@ static void usage(void)
" -i = interface name\n"
" -d = increase debugging verbosity (-dd even more)\n"
" -D = driver name\n"
+#ifdef CONFIG_DEBUG_FILE
+ " -f = log output to debug file instead of stdout\n"
+#endif /* CONFIG_DEBUG_FILE */
" -g = global ctrl_interface\n"
" -K = include keys (passwords, etc.) in debug output\n"
" -t = include timestamp in debug messages\n"
@@ -143,7 +147,7 @@ int main(int argc, char *argv[])
wpa_supplicant_fd_workaround();
for (;;) {
- c = getopt(argc, argv, "b:Bc:C:D:dg:hi:KLNp:P:qtuvwW");
+ c = getopt(argc, argv, "b:Bc:C:D:df:g:hi:KLNp:P:qtuvwW");
if (c < 0)
break;
switch (c) {
@@ -172,6 +176,11 @@ int main(int argc, char *argv[])
params.wpa_debug_level--;
break;
#endif /* CONFIG_NO_STDOUT_DEBUG */
+#ifdef CONFIG_DEBUG_FILE
+ case 'f':
+ params.wpa_debug_file_path = optarg;
+ break;
+#endif /* CONFIG_DEBUG_FILE */
case 'g':
params.ctrl_interface = optarg;
break;
diff --git a/contrib/wpa_supplicant/os.h b/contrib/wpa_supplicant/os.h
index 4931adb2b8c2..25570a5e171a 100644
--- a/contrib/wpa_supplicant/os.h
+++ b/contrib/wpa_supplicant/os.h
@@ -63,6 +63,9 @@ int os_get_time(struct os_time *t);
* @t: Buffer for returning calendar time representation (seconds since
* 1970-01-01 00:00:00)
* Returns: 0 on success, -1 on failure
+ *
+ * Note: The result is in seconds from Epoch, i.e., in UTC, not in local time
+ * which is used by POSIX mktime().
*/
int os_mktime(int year, int month, int day, int hour, int min, int sec,
os_time_t *t);
diff --git a/contrib/wpa_supplicant/os_unix.c b/contrib/wpa_supplicant/os_unix.c
index fb8149a7f3b9..69ba25a3e856 100644
--- a/contrib/wpa_supplicant/os_unix.c
+++ b/contrib/wpa_supplicant/os_unix.c
@@ -39,7 +39,9 @@ int os_get_time(struct os_time *t)
int os_mktime(int year, int month, int day, int hour, int min, int sec,
os_time_t *t)
{
- struct tm tm;
+ struct tm tm, *tm1;
+ time_t t_local, t1, t2;
+ os_time_t tz_offset;
if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
@@ -54,7 +56,22 @@ int os_mktime(int year, int month, int day, int hour, int min, int sec,
tm.tm_min = min;
tm.tm_sec = sec;
- *t = (os_time_t) mktime(&tm);
+ t_local = mktime(&tm);
+
+ /* figure out offset to UTC */
+ tm1 = localtime(&t_local);
+ if (tm1) {
+ t1 = mktime(tm1);
+ tm1 = gmtime(&t_local);
+ if (tm1) {
+ t2 = mktime(tm1);
+ tz_offset = t2 - t1;
+ } else
+ tz_offset = 0;
+ } else
+ tz_offset = 0;
+
+ *t = (os_time_t) t_local - tz_offset;
return 0;
}
diff --git a/contrib/wpa_supplicant/pcsc_funcs.c b/contrib/wpa_supplicant/pcsc_funcs.c
index cef86534598f..cf8e3b009506 100644
--- a/contrib/wpa_supplicant/pcsc_funcs.c
+++ b/contrib/wpa_supplicant/pcsc_funcs.c
@@ -848,7 +848,8 @@ static int scard_read_record(struct scard_data *scard,
}
if (blen != len + 2) {
wpa_printf(MSG_DEBUG, "SCARD: record read returned unexpected "
- "length %d (expected %d)", blen, len + 2);
+ "length %ld (expected %ld)",
+ (long) blen, (long) len + 2);
os_free(buf);
return -3;
}
@@ -891,7 +892,8 @@ static int scard_read_file(struct scard_data *scard,
}
if (blen != len + 2) {
wpa_printf(MSG_DEBUG, "SCARD: file read returned unexpected "
- "length %d (expected %d)", blen, len + 2);
+ "length %ld (expected %ld)",
+ (long) blen, (long) len + 2);
os_free(buf);
return -3;
}
@@ -969,7 +971,7 @@ int scard_get_imsi(struct scard_data *scard, char *imsi, size_t *len)
return -1;
if (blen < 4) {
wpa_printf(MSG_WARNING, "SCARD: too short (GSM) EF-IMSI "
- "header (len=%d)", blen);
+ "header (len=%ld)", (long) blen);
return -2;
}
@@ -982,14 +984,14 @@ int scard_get_imsi(struct scard_data *scard, char *imsi, size_t *len)
blen = file_size;
}
if (blen < 2 || blen > sizeof(buf)) {
- wpa_printf(MSG_DEBUG, "SCARD: invalid IMSI file length=%d",
- blen);
+ wpa_printf(MSG_DEBUG, "SCARD: invalid IMSI file length=%ld",
+ (long) blen);
return -3;
}
imsilen = (blen - 2) * 2 + 1;
- wpa_printf(MSG_DEBUG, "SCARD: IMSI file length=%d imsilen=%d",
- blen, imsilen);
+ wpa_printf(MSG_DEBUG, "SCARD: IMSI file length=%ld imsilen=%ld",
+ (long) blen, (long) imsilen);
if (blen < 2 || imsilen > *len) {
*len = imsilen;
return -4;
@@ -1071,8 +1073,8 @@ int scard_gsm_auth(struct scard_data *scard, const unsigned char *_rand,
(scard->sim_type == SCARD_USIM &&
(len != 2 || resp[0] != 0x61 || resp[1] != 0x0e))) {
wpa_printf(MSG_WARNING, "SCARD: unexpected response for GSM "
- "auth request (len=%d resp=%02x %02x)",
- len, resp[0], resp[1]);
+ "auth request (len=%ld resp=%02x %02x)",
+ (long) len, resp[0], resp[1]);
return -3;
}
get_resp[4] = resp[1];
@@ -1085,8 +1087,8 @@ int scard_gsm_auth(struct scard_data *scard, const unsigned char *_rand,
if (scard->sim_type == SCARD_GSM_SIM) {
if (len != 4 + 8 + 2) {
wpa_printf(MSG_WARNING, "SCARD: unexpected data "
- "length for GSM auth (len=%d, expected 14)",
- len);
+ "length for GSM auth (len=%ld, expected 14)",
+ (long) len);
return -5;
}
os_memcpy(sres, buf, 4);
@@ -1094,8 +1096,8 @@ int scard_gsm_auth(struct scard_data *scard, const unsigned char *_rand,
} else {
if (len != 1 + 4 + 1 + 8 + 2) {
wpa_printf(MSG_WARNING, "SCARD: unexpected data "
- "length for USIM auth (len=%d, "
- "expected 16)", len);
+ "length for USIM auth (len=%ld, "
+ "expected 16)", (long) len);
return -5;
}
if (buf[0] != 4 || buf[5] != 8) {
@@ -1176,8 +1178,8 @@ int scard_umts_auth(struct scard_data *scard, const unsigned char *_rand,
return -1;
} else if (len != 2 || resp[0] != 0x61) {
wpa_printf(MSG_WARNING, "SCARD: unexpected response for UMTS "
- "auth request (len=%d resp=%02x %02x)",
- len, resp[0], resp[1]);
+ "auth request (len=%ld resp=%02x %02x)",
+ (long) len, resp[0], resp[1]);
return -1;
}
get_resp[4] = resp[1];
diff --git a/contrib/wpa_supplicant/radius.c b/contrib/wpa_supplicant/radius.c
index bf39b2fc42e8..743f3400f1de 100644
--- a/contrib/wpa_supplicant/radius.c
+++ b/contrib/wpa_supplicant/radius.c
@@ -1,6 +1,6 @@
/*
* hostapd / RADIUS message processing
- * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -138,6 +138,7 @@ static struct radius_attr_type radius_attrs[] =
{ RADIUS_ATTR_CALLING_STATION_ID, "Calling-Station-Id",
RADIUS_ATTR_TEXT },
{ RADIUS_ATTR_NAS_IDENTIFIER, "NAS-Identifier", RADIUS_ATTR_TEXT },
+ { RADIUS_ATTR_PROXY_STATE, "Proxy-State", RADIUS_ATTR_UNDIST },
{ RADIUS_ATTR_ACCT_STATUS_TYPE, "Acct-Status-Type",
RADIUS_ATTR_INT32 },
{ RADIUS_ATTR_ACCT_DELAY_TIME, "Acct-Delay-Time", RADIUS_ATTR_INT32 },
@@ -230,8 +231,9 @@ static void radius_msg_dump_attr(struct radius_attr_hdr *hdr)
case RADIUS_ATTR_IP:
if (len == 4) {
- struct in_addr *addr = (struct in_addr *) pos;
- printf(" Value: %s\n", inet_ntoa(*addr));
+ struct in_addr addr;
+ os_memcpy(&addr, pos, 4);
+ printf(" Value: %s\n", inet_ntoa(addr));
} else
printf(" Invalid IP address length %d\n", len);
break;
@@ -664,24 +666,21 @@ int radius_msg_verify(struct radius_msg *msg, const u8 *secret,
int radius_msg_copy_attr(struct radius_msg *dst, struct radius_msg *src,
u8 type)
{
- struct radius_attr_hdr *attr = NULL;
+ struct radius_attr_hdr *attr;
size_t i;
+ int count = 0;
for (i = 0; i < src->attr_used; i++) {
- if (src->attrs[i]->type == type) {
- attr = src->attrs[i];
- break;
+ attr = src->attrs[i];
+ if (attr->type == type) {
+ if (!radius_msg_add_attr(dst, type, (u8 *) (attr + 1),
+ attr->length - sizeof(*attr)))
+ return -1;
+ count++;
}
}
- if (attr == NULL)
- return 0;
-
- if (!radius_msg_add_attr(dst, type, (u8 *) (attr + 1),
- attr->length - sizeof(*attr)))
- return -1;
-
- return 1;
+ return count;
}
diff --git a/contrib/wpa_supplicant/radius.h b/contrib/wpa_supplicant/radius.h
index d1b909da98bf..d4375376a94f 100644
--- a/contrib/wpa_supplicant/radius.h
+++ b/contrib/wpa_supplicant/radius.h
@@ -62,6 +62,7 @@ enum { RADIUS_ATTR_USER_NAME = 1,
RADIUS_ATTR_CALLED_STATION_ID = 30,
RADIUS_ATTR_CALLING_STATION_ID = 31,
RADIUS_ATTR_NAS_IDENTIFIER = 32,
+ RADIUS_ATTR_PROXY_STATE = 33,
RADIUS_ATTR_ACCT_STATUS_TYPE = 40,
RADIUS_ATTR_ACCT_DELAY_TIME = 41,
RADIUS_ATTR_ACCT_INPUT_OCTETS = 42,
diff --git a/contrib/wpa_supplicant/radius_client.c b/contrib/wpa_supplicant/radius_client.c
index 5b00bbeb8577..81cd9c58b16b 100644
--- a/contrib/wpa_supplicant/radius_client.c
+++ b/contrib/wpa_supplicant/radius_client.c
@@ -142,7 +142,8 @@ static void radius_client_handle_send_error(struct radius_client_data *radius,
#ifndef CONFIG_NATIVE_WINDOWS
int _errno = errno;
perror("send[RADIUS]");
- if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL) {
+ if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL ||
+ _errno == EBADF) {
hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO,
"Send failed - maybe interface status changed -"
@@ -451,6 +452,13 @@ int radius_client_send(struct radius_client_data *radius,
}
if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM) {
+ if (conf->acct_server == NULL) {
+ hostapd_logger(radius->ctx, NULL,
+ HOSTAPD_MODULE_RADIUS,
+ HOSTAPD_LEVEL_INFO,
+ "No accounting server configured");
+ return -1;
+ }
shared_secret = conf->acct_server->shared_secret;
shared_secret_len = conf->acct_server->shared_secret_len;
radius_msg_finish_acct(msg, shared_secret, shared_secret_len);
@@ -458,6 +466,13 @@ int radius_client_send(struct radius_client_data *radius,
s = radius->acct_sock;
conf->acct_server->requests++;
} else {
+ if (conf->auth_server == NULL) {
+ hostapd_logger(radius->ctx, NULL,
+ HOSTAPD_MODULE_RADIUS,
+ HOSTAPD_LEVEL_INFO,
+ "No authentication server configured");
+ return -1;
+ }
shared_secret = conf->auth_server->shared_secret;
shared_secret_len = conf->auth_server->shared_secret_len;
radius_msg_finish(msg, shared_secret, shared_secret_len);
diff --git a/contrib/wpa_supplicant/tests/test_aes.c b/contrib/wpa_supplicant/tests/test_aes.c
new file mode 100644
index 000000000000..09c2d8e3586e
--- /dev/null
+++ b/contrib/wpa_supplicant/tests/test_aes.c
@@ -0,0 +1,306 @@
+/*
+ * Test program for AES
+ * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "crypto.h"
+#include "aes_wrap.h"
+
+#define BLOCK_SIZE 16
+
+static void test_aes_perf(void)
+{
+#if 0 /* this did not seem to work with new compiler?! */
+#ifdef __i386__
+#define rdtscll(val) \
+ __asm__ __volatile__("rdtsc" : "=A" (val))
+ const int num_iters = 10;
+ int i;
+ unsigned int start, end;
+ u8 key[16], pt[16], ct[16];
+ void *ctx;
+
+ printf("keySetupEnc:");
+ for (i = 0; i < num_iters; i++) {
+ rdtscll(start);
+ ctx = aes_encrypt_init(key, 16);
+ rdtscll(end);
+ aes_encrypt_deinit(ctx);
+ printf(" %d", end - start);
+ }
+ printf("\n");
+
+ printf("Encrypt:");
+ ctx = aes_encrypt_init(key, 16);
+ for (i = 0; i < num_iters; i++) {
+ rdtscll(start);
+ aes_encrypt(ctx, pt, ct);
+ rdtscll(end);
+ printf(" %d", end - start);
+ }
+ aes_encrypt_deinit(ctx);
+ printf("\n");
+#endif /* __i386__ */
+#endif
+}
+
+
+static int test_eax(void)
+{
+ u8 msg[] = { 0xF7, 0xFB };
+ u8 key[] = { 0x91, 0x94, 0x5D, 0x3F, 0x4D, 0xCB, 0xEE, 0x0B,
+ 0xF4, 0x5E, 0xF5, 0x22, 0x55, 0xF0, 0x95, 0xA4 };
+ u8 nonce[] = { 0xBE, 0xCA, 0xF0, 0x43, 0xB0, 0xA2, 0x3D, 0x84,
+ 0x31, 0x94, 0xBA, 0x97, 0x2C, 0x66, 0xDE, 0xBD };
+ u8 hdr[] = { 0xFA, 0x3B, 0xFD, 0x48, 0x06, 0xEB, 0x53, 0xFA };
+ u8 cipher[] = { 0x19, 0xDD, 0x5C, 0x4C, 0x93, 0x31, 0x04, 0x9D,
+ 0x0B, 0xDA, 0xB0, 0x27, 0x74, 0x08, 0xF6, 0x79,
+ 0x67, 0xE5 };
+ u8 data[sizeof(msg)], tag[BLOCK_SIZE];
+
+ memcpy(data, msg, sizeof(msg));
+ if (aes_128_eax_encrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
+ data, sizeof(data), tag)) {
+ printf("AES-128 EAX mode encryption failed\n");
+ return 1;
+ }
+ if (memcmp(data, cipher, sizeof(data)) != 0) {
+ printf("AES-128 EAX mode encryption returned invalid cipher "
+ "text\n");
+ return 1;
+ }
+ if (memcmp(tag, cipher + sizeof(data), BLOCK_SIZE) != 0) {
+ printf("AES-128 EAX mode encryption returned invalid tag\n");
+ return 1;
+ }
+
+ if (aes_128_eax_decrypt(key, nonce, sizeof(nonce), hdr, sizeof(hdr),
+ data, sizeof(data), tag)) {
+ printf("AES-128 EAX mode decryption failed\n");
+ return 1;
+ }
+ if (memcmp(data, msg, sizeof(data)) != 0) {
+ printf("AES-128 EAX mode decryption returned invalid plain "
+ "text\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static int test_cbc(void)
+{
+ struct cbc_test_vector {
+ u8 key[16];
+ u8 iv[16];
+ u8 plain[32];
+ u8 cipher[32];
+ size_t len;
+ } vectors[] = {
+ {
+ { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b,
+ 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 },
+ { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30,
+ 0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 },
+ "Single block msg",
+ { 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8,
+ 0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a },
+ 16
+ },
+ {
+ { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0,
+ 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a },
+ { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28,
+ 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+ { 0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a,
+ 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a,
+ 0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9,
+ 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1 },
+ 32
+ }
+ };
+ int ret = 0;
+ u8 *buf;
+ unsigned int i;
+
+ for (i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) {
+ struct cbc_test_vector *tv = &vectors[i];
+ buf = malloc(tv->len);
+ if (buf == NULL) {
+ ret++;
+ break;
+ }
+ memcpy(buf, tv->plain, tv->len);
+ aes_128_cbc_encrypt(tv->key, tv->iv, buf, tv->len);
+ if (memcmp(buf, tv->cipher, tv->len) != 0) {
+ printf("AES-CBC encrypt %d failed\n", i);
+ ret++;
+ }
+ memcpy(buf, tv->cipher, tv->len);
+ aes_128_cbc_decrypt(tv->key, tv->iv, buf, tv->len);
+ if (memcmp(buf, tv->plain, tv->len) != 0) {
+ printf("AES-CBC decrypt %d failed\n", i);
+ ret++;
+ }
+ free(buf);
+ }
+
+ return ret;
+}
+
+
+/* OMAC1 AES-128 test vectors from
+ * http://csrc.nist.gov/CryptoToolkit/modes/proposedmodes/omac/omac-ad.pdf
+ */
+
+struct omac1_test_vector {
+ u8 k[16];
+ u8 msg[64];
+ int msg_len;
+ u8 tag[16];
+};
+
+static struct omac1_test_vector test_vectors[] =
+{
+ {
+ { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+ { },
+ 0,
+ { 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
+ 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 }
+ },
+ {
+ { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+ { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a},
+ 16,
+ { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
+ 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c }
+ },
+ {
+ { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+ { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+ 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 },
+ 40,
+ { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
+ 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 }
+ },
+ {
+ { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+ { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+ 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
+ 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+ 64,
+ { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
+ 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe }
+ },
+};
+
+
+int main(int argc, char *argv[])
+{
+ u8 kek[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+ };
+ u8 plain[] = {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
+ };
+ u8 crypt[] = {
+ 0x1F, 0xA6, 0x8B, 0x0A, 0x81, 0x12, 0xB4, 0x47,
+ 0xAE, 0xF3, 0x4B, 0xD8, 0xFB, 0x5A, 0x7B, 0x82,
+ 0x9D, 0x3E, 0x86, 0x23, 0x71, 0xD2, 0xCF, 0xE5
+ };
+ u8 result[24];
+ int ret = 0;
+ unsigned int i;
+ struct omac1_test_vector *tv;
+
+ if (aes_wrap(kek, 2, plain, result)) {
+ printf("AES-WRAP-128-128 reported failure\n");
+ ret++;
+ }
+ if (memcmp(result, crypt, 24) != 0) {
+ printf("AES-WRAP-128-128 failed\n");
+ ret++;
+ }
+ if (aes_unwrap(kek, 2, crypt, result)) {
+ printf("AES-UNWRAP-128-128 reported failure\n");
+ ret++;
+ }
+ if (memcmp(result, plain, 16) != 0) {
+ int i;
+ printf("AES-UNWRAP-128-128 failed\n");
+ ret++;
+ for (i = 0; i < 16; i++)
+ printf(" %02x", result[i]);
+ printf("\n");
+ }
+
+ test_aes_perf();
+
+ for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) {
+ tv = &test_vectors[i];
+ omac1_aes_128(tv->k, tv->msg, tv->msg_len, result);
+ if (memcmp(result, tv->tag, 16) != 0) {
+ printf("OMAC1-AES-128 test vector %d failed\n", i);
+ ret++;
+ }
+
+ if (tv->msg_len > 1) {
+ const u8 *addr[2];
+ size_t len[2];
+
+ addr[0] = tv->msg;
+ len[0] = 1;
+ addr[1] = tv->msg + 1;
+ len[1] = tv->msg_len - 1;
+
+ omac1_aes_128_vector(tv->k, 2, addr, len, result);
+ if (memcmp(result, tv->tag, 16) != 0) {
+ printf("OMAC1-AES-128(vector) test vector %d "
+ "failed\n", i);
+ ret++;
+ }
+ }
+ }
+
+ ret += test_eax();
+
+ ret += test_cbc();
+
+ if (ret)
+ printf("FAILED!\n");
+
+ return ret;
+}
diff --git a/contrib/wpa_supplicant/tests/test_eap_sim_common.c b/contrib/wpa_supplicant/tests/test_eap_sim_common.c
new file mode 100644
index 000000000000..ee3eee4d2911
--- /dev/null
+++ b/contrib/wpa_supplicant/tests/test_eap_sim_common.c
@@ -0,0 +1,53 @@
+/*
+ * Test program for EAP-SIM PRF
+ * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "eap_sim_common.c"
+
+
+static int test_eap_sim_prf(void)
+{
+ /* http://csrc.nist.gov/encryption/dss/Examples-1024bit.pdf */
+ u8 xkey[] = {
+ 0xbd, 0x02, 0x9b, 0xbe, 0x7f, 0x51, 0x96, 0x0b,
+ 0xcf, 0x9e, 0xdb, 0x2b, 0x61, 0xf0, 0x6f, 0x0f,
+ 0xeb, 0x5a, 0x38, 0xb6
+ };
+ u8 w[] = {
+ 0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f,
+ 0xde, 0x1c, 0x0f, 0xfc, 0x7b, 0x2e, 0x3b, 0x49,
+ 0x8b, 0x26, 0x06, 0x14, 0x3c, 0x6c, 0x18, 0xba,
+ 0xcb, 0x0f, 0x6c, 0x55, 0xba, 0xbb, 0x13, 0x78,
+ 0x8e, 0x20, 0xd7, 0x37, 0xa3, 0x27, 0x51, 0x16
+ };
+ u8 buf[40];
+
+ printf("Testing EAP-SIM PRF (FIPS 186-2 + change notice 1)\n");
+ eap_sim_prf(xkey, buf, sizeof(buf));
+ if (memcmp(w, buf, sizeof(w) != 0)) {
+ printf("eap_sim_prf failed\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int main(int argc, char *argv[])
+{
+ int errors = 0;
+
+ errors += test_eap_sim_prf();
+
+ return errors;
+}
diff --git a/contrib/wpa_supplicant/tests/test_md4.c b/contrib/wpa_supplicant/tests/test_md4.c
new file mode 100644
index 000000000000..e92e9a5fafdd
--- /dev/null
+++ b/contrib/wpa_supplicant/tests/test_md4.c
@@ -0,0 +1,99 @@
+/*
+ * Test program for MD4 (test vectors from RFC 1320)
+ * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "crypto.h"
+
+int main(int argc, char *argv[])
+{
+ struct {
+ char *data;
+ u8 *hash;
+ } tests[] = {
+ {
+ "",
+ "\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31"
+ "\xb7\x3c\x59\xd7\xe0\xc0\x89\xc0"
+ },
+ {
+ "a",
+ "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46"
+ "\x24\x5e\x05\xfb\xdb\xd6\xfb\x24"
+ },
+ {
+ "abc",
+ "\xa4\x48\x01\x7a\xaf\x21\xd8\x52"
+ "\x5f\xc1\x0a\xe8\x7a\xa6\x72\x9d"
+ },
+ {
+ "message digest",
+ "\xd9\x13\x0a\x81\x64\x54\x9f\xe8"
+ "\x18\x87\x48\x06\xe1\xc7\x01\x4b"
+ },
+ {
+ "abcdefghijklmnopqrstuvwxyz",
+ "\xd7\x9e\x1c\x30\x8a\xa5\xbb\xcd"
+ "\xee\xa8\xed\x63\xdf\x41\x2d\xa9"
+ },
+ {
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ "0123456789",
+ "\x04\x3f\x85\x82\xf2\x41\xdb\x35"
+ "\x1c\xe6\x27\xe1\x53\xe7\xf0\xe4"
+ },
+ {
+ "12345678901234567890123456789012345678901234567890"
+ "123456789012345678901234567890",
+ "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19"
+ "\x9c\x3e\x7b\x16\x4f\xcc\x05\x36"
+ }
+ };
+ unsigned int i;
+ u8 hash[16];
+ const u8 *addr[2];
+ size_t len[2];
+ int errors = 0;
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ printf("MD4 test case %d:", i);
+
+ addr[0] = tests[i].data;
+ len[0] = strlen(tests[i].data);
+ md4_vector(1, addr, len, hash);
+ if (memcmp(hash, tests[i].hash, 16) != 0) {
+ printf(" FAIL");
+ errors++;
+ } else
+ printf(" OK");
+
+ if (len[0]) {
+ addr[0] = tests[i].data;
+ len[0] = strlen(tests[i].data);
+ addr[1] = tests[i].data + 1;
+ len[1] = strlen(tests[i].data) - 1;
+ md4_vector(1, addr, len, hash);
+ if (memcmp(hash, tests[i].hash, 16) != 0) {
+ printf(" FAIL");
+ errors++;
+ } else
+ printf(" OK");
+ }
+
+ printf("\n");
+ }
+
+ return errors;
+}
diff --git a/contrib/wpa_supplicant/tests/test_md5.c b/contrib/wpa_supplicant/tests/test_md5.c
new file mode 100644
index 000000000000..d8fb41ef694e
--- /dev/null
+++ b/contrib/wpa_supplicant/tests/test_md5.c
@@ -0,0 +1,99 @@
+/*
+ * Test program for MD5 (test vectors from RFC 1321)
+ * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "crypto.h"
+
+int main(int argc, char *argv[])
+{
+ struct {
+ char *data;
+ u8 *hash;
+ } tests[] = {
+ {
+ "",
+ "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04"
+ "\xe9\x80\x09\x98\xec\xf8\x42\x7e"
+ },
+ {
+ "a",
+ "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8"
+ "\x31\xc3\x99\xe2\x69\x77\x26\x61"
+ },
+ {
+ "abc",
+ "\x90\x01\x50\x98\x3c\xd2\x4f\xb0"
+ "\xd6\x96\x3f\x7d\x28\xe1\x7f\x72"
+ },
+ {
+ "message digest",
+ "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d"
+ "\x52\x5a\x2f\x31\xaa\xf1\x61\xd0"
+ },
+ {
+ "abcdefghijklmnopqrstuvwxyz",
+ "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00"
+ "\x7d\xfb\x49\x6c\xca\x67\xe1\x3b"
+ },
+ {
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ "0123456789",
+ "\xd1\x74\xab\x98\xd2\x77\xd9\xf5"
+ "\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f"
+ },
+ {
+ "12345678901234567890123456789012345678901234567890"
+ "123456789012345678901234567890",
+ "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55"
+ "\xac\x49\xda\x2e\x21\x07\xb6\x7a"
+ }
+ };
+ unsigned int i;
+ u8 hash[16];
+ const u8 *addr[2];
+ size_t len[2];
+ int errors = 0;
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ printf("MD5 test case %d:", i);
+
+ addr[0] = tests[i].data;
+ len[0] = strlen(tests[i].data);
+ md5_vector(1, addr, len, hash);
+ if (memcmp(hash, tests[i].hash, 16) != 0) {
+ printf(" FAIL");
+ errors++;
+ } else
+ printf(" OK");
+
+ if (len[0]) {
+ addr[0] = tests[i].data;
+ len[0] = strlen(tests[i].data);
+ addr[1] = tests[i].data + 1;
+ len[1] = strlen(tests[i].data) - 1;
+ md5_vector(1, addr, len, hash);
+ if (memcmp(hash, tests[i].hash, 16) != 0) {
+ printf(" FAIL");
+ errors++;
+ } else
+ printf(" OK");
+ }
+
+ printf("\n");
+ }
+
+ return errors;
+}
diff --git a/contrib/wpa_supplicant/tests/test_ms_funcs.c b/contrib/wpa_supplicant/tests/test_ms_funcs.c
new file mode 100644
index 000000000000..09b53c46f34f
--- /dev/null
+++ b/contrib/wpa_supplicant/tests/test_ms_funcs.c
@@ -0,0 +1,119 @@
+/*
+ * Test program for ms_funcs
+ * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "ms_funcs.c"
+
+
+int main(int argc, char *argv[])
+{
+ /* Test vector from RFC2759 example */
+ u8 *username = "User";
+ u8 *password = "clientPass";
+ u8 auth_challenge[] = {
+ 0x5B, 0x5D, 0x7C, 0x7D, 0x7B, 0x3F, 0x2F, 0x3E,
+ 0x3C, 0x2C, 0x60, 0x21, 0x32, 0x26, 0x26, 0x28
+ };
+ u8 peer_challenge[] = {
+ 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A,
+ 0x28, 0x29, 0x5F, 0x2B, 0x3A, 0x33, 0x7C, 0x7E
+ };
+ u8 challenge[] = { 0xD0, 0x2E, 0x43, 0x86, 0xBC, 0xE9, 0x12, 0x26 };
+ u8 password_hash[] = {
+ 0x44, 0xEB, 0xBA, 0x8D, 0x53, 0x12, 0xB8, 0xD6,
+ 0x11, 0x47, 0x44, 0x11, 0xF5, 0x69, 0x89, 0xAE
+ };
+ u8 nt_response[] = {
+ 0x82, 0x30, 0x9E, 0xCD, 0x8D, 0x70, 0x8B, 0x5E,
+ 0xA0, 0x8F, 0xAA, 0x39, 0x81, 0xCD, 0x83, 0x54,
+ 0x42, 0x33, 0x11, 0x4A, 0x3D, 0x85, 0xD6, 0xDF
+ };
+ u8 password_hash_hash[] = {
+ 0x41, 0xC0, 0x0C, 0x58, 0x4B, 0xD2, 0xD9, 0x1C,
+ 0x40, 0x17, 0xA2, 0xA1, 0x2F, 0xA5, 0x9F, 0x3F
+ };
+ u8 authenticator_response[] = {
+ 0x40, 0x7A, 0x55, 0x89, 0x11, 0x5F, 0xD0, 0xD6,
+ 0x20, 0x9F, 0x51, 0x0F, 0xE9, 0xC0, 0x45, 0x66,
+ 0x93, 0x2C, 0xDA, 0x56
+ };
+ u8 master_key[] = {
+ 0xFD, 0xEC, 0xE3, 0x71, 0x7A, 0x8C, 0x83, 0x8C,
+ 0xB3, 0x88, 0xE5, 0x27, 0xAE, 0x3C, 0xDD, 0x31
+ };
+ u8 send_start_key[] = {
+ 0x8B, 0x7C, 0xDC, 0x14, 0x9B, 0x99, 0x3A, 0x1B,
+ 0xA1, 0x18, 0xCB, 0x15, 0x3F, 0x56, 0xDC, 0xCB
+ };
+ u8 buf[32];
+
+ int errors = 0;
+
+ printf("Testing ms_funcs.c\n");
+
+ challenge_hash(peer_challenge, auth_challenge,
+ username, strlen(username),
+ buf);
+ if (memcmp(challenge, buf, sizeof(challenge)) != 0) {
+ printf("challenge_hash failed\n");
+ errors++;
+ }
+
+ nt_password_hash(password, strlen(password), buf);
+ if (memcmp(password_hash, buf, sizeof(password_hash)) != 0) {
+ printf("nt_password_hash failed\n");
+ errors++;
+ }
+
+ generate_nt_response(auth_challenge, peer_challenge,
+ username, strlen(username),
+ password, strlen(password),
+ buf);
+ if (memcmp(nt_response, buf, sizeof(nt_response)) != 0) {
+ printf("generate_nt_response failed\n");
+ errors++;
+ }
+
+ hash_nt_password_hash(password_hash, buf);
+ if (memcmp(password_hash_hash, buf, sizeof(password_hash_hash)) != 0) {
+ printf("hash_nt_password_hash failed\n");
+ errors++;
+ }
+
+ generate_authenticator_response(password, strlen(password),
+ peer_challenge, auth_challenge,
+ username, strlen(username),
+ nt_response, buf);
+ if (memcmp(authenticator_response, buf, sizeof(authenticator_response))
+ != 0) {
+ printf("generate_authenticator_response failed\n");
+ errors++;
+ }
+
+ get_master_key(password_hash_hash, nt_response, buf);
+ if (memcmp(master_key, buf, sizeof(master_key)) != 0) {
+ printf("get_master_key failed\n");
+ errors++;
+ }
+
+ get_asymetric_start_key(master_key, buf, sizeof(send_start_key), 1, 1);
+ if (memcmp(send_start_key, buf, sizeof(send_start_key)) != 0) {
+ printf("get_asymetric_start_key failed\n");
+ errors++;
+ }
+
+ if (errors)
+ printf("FAILED! %d errors\n", errors);
+
+ return errors;
+}
diff --git a/contrib/wpa_supplicant/tests/test_sha1.c b/contrib/wpa_supplicant/tests/test_sha1.c
new file mode 100644
index 000000000000..a34e3bf4bbc1
--- /dev/null
+++ b/contrib/wpa_supplicant/tests/test_sha1.c
@@ -0,0 +1,328 @@
+/*
+ * Test program for SHA1 and MD5
+ * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "sha1.h"
+#include "md5.h"
+#include "crypto.h"
+
+
+static int test_eap_fast(void)
+{
+ /* draft-cam-winget-eap-fast-01.txt */
+ const u8 pac_key[] = {
+ 0x0B, 0x97, 0x39, 0x0F, 0x37, 0x51, 0x78, 0x09,
+ 0x81, 0x1E, 0xFD, 0x9C, 0x6E, 0x65, 0x94, 0x2B,
+ 0x63, 0x2C, 0xE9, 0x53, 0x89, 0x38, 0x08, 0xBA,
+ 0x36, 0x0B, 0x03, 0x7C, 0xD1, 0x85, 0xE4, 0x14
+ };
+ const u8 seed[] = {
+ 0x3F, 0xFB, 0x11, 0xC4, 0x6C, 0xBF, 0xA5, 0x7A,
+ 0x54, 0x40, 0xDA, 0xE8, 0x22, 0xD3, 0x11, 0xD3,
+ 0xF7, 0x6D, 0xE4, 0x1D, 0xD9, 0x33, 0xE5, 0x93,
+ 0x70, 0x97, 0xEB, 0xA9, 0xB3, 0x66, 0xF4, 0x2A,
+ 0x00, 0x00, 0x00, 0x02, 0x6A, 0x66, 0x43, 0x2A,
+ 0x8D, 0x14, 0x43, 0x2C, 0xEC, 0x58, 0x2D, 0x2F,
+ 0xC7, 0x9C, 0x33, 0x64, 0xBA, 0x04, 0xAD, 0x3A,
+ 0x52, 0x54, 0xD6, 0xA5, 0x79, 0xAD, 0x1E, 0x00
+ };
+ const u8 master_secret[] = {
+ 0x4A, 0x1A, 0x51, 0x2C, 0x01, 0x60, 0xBC, 0x02,
+ 0x3C, 0xCF, 0xBC, 0x83, 0x3F, 0x03, 0xBC, 0x64,
+ 0x88, 0xC1, 0x31, 0x2F, 0x0B, 0xA9, 0xA2, 0x77,
+ 0x16, 0xA8, 0xD8, 0xE8, 0xBD, 0xC9, 0xD2, 0x29,
+ 0x38, 0x4B, 0x7A, 0x85, 0xBE, 0x16, 0x4D, 0x27,
+ 0x33, 0xD5, 0x24, 0x79, 0x87, 0xB1, 0xC5, 0xA2
+ };
+ const u8 key_block[] = {
+ 0x59, 0x59, 0xBE, 0x8E, 0x41, 0x3A, 0x77, 0x74,
+ 0x8B, 0xB2, 0xE5, 0xD3, 0x60, 0xAC, 0x4D, 0x35,
+ 0xDF, 0xFB, 0xC8, 0x1E, 0x9C, 0x24, 0x9C, 0x8B,
+ 0x0E, 0xC3, 0x1D, 0x72, 0xC8, 0x84, 0x9D, 0x57,
+ 0x48, 0x51, 0x2E, 0x45, 0x97, 0x6C, 0x88, 0x70,
+ 0xBE, 0x5F, 0x01, 0xD3, 0x64, 0xE7, 0x4C, 0xBB,
+ 0x11, 0x24, 0xE3, 0x49, 0xE2, 0x3B, 0xCD, 0xEF,
+ 0x7A, 0xB3, 0x05, 0x39, 0x5D, 0x64, 0x8A, 0x44,
+ 0x11, 0xB6, 0x69, 0x88, 0x34, 0x2E, 0x8E, 0x29,
+ 0xD6, 0x4B, 0x7D, 0x72, 0x17, 0x59, 0x28, 0x05,
+ 0xAF, 0xF9, 0xB7, 0xFF, 0x66, 0x6D, 0xA1, 0x96,
+ 0x8F, 0x0B, 0x5E, 0x06, 0x46, 0x7A, 0x44, 0x84,
+ 0x64, 0xC1, 0xC8, 0x0C, 0x96, 0x44, 0x09, 0x98,
+ 0xFF, 0x92, 0xA8, 0xB4, 0xC6, 0x42, 0x28, 0x71
+ };
+ const u8 sks[] = {
+ 0xD6, 0x4B, 0x7D, 0x72, 0x17, 0x59, 0x28, 0x05,
+ 0xAF, 0xF9, 0xB7, 0xFF, 0x66, 0x6D, 0xA1, 0x96,
+ 0x8F, 0x0B, 0x5E, 0x06, 0x46, 0x7A, 0x44, 0x84,
+ 0x64, 0xC1, 0xC8, 0x0C, 0x96, 0x44, 0x09, 0x98,
+ 0xFF, 0x92, 0xA8, 0xB4, 0xC6, 0x42, 0x28, 0x71
+ };
+ const u8 isk[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ const u8 imck[] = {
+ 0x16, 0x15, 0x3C, 0x3F, 0x21, 0x55, 0xEF, 0xD9,
+ 0x7F, 0x34, 0xAE, 0xC8, 0x1A, 0x4E, 0x66, 0x80,
+ 0x4C, 0xC3, 0x76, 0xF2, 0x8A, 0xA9, 0x6F, 0x96,
+ 0xC2, 0x54, 0x5F, 0x8C, 0xAB, 0x65, 0x02, 0xE1,
+ 0x18, 0x40, 0x7B, 0x56, 0xBE, 0xEA, 0xA7, 0xC5,
+ 0x76, 0x5D, 0x8F, 0x0B, 0xC5, 0x07, 0xC6, 0xB9,
+ 0x04, 0xD0, 0x69, 0x56, 0x72, 0x8B, 0x6B, 0xB8,
+ 0x15, 0xEC, 0x57, 0x7B
+ };
+ const u8 msk[] = {
+ 0x4D, 0x83, 0xA9, 0xBE, 0x6F, 0x8A, 0x74, 0xED,
+ 0x6A, 0x02, 0x66, 0x0A, 0x63, 0x4D, 0x2C, 0x33,
+ 0xC2, 0xDA, 0x60, 0x15, 0xC6, 0x37, 0x04, 0x51,
+ 0x90, 0x38, 0x63, 0xDA, 0x54, 0x3E, 0x14, 0xB9,
+ 0x27, 0x99, 0x18, 0x1E, 0x07, 0xBF, 0x0F, 0x5A,
+ 0x5E, 0x3C, 0x32, 0x93, 0x80, 0x8C, 0x6C, 0x49,
+ 0x67, 0xED, 0x24, 0xFE, 0x45, 0x40, 0xA0, 0x59,
+ 0x5E, 0x37, 0xC2, 0xE9, 0xD0, 0x5D, 0x0A, 0xE3
+ };
+ u8 tlv[] = {
+ 0x80, 0x0C, 0x00, 0x38, 0x00, 0x01, 0x01, 0x00,
+ 0xD8, 0x6A, 0x8C, 0x68, 0x3C, 0x32, 0x31, 0xA8,
+ 0x56, 0x63, 0xB6, 0x40, 0x21, 0xFE, 0x21, 0x14,
+ 0x4E, 0xE7, 0x54, 0x20, 0x79, 0x2D, 0x42, 0x62,
+ 0xC9, 0xBF, 0x53, 0x7F, 0x54, 0xFD, 0xAC, 0x58,
+ 0x43, 0x24, 0x6E, 0x30, 0x92, 0x17, 0x6D, 0xCF,
+ 0xE6, 0xE0, 0x69, 0xEB, 0x33, 0x61, 0x6A, 0xCC,
+ 0x05, 0xC5, 0x5B, 0xB7
+ };
+ const u8 compound_mac[] = {
+ 0x43, 0x24, 0x6E, 0x30, 0x92, 0x17, 0x6D, 0xCF,
+ 0xE6, 0xE0, 0x69, 0xEB, 0x33, 0x61, 0x6A, 0xCC,
+ 0x05, 0xC5, 0x5B, 0xB7
+ };
+ u8 buf[512];
+ const u8 *simck, *cmk;
+ int errors = 0;
+
+ printf("EAP-FAST test cases\n");
+
+ printf("- T-PRF (SHA1) test case / master_secret\n");
+ sha1_t_prf(pac_key, sizeof(pac_key), "PAC to master secret label hash",
+ seed, sizeof(seed), buf, sizeof(master_secret));
+ if (memcmp(master_secret, buf, sizeof(master_secret)) != 0) {
+ printf("T-PRF test - FAILED!\n");
+ errors++;
+ }
+
+ printf("- PRF (TLS, SHA1/MD5) test case / key_block\n");
+ tls_prf(master_secret, sizeof(master_secret), "key expansion",
+ seed, sizeof(seed), buf, sizeof(key_block));
+ if (memcmp(key_block, buf, sizeof(key_block)) != 0) {
+ printf("PRF test - FAILED!\n");
+ errors++;
+ }
+
+ printf("- T-PRF (SHA1) test case / IMCK\n");
+ sha1_t_prf(sks, sizeof(sks), "Inner Methods Compound Keys",
+ isk, sizeof(isk), buf, sizeof(imck));
+ if (memcmp(imck, buf, sizeof(imck)) != 0) {
+ printf("T-PRF test - FAILED!\n");
+ errors++;
+ }
+
+ simck = imck;
+ cmk = imck + 40;
+
+ printf("- T-PRF (SHA1) test case / MSK\n");
+ sha1_t_prf(simck, 40, "Session Key Generating Function",
+ (u8 *) "", 0, buf, sizeof(msk));
+ if (memcmp(msk, buf, sizeof(msk)) != 0) {
+ printf("T-PRF test - FAILED!\n");
+ errors++;
+ }
+
+ printf("- Compound MAC test case\n");
+ memset(tlv + sizeof(tlv) - 20, 0, 20);
+ hmac_sha1(cmk, 20, tlv, sizeof(tlv), tlv + sizeof(tlv) - 20);
+ if (memcmp(tlv + sizeof(tlv) - 20, compound_mac, sizeof(compound_mac))
+ != 0) {
+ printf("Compound MAC test - FAILED!\n");
+ errors++;
+ }
+
+ return errors;
+}
+
+
+static u8 key0[] =
+{
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b
+};
+static u8 data0[] = "Hi There";
+static u8 prf0[] =
+{
+ 0xbc, 0xd4, 0xc6, 0x50, 0xb3, 0x0b, 0x96, 0x84,
+ 0x95, 0x18, 0x29, 0xe0, 0xd7, 0x5f, 0x9d, 0x54,
+ 0xb8, 0x62, 0x17, 0x5e, 0xd9, 0xf0, 0x06, 0x06,
+ 0xe1, 0x7d, 0x8d, 0xa3, 0x54, 0x02, 0xff, 0xee,
+ 0x75, 0xdf, 0x78, 0xc3, 0xd3, 0x1e, 0x0f, 0x88,
+ 0x9f, 0x01, 0x21, 0x20, 0xc0, 0x86, 0x2b, 0xeb,
+ 0x67, 0x75, 0x3e, 0x74, 0x39, 0xae, 0x24, 0x2e,
+ 0xdb, 0x83, 0x73, 0x69, 0x83, 0x56, 0xcf, 0x5a
+};
+
+static u8 key1[] = "Jefe";
+static u8 data1[] = "what do ya want for nothing?";
+static u8 prf1[] =
+{
+ 0x51, 0xf4, 0xde, 0x5b, 0x33, 0xf2, 0x49, 0xad,
+ 0xf8, 0x1a, 0xeb, 0x71, 0x3a, 0x3c, 0x20, 0xf4,
+ 0xfe, 0x63, 0x14, 0x46, 0xfa, 0xbd, 0xfa, 0x58,
+ 0x24, 0x47, 0x59, 0xae, 0x58, 0xef, 0x90, 0x09,
+ 0xa9, 0x9a, 0xbf, 0x4e, 0xac, 0x2c, 0xa5, 0xfa,
+ 0x87, 0xe6, 0x92, 0xc4, 0x40, 0xeb, 0x40, 0x02,
+ 0x3e, 0x7b, 0xab, 0xb2, 0x06, 0xd6, 0x1d, 0xe7,
+ 0xb9, 0x2f, 0x41, 0x52, 0x90, 0x92, 0xb8, 0xfc
+};
+
+
+static u8 key2[] =
+{
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa
+};
+static u8 data2[] =
+{
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd
+};
+static u8 prf2[] =
+{
+ 0xe1, 0xac, 0x54, 0x6e, 0xc4, 0xcb, 0x63, 0x6f,
+ 0x99, 0x76, 0x48, 0x7b, 0xe5, 0xc8, 0x6b, 0xe1,
+ 0x7a, 0x02, 0x52, 0xca, 0x5d, 0x8d, 0x8d, 0xf1,
+ 0x2c, 0xfb, 0x04, 0x73, 0x52, 0x52, 0x49, 0xce,
+ 0x9d, 0xd8, 0xd1, 0x77, 0xea, 0xd7, 0x10, 0xbc,
+ 0x9b, 0x59, 0x05, 0x47, 0x23, 0x91, 0x07, 0xae,
+ 0xf7, 0xb4, 0xab, 0xd4, 0x3d, 0x87, 0xf0, 0xa6,
+ 0x8f, 0x1c, 0xbd, 0x9e, 0x2b, 0x6f, 0x76, 0x07
+};
+
+
+struct passphrase_test {
+ char *passphrase;
+ char *ssid;
+ char psk[32];
+};
+
+static struct passphrase_test passphrase_tests[] =
+{
+ {
+ "password",
+ "IEEE",
+ {
+ 0xf4, 0x2c, 0x6f, 0xc5, 0x2d, 0xf0, 0xeb, 0xef,
+ 0x9e, 0xbb, 0x4b, 0x90, 0xb3, 0x8a, 0x5f, 0x90,
+ 0x2e, 0x83, 0xfe, 0x1b, 0x13, 0x5a, 0x70, 0xe2,
+ 0x3a, 0xed, 0x76, 0x2e, 0x97, 0x10, 0xa1, 0x2e
+ }
+ },
+ {
+ "ThisIsAPassword",
+ "ThisIsASSID",
+ {
+ 0x0d, 0xc0, 0xd6, 0xeb, 0x90, 0x55, 0x5e, 0xd6,
+ 0x41, 0x97, 0x56, 0xb9, 0xa1, 0x5e, 0xc3, 0xe3,
+ 0x20, 0x9b, 0x63, 0xdf, 0x70, 0x7d, 0xd5, 0x08,
+ 0xd1, 0x45, 0x81, 0xf8, 0x98, 0x27, 0x21, 0xaf
+ }
+ },
+ {
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
+ {
+ 0xbe, 0xcb, 0x93, 0x86, 0x6b, 0xb8, 0xc3, 0x83,
+ 0x2c, 0xb7, 0x77, 0xc2, 0xf5, 0x59, 0x80, 0x7c,
+ 0x8c, 0x59, 0xaf, 0xcb, 0x6e, 0xae, 0x73, 0x48,
+ 0x85, 0x00, 0x13, 0x00, 0xa9, 0x81, 0xcc, 0x62
+ }
+ },
+};
+
+#define NUM_PASSPHRASE_TESTS \
+(sizeof(passphrase_tests) / sizeof(passphrase_tests[0]))
+
+
+int main(int argc, char *argv[])
+{
+ u8 res[512];
+ int ret = 0;
+ unsigned int i;
+
+ printf("PRF-SHA1 test cases:\n");
+
+ sha1_prf(key0, sizeof(key0), "prefix", data0, sizeof(data0) - 1,
+ res, sizeof(prf0));
+ if (memcmp(res, prf0, sizeof(prf0)) == 0)
+ printf("Test case 0 - OK\n");
+ else {
+ printf("Test case 0 - FAILED!\n");
+ ret++;
+ }
+
+ sha1_prf(key1, sizeof(key1) - 1, "prefix", data1, sizeof(data1) - 1,
+ res, sizeof(prf1));
+ if (memcmp(res, prf1, sizeof(prf1)) == 0)
+ printf("Test case 1 - OK\n");
+ else {
+ printf("Test case 1 - FAILED!\n");
+ ret++;
+ }
+
+ sha1_prf(key2, sizeof(key2), "prefix", data2, sizeof(data2),
+ res, sizeof(prf2));
+ if (memcmp(res, prf2, sizeof(prf2)) == 0)
+ printf("Test case 2 - OK\n");
+ else {
+ printf("Test case 2 - FAILED!\n");
+ ret++;
+ }
+
+ ret += test_eap_fast();
+
+ printf("PBKDF2-SHA1 Passphrase test cases:\n");
+ for (i = 0; i < NUM_PASSPHRASE_TESTS; i++) {
+ u8 psk[32];
+ struct passphrase_test *test = &passphrase_tests[i];
+ pbkdf2_sha1(test->passphrase,
+ test->ssid, strlen(test->ssid),
+ 4096, psk, 32);
+ if (memcmp(psk, test->psk, 32) == 0)
+ printf("Test case %d - OK\n", i);
+ else {
+ printf("Test case %d - FAILED!\n", i);
+ ret++;
+ }
+ }
+
+ return ret;
+}
diff --git a/contrib/wpa_supplicant/tests/test_sha256.c b/contrib/wpa_supplicant/tests/test_sha256.c
new file mode 100644
index 000000000000..161533ea7365
--- /dev/null
+++ b/contrib/wpa_supplicant/tests/test_sha256.c
@@ -0,0 +1,330 @@
+/*
+ * Test program for SHA256
+ * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "sha256.h"
+#include "crypto.h"
+
+struct {
+ char *data;
+ u8 hash[32];
+} tests[] = {
+ {
+ "abc",
+ {
+ 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
+ 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
+ 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
+ 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
+ }
+ },
+ {
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ {
+ 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
+ 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
+ 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
+ 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1
+ }
+ }
+};
+
+struct hmac_test {
+ u8 key[80];
+ size_t key_len;
+ u8 data[128];
+ size_t data_len;
+ u8 hash[32];
+} hmac_tests[] = {
+ /* draft-ietf-ipsec-ciph-sha-256-01.txt */
+ {
+ {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
+ },
+ 32,
+ "abc", 3,
+ {
+ 0xa2, 0x1b, 0x1f, 0x5d, 0x4c, 0xf4, 0xf7, 0x3a,
+ 0x4d, 0xd9, 0x39, 0x75, 0x0f, 0x7a, 0x06, 0x6a,
+ 0x7f, 0x98, 0xcc, 0x13, 0x1c, 0xb1, 0x6a, 0x66,
+ 0x92, 0x75, 0x90, 0x21, 0xcf, 0xab, 0x81, 0x81
+ }
+ },
+ {
+ {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
+ },
+ 32,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ 56,
+ {
+ 0x10, 0x4f, 0xdc, 0x12, 0x57, 0x32, 0x8f, 0x08,
+ 0x18, 0x4b, 0xa7, 0x31, 0x31, 0xc5, 0x3c, 0xae,
+ 0xe6, 0x98, 0xe3, 0x61, 0x19, 0x42, 0x11, 0x49,
+ 0xea, 0x8c, 0x71, 0x24, 0x56, 0x69, 0x7d, 0x30
+ }
+ },
+ {
+ {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
+ },
+ 32,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ 112,
+ {
+ 0x47, 0x03, 0x05, 0xfc, 0x7e, 0x40, 0xfe, 0x34,
+ 0xd3, 0xee, 0xb3, 0xe7, 0x73, 0xd9, 0x5a, 0xab,
+ 0x73, 0xac, 0xf0, 0xfd, 0x06, 0x04, 0x47, 0xa5,
+ 0xeb, 0x45, 0x95, 0xbf, 0x33, 0xa9, 0xd1, 0xa3
+ }
+ },
+ {
+ {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
+ },
+ 32,
+ "Hi There",
+ 8,
+ {
+ 0x19, 0x8a, 0x60, 0x7e, 0xb4, 0x4b, 0xfb, 0xc6,
+ 0x99, 0x03, 0xa0, 0xf1, 0xcf, 0x2b, 0xbd, 0xc5,
+ 0xba, 0x0a, 0xa3, 0xf3, 0xd9, 0xae, 0x3c, 0x1c,
+ 0x7a, 0x3b, 0x16, 0x96, 0xa0, 0xb6, 0x8c, 0xf7
+ }
+ },
+ {
+ "Jefe",
+ 4,
+ "what do ya want for nothing?",
+ 28,
+ {
+ 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
+ 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
+ 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
+ 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43
+ }
+ },
+ {
+ {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
+ },
+ 32,
+ {
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+ 0xdd, 0xdd
+ },
+ 50,
+ {
+ 0xcd, 0xcb, 0x12, 0x20, 0xd1, 0xec, 0xcc, 0xea,
+ 0x91, 0xe5, 0x3a, 0xba, 0x30, 0x92, 0xf9, 0x62,
+ 0xe5, 0x49, 0xfe, 0x6c, 0xe9, 0xed, 0x7f, 0xdc,
+ 0x43, 0x19, 0x1f, 0xbd, 0xe4, 0x5c, 0x30, 0xb0
+ }
+ },
+ {
+ {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25
+ },
+ 37,
+ {
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+ 0xcd, 0xcd
+ },
+ 50,
+ {
+ 0xd4, 0x63, 0x3c, 0x17, 0xf6, 0xfb, 0x8d, 0x74,
+ 0x4c, 0x66, 0xde, 0xe0, 0xf8, 0xf0, 0x74, 0x55,
+ 0x6e, 0xc4, 0xaf, 0x55, 0xef, 0x07, 0x99, 0x85,
+ 0x41, 0x46, 0x8e, 0xb4, 0x9b, 0xd2, 0xe9, 0x17
+ }
+ },
+ {
+ {
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c
+ },
+ 32,
+ "Test With Truncation",
+ 20,
+ {
+ 0x75, 0x46, 0xaf, 0x01, 0x84, 0x1f, 0xc0, 0x9b,
+ 0x1a, 0xb9, 0xc3, 0x74, 0x9a, 0x5f, 0x1c, 0x17,
+ 0xd4, 0xf5, 0x89, 0x66, 0x8a, 0x58, 0x7b, 0x27,
+ 0x00, 0xa9, 0xc9, 0x7c, 0x11, 0x93, 0xcf, 0x42
+ }
+ },
+ {
+ {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
+ },
+ 80,
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ 54,
+ {
+ 0x69, 0x53, 0x02, 0x5e, 0xd9, 0x6f, 0x0c, 0x09,
+ 0xf8, 0x0a, 0x96, 0xf7, 0x8e, 0x65, 0x38, 0xdb,
+ 0xe2, 0xe7, 0xb8, 0x20, 0xe3, 0xdd, 0x97, 0x0e,
+ 0x7d, 0xdd, 0x39, 0x09, 0x1b, 0x32, 0x35, 0x2f
+ }
+ },
+ {
+ {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
+ },
+ 80,
+ "Test Using Larger Than Block-Size Key and Larger Than One "
+ "Block-Size Data",
+ 73,
+ {
+ 0x63, 0x55, 0xac, 0x22, 0xe8, 0x90, 0xd0, 0xa3,
+ 0xc8, 0x48, 0x1a, 0x5c, 0xa4, 0x82, 0x5b, 0xc8,
+ 0x84, 0xd3, 0xe7, 0xa1, 0xff, 0x98, 0xa2, 0xfc,
+ 0x2a, 0xc7, 0xd8, 0xe0, 0x64, 0xc3, 0xb2, 0xe6
+ }
+ }
+};
+
+
+int main(int argc, char *argv[])
+{
+
+ unsigned int i;
+ u8 hash[32];
+ const u8 *addr[2];
+ size_t len[2];
+ int errors = 0;
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ printf("SHA256 test case %d:", i + 1);
+
+ addr[0] = (u8 *) tests[i].data;
+ len[0] = strlen(tests[i].data);
+ sha256_vector(1, addr, len, hash);
+ if (memcmp(hash, tests[i].hash, 32) != 0) {
+ printf(" FAIL");
+ errors++;
+ } else
+ printf(" OK");
+
+ if (len[0]) {
+ addr[0] = (u8 *) tests[i].data;
+ len[0] = 1;
+ addr[1] = (u8 *) tests[i].data + 1;
+ len[1] = strlen(tests[i].data) - 1;
+ sha256_vector(2, addr, len, hash);
+ if (memcmp(hash, tests[i].hash, 32) != 0) {
+ printf(" FAIL");
+ errors++;
+ } else
+ printf(" OK");
+ }
+
+ printf("\n");
+ }
+
+ for (i = 0; i < sizeof(hmac_tests) / sizeof(hmac_tests[0]); i++) {
+ struct hmac_test *t = &hmac_tests[i];
+ printf("HMAC-SHA256 test case %d:", i + 1);
+
+ hmac_sha256(t->key, t->key_len, t->data, t->data_len, hash);
+ if (memcmp(hash, t->hash, 32) != 0) {
+ printf(" FAIL");
+ errors++;
+ } else
+ printf(" OK");
+
+ addr[0] = t->data;
+ len[0] = t->data_len;
+ hmac_sha256_vector(t->key, t->key_len, 1, addr, len, hash);
+ if (memcmp(hash, t->hash, 32) != 0) {
+ printf(" FAIL");
+ errors++;
+ } else
+ printf(" OK");
+
+ if (len[0]) {
+ addr[0] = t->data;
+ len[0] = 1;
+ addr[1] = t->data + 1;
+ len[1] = t->data_len - 1;
+ hmac_sha256_vector(t->key, t->key_len, 2, addr, len,
+ hash);
+ if (memcmp(hash, t->hash, 32) != 0) {
+ printf(" FAIL");
+ errors++;
+ } else
+ printf(" OK");
+ }
+
+ printf("\n");
+ }
+
+ printf("Test IEEE 802.11r KDF\n");
+ sha256_prf("abc", 3, "KDF test", "data", 4, hash, sizeof(hash));
+ /* TODO: add proper test case for this */
+
+ return errors;
+}
diff --git a/contrib/wpa_supplicant/tests/test_x509v3.c b/contrib/wpa_supplicant/tests/test_x509v3.c
new file mode 100644
index 000000000000..aa98ecedd76f
--- /dev/null
+++ b/contrib/wpa_supplicant/tests/test_x509v3.c
@@ -0,0 +1,69 @@
+/*
+ * Testing tool for X.509v3 routines
+ * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "asn1.h"
+#include "x509v3.h"
+
+extern int wpa_debug_level;
+
+
+int main(int argc, char *argv[])
+{
+ char *buf;
+ size_t len;
+ struct x509_certificate *certs = NULL, *last = NULL, *cert;
+ int i, reason;
+
+ wpa_debug_level = 0;
+
+ if (argc < 3 || strcmp(argv[1], "-v") != 0) {
+ printf("usage: test_x509v3 -v <cert1.der> <cert2.der> ..\n");
+ return -1;
+ }
+
+ for (i = 2; i < argc; i++) {
+ printf("Reading: %s\n", argv[i]);
+ buf = os_readfile(argv[i], &len);
+ if (buf == NULL) {
+ printf("Failed to read '%s'\n", argv[i]);
+ return -1;
+ }
+
+ cert = x509_certificate_parse(buf, len);
+ if (cert == NULL) {
+ printf("Failed to parse X.509 certificate\n");
+ return -1;
+ }
+
+ free(buf);
+
+ if (certs == NULL)
+ certs = cert;
+ else
+ last->next = cert;
+ last = cert;
+ }
+
+ printf("\n\nValidating certificate chain\n");
+ if (x509_certificate_chain_validate(last, certs, &reason) < 0) {
+ printf("\nCertificate chain validation failed: %d\n", reason);
+ return -1;
+ }
+ printf("\nCertificate chain is valid\n");
+
+ return 0;
+}
diff --git a/contrib/wpa_supplicant/tls_openssl.c b/contrib/wpa_supplicant/tls_openssl.c
index c8d941f7a113..d5aafaaa89d4 100644
--- a/contrib/wpa_supplicant/tls_openssl.c
+++ b/contrib/wpa_supplicant/tls_openssl.c
@@ -1095,6 +1095,18 @@ static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn,
{
SSL_CTX *ssl_ctx = _ssl_ctx;
+ /*
+ * Remove previously configured trusted CA certificates before adding
+ * new ones.
+ */
+ X509_STORE_free(ssl_ctx->cert_store);
+ ssl_ctx->cert_store = X509_STORE_new();
+ if (ssl_ctx->cert_store == NULL) {
+ wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
+ "certificate store", __func__);
+ return -1;
+ }
+
if (ca_cert_blob) {
X509 *cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ca_cert_blob,
ca_cert_blob_len);
@@ -2272,7 +2284,11 @@ int tls_connection_get_keyblock_size(void *tls_ctx,
return -1;
c = conn->ssl->enc_read_ctx->cipher;
+#if OPENSSL_VERSION_NUMBER >= 0x00909000L
+ h = EVP_MD_CTX_md(conn->ssl->read_hash);
+#else
h = conn->ssl->read_hash;
+#endif
return 2 * (EVP_CIPHER_key_length(c) +
EVP_MD_size(h) +
diff --git a/contrib/wpa_supplicant/version.h b/contrib/wpa_supplicant/version.h
index 2eed290d1b92..364d8aea9657 100644
--- a/contrib/wpa_supplicant/version.h
+++ b/contrib/wpa_supplicant/version.h
@@ -1,6 +1,6 @@
#ifndef VERSION_H
#define VERSION_H
-#define VERSION_STR "0.5.8"
+#define VERSION_STR "0.5.10"
#endif /* VERSION_H */
diff --git a/contrib/wpa_supplicant/wpa.c b/contrib/wpa_supplicant/wpa.c
index b6dd75668fe5..5669e6a330e5 100644
--- a/contrib/wpa_supplicant/wpa.c
+++ b/contrib/wpa_supplicant/wpa.c
@@ -4161,10 +4161,6 @@ int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
* @wpa_ie: Pointer to buffer for WPA/RSN IE
* @wpa_ie_len: Pointer to the length of the wpa_ie buffer
* Returns: 0 on success, -1 on failure
- *
- * Inform WPA state machine about the WPA/RSN IE used in (Re)Association
- * Request frame. The IE will be used to override the default value generated
- * with wpa_sm_set_assoc_wpa_ie_default().
*/
int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
size_t *wpa_ie_len)
diff --git a/contrib/wpa_supplicant/wpa_cli.c b/contrib/wpa_supplicant/wpa_cli.c
index a641249bb886..7176c956af67 100644
--- a/contrib/wpa_supplicant/wpa_cli.c
+++ b/contrib/wpa_supplicant/wpa_cli.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant - command line interface for wpa_supplicant daemon
- * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -31,7 +31,7 @@
static const char *wpa_cli_version =
"wpa_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> and contributors";
static const char *wpa_cli_license =
@@ -120,8 +120,10 @@ static const char *commands_help =
" list of variables when run without arguments)\n"
" get_network <network id> <variable> = get network variables\n"
" save_config = save the current configuration\n"
-" disconnect = disconnect and wait for reassociate command before "
-"connecting\n"
+" disconnect = disconnect and wait for reassociate/reconnect command before\n "
+" connecting\n"
+" reconnect = like reassociate, but only takes effect if already "
+"disconnected\n"
" scan = request new BSS scan\n"
" scan_results = get latest scan results\n"
" get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg> = "
@@ -318,13 +320,13 @@ static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
if (argc != 2) {
printf("Invalid SET command: needs two arguments (variable "
"name and value)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long SET command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -358,13 +360,13 @@ static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
if (argc != 1) {
printf("Invalid PREAUTH command: needs one argument "
"(BSSID)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long PREAUTH command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -378,12 +380,12 @@ static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
if (argc != 1) {
printf("Invalid AP_SCAN command: needs one argument (ap_scan "
"value)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long AP_SCAN command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -398,13 +400,13 @@ static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
if (argc != 1) {
printf("Invalid STKSTART command: needs one argument "
"(Peer STA MAC address)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long STKSTART command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -418,12 +420,12 @@ static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
if (argc != 1) {
printf("Invalid LEVEL command: needs one argument (debug "
"level)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long LEVEL command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -437,7 +439,7 @@ static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
if (argc < 2) {
printf("Invalid IDENTITY command: needs two arguments "
"(network id and identity)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -446,14 +448,14 @@ static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long IDENTITY command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long IDENTITY command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -470,7 +472,7 @@ static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
if (argc < 2) {
printf("Invalid PASSWORD command: needs two arguments "
"(network id and password)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -479,14 +481,14 @@ static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PASSWORD command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PASSWORD command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -504,7 +506,7 @@ static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
if (argc < 2) {
printf("Invalid NEW_PASSWORD command: needs two arguments "
"(network id and password)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -513,14 +515,14 @@ static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long NEW_PASSWORD command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long NEW_PASSWORD command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -537,7 +539,7 @@ static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
if (argc < 2) {
printf("Invalid PIN command: needs two arguments "
"(network id and pin)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -546,14 +548,14 @@ static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PIN command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PIN command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -569,7 +571,7 @@ static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
if (argc < 2) {
printf("Invalid OTP command: needs two arguments (network "
"id and password)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -578,14 +580,14 @@ static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long OTP command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long OTP command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -603,7 +605,7 @@ static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
if (argc < 2) {
printf("Invalid PASSPHRASE command: needs two arguments "
"(network id and passphrase)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -612,14 +614,14 @@ static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PASSPHRASE command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PASSPHRASE command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -636,7 +638,7 @@ static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
if (argc < 2) {
printf("Invalid BSSID command: needs two arguments (network "
"id and BSSID)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -644,14 +646,14 @@ static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
ret = os_snprintf(pos, end - pos, "BSSID");
if (ret < 0 || ret >= end - pos) {
printf("Too long BSSID command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 0; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long BSSID command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -675,7 +677,7 @@ static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
if (argc < 1) {
printf("Invalid SELECT_NETWORK command: needs one argument "
"(network id)\n");
- return 0;
+ return -1;
}
os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
@@ -693,7 +695,7 @@ static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
if (argc < 1) {
printf("Invalid ENABLE_NETWORK command: needs one argument "
"(network id)\n");
- return 0;
+ return -1;
}
os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
@@ -711,7 +713,7 @@ static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
if (argc < 1) {
printf("Invalid DISABLE_NETWORK command: needs one argument "
"(network id)\n");
- return 0;
+ return -1;
}
os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
@@ -736,7 +738,7 @@ static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
if (argc < 1) {
printf("Invalid REMOVE_NETWORK command: needs one argument "
"(network id)\n");
- return 0;
+ return -1;
}
os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
@@ -781,14 +783,14 @@ static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
if (argc != 3) {
printf("Invalid SET_NETWORK command: needs three arguments\n"
"(network id, variable name, and value)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
argv[0], argv[1], argv[2]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long SET_NETWORK command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -808,14 +810,14 @@ static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
if (argc != 2) {
printf("Invalid GET_NETWORK command: needs two arguments\n"
"(network id and variable name)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
argv[0], argv[1]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long GET_NETWORK command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -828,6 +830,13 @@ static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
}
+static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return wpa_ctrl_command(ctrl, "RECONNECT");
+}
+
+
static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
@@ -856,13 +865,13 @@ static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
if (argc < 1 || argc > 2) {
printf("Invalid GET_CAPABILITY command: need either one or "
"two arguments\n");
- return 0;
+ return -1;
}
if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
printf("Invalid GET_CAPABILITY command: second argument, "
"if any, must be 'strict'\n");
- return 0;
+ return -1;
}
os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
@@ -929,9 +938,9 @@ static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
if (argc < 1) {
printf("Invalid INTERFACE_ADD command: needs at least one "
"argument (interface name)\n"
- "All arguments: ifname confname driver ctrl_interface "
- "driver_param bridge_name\n");
- return 0;
+ "All arguments: ifname confname driver ctrl_interface "
+ "driver_param bridge_name\n");
+ return -1;
}
/*
@@ -956,7 +965,7 @@ static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
if (argc != 1) {
printf("Invalid INTERFACE_REMOVE command: needs one argument "
"(interface name)\n");
- return 0;
+ return -1;
}
os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
@@ -1002,6 +1011,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
{ "get_network", wpa_cli_cmd_get_network },
{ "save_config", wpa_cli_cmd_save_config },
{ "disconnect", wpa_cli_cmd_disconnect },
+ { "reconnect", wpa_cli_cmd_reconnect },
{ "scan", wpa_cli_cmd_scan },
{ "scan_results", wpa_cli_cmd_scan_results },
{ "get_capability", wpa_cli_cmd_get_capability },
@@ -1015,10 +1025,11 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
};
-static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
+static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
struct wpa_cli_cmd *cmd, *match = NULL;
int count;
+ int ret = 0;
count = 0;
cmd = wpa_cli_commands;
@@ -1047,11 +1058,15 @@ static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
cmd++;
}
printf("\n");
+ ret = 1;
} else if (count == 0) {
printf("Unknown command '%s'\n", argv[0]);
+ ret = 1;
} else {
- match->handler(ctrl, argc - 1, &argv[1]);
+ ret = match->handler(ctrl, argc - 1, &argv[1]);
}
+
+ return ret;
}
@@ -1497,6 +1512,7 @@ int main(int argc, char *argv[])
int warning_displayed = 0;
int c;
int daemonize = 0;
+ int ret = 0;
const char *global = NULL;
if (os_program_init())
@@ -1608,12 +1624,12 @@ int main(int argc, char *argv[])
else if (action_file)
wpa_cli_action(ctrl_conn);
else
- wpa_request(ctrl_conn, argc - optind, &argv[optind]);
+ ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
os_free(ctrl_ifname);
wpa_cli_cleanup();
- return 0;
+ return ret;
}
#else /* CONFIG_CTRL_IFACE */
diff --git a/contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp b/contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
index ca86265121fb..6ea35e0a259a 100644
--- a/contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
+++ b/contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
@@ -162,7 +162,7 @@ void NetworkConfig::addNetwork()
setNetworkParam(id, "ssid", ssidEdit->text().ascii(), true);
- char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
+ const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
switch (auth) {
case AUTH_NONE:
key_mgmt = "NONE";
diff --git a/contrib/wpa_supplicant/wpa_gui-qt4/wpagui.cpp b/contrib/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
index 1dc7af240d5b..31cb38c4c0fd 100644
--- a/contrib/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
+++ b/contrib/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
@@ -1,6 +1,6 @@
/*
* wpa_gui - WpaGui class
- * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2005-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -513,7 +513,7 @@ void WpaGui::helpContents()
void WpaGui::helpAbout()
{
QMessageBox::about(this, "wpa_gui for wpa_supplicant",
- "Copyright (c) 2003-2006,\n"
+ "Copyright (c) 2003-2008,\n"
"Jouni Malinen <j@w1.fi>\n"
"and contributors.\n"
"\n"
diff --git a/contrib/wpa_supplicant/wpa_gui/networkconfig.ui.h b/contrib/wpa_supplicant/wpa_gui/networkconfig.ui.h
index 49bc7225ef3f..a3cd733d06c2 100644
--- a/contrib/wpa_supplicant/wpa_gui/networkconfig.ui.h
+++ b/contrib/wpa_supplicant/wpa_gui/networkconfig.ui.h
@@ -131,7 +131,7 @@ void NetworkConfig::addNetwork()
setNetworkParam(id, "ssid", ssidEdit->text().ascii(), true);
- char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
+ const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
switch (auth) {
case AUTH_NONE:
key_mgmt = "NONE";
diff --git a/contrib/wpa_supplicant/wpa_gui/setup-mingw-cross-compiling b/contrib/wpa_supplicant/wpa_gui/setup-mingw-cross-compiling
index e173b0013781..07e4a8fb6b98 100755
--- a/contrib/wpa_supplicant/wpa_gui/setup-mingw-cross-compiling
+++ b/contrib/wpa_supplicant/wpa_gui/setup-mingw-cross-compiling
@@ -4,8 +4,8 @@
# and I have no idea how to change these. For now, just override the
# directories in the Makefile.Release file after qmake run.
-qmake -spec /q/jm/qt4-win/4.0.0/mkspecs/win32-g++ wpa_gui.pro -o Makefile
+qmake -spec /q/jm/qt4-win/4.3.3/mkspecs/win32-g++ wpa_gui.pro -o Makefile
cat Makefile.Release |
- sed s%qt4/lib%qt4-win/4.0.0/lib%g |
- sed s%qt4/include%qt4-win/4.0.0/include%g > tmp.Makefile.Release &&
+ sed s%/usr/lib/qt4%/q/jm/qt4-win/4.3.3/lib%g |
+ sed s%/usr/include/qt4%/q/jm/qt4-win/4.3.3/include%g > tmp.Makefile.Release &&
mv -f tmp.Makefile.Release Makefile.Release
diff --git a/contrib/wpa_supplicant/wpa_gui/wpagui.ui.h b/contrib/wpa_supplicant/wpa_gui/wpagui.ui.h
index 04e438df1eab..6db886243fa6 100644
--- a/contrib/wpa_supplicant/wpa_gui/wpagui.ui.h
+++ b/contrib/wpa_supplicant/wpa_gui/wpagui.ui.h
@@ -468,7 +468,7 @@ void WpaGui::helpContents()
void WpaGui::helpAbout()
{
QMessageBox::about(this, "wpa_gui for wpa_supplicant",
- "Copyright (c) 2003-2005,\n"
+ "Copyright (c) 2003-2008,\n"
"Jouni Malinen <j@w1.fi>\n"
"and contributors.\n"
"\n"
diff --git a/contrib/wpa_supplicant/wpa_supplicant.c b/contrib/wpa_supplicant/wpa_supplicant.c
index f7ac13e836ab..99f1185f048c 100644
--- a/contrib/wpa_supplicant/wpa_supplicant.c
+++ b/contrib/wpa_supplicant/wpa_supplicant.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant
- * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -38,7 +38,7 @@
const char *wpa_supplicant_version =
"wpa_supplicant v" VERSION_STR "\n"
-"Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> and contributors";
const char *wpa_supplicant_license =
"This program is free software. You can distribute it and/or modify it\n"
@@ -106,7 +106,6 @@ const char *wpa_supplicant_full_license5 =
extern struct wpa_driver_ops *wpa_supplicant_drivers[];
-extern int wpa_debug_use_file;
extern int wpa_debug_level;
extern int wpa_debug_show_keys;
extern int wpa_debug_timestamp;
@@ -519,7 +518,7 @@ static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
if (os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
bssid = wpa_s->pending_bssid;
wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
- MAC2STR(wpa_s->bssid));
+ MAC2STR(bssid));
wpa_blacklist_add(wpa_s, bssid);
wpa_sm_notify_disassoc(wpa_s->wpa);
wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
@@ -900,6 +899,13 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
* TODO: should notify EAPOL SM about changes in opensc_engine_path,
* pkcs11_engine_path, pkcs11_module_path.
*/
+ if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
+ /*
+ * Clear forced success to clear EAP state for next
+ * authentication.
+ */
+ eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
+ }
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
wpa_sm_set_config(wpa_s->wpa, NULL);
wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
@@ -956,7 +962,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
struct wpa_ssid *ssid;
int enabled, scan_req = 0, ret;
- if (wpa_s->disconnected)
+ if (wpa_s->disconnected && !wpa_s->scan_req)
return;
enabled = 0;
@@ -1461,6 +1467,8 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
params.ssid = ssid->ssid;
params.ssid_len = ssid->ssid_len;
}
+ if (ssid->mode == 1 && ssid->frequency > 0 && params.freq == 0)
+ params.freq = ssid->frequency; /* Initial channel for IBSS */
params.wpa_ie = wpa_ie;
params.wpa_ie_len = wpa_ie_len;
params.pairwise_suite = cipher_pairwise;
@@ -2414,7 +2422,7 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
*
* This function can be used to dynamically remove network interfaces from
* %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
- * addition, this function is used to remove all remaining interdaces when
+ * addition, this function is used to remove all remaining interfaces when
* %wpa_supplicant is terminated.
*/
int wpa_supplicant_remove_iface(struct wpa_global *global,
@@ -2479,8 +2487,7 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
if (params == NULL)
return NULL;
- wpa_debug_use_file = params->wpa_debug_use_file;
- wpa_debug_open_file();
+ wpa_debug_open_file(params->wpa_debug_file_path);
ret = eap_peer_register_methods();
if (ret) {
@@ -2509,8 +2516,6 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
params->wpa_debug_show_keys;
wpa_debug_timestamp = global->params.wpa_debug_timestamp =
params->wpa_debug_timestamp;
- wpa_debug_use_file = global->params.wpa_debug_use_file =
- params->wpa_debug_use_file;
if (eloop_init(global)) {
wpa_printf(MSG_ERROR, "Failed to initialize event loop");
diff --git a/contrib/wpa_supplicant/wpa_supplicant.conf b/contrib/wpa_supplicant/wpa_supplicant.conf
index dce9d8705593..ec8b0eeb3f21 100644
--- a/contrib/wpa_supplicant/wpa_supplicant.conf
+++ b/contrib/wpa_supplicant/wpa_supplicant.conf
@@ -192,6 +192,13 @@ fast_reauth=1
# proto=WPA, key_mgmt=WPA-NONE, pairwise=NONE, group=TKIP (or CCMP, but not
# both), and psk must also be set.
#
+# frequency: Channel frequency in megahertz (MHz) for IBSS, e.g.,
+# 2412 = IEEE 802.11b/g channel 1. This value is used to configure the initial
+# channel for IBSS (adhoc) networks. It is ignored in the infrastructure mode.
+# In addition, this value is only used by the station that creates the IBSS. If
+# an IBSS network with the configured SSID is already present, the frequency of
+# the network will be used instead of this configured value.
+#
# proto: list of accepted protocols
# WPA = WPA/IEEE 802.11i/D3.0
# RSN = WPA2/IEEE 802.11i (also WPA2 can be used as an alias for RSN)
@@ -657,6 +664,7 @@ network={
network={
ssid="test adhoc"
mode=1
+ frequency=2412
proto=WPA
key_mgmt=WPA-NONE
pairwise=NONE
diff --git a/contrib/wpa_supplicant/wpa_supplicant_i.h b/contrib/wpa_supplicant/wpa_supplicant_i.h
index bb80f898f873..0d6f24a938df 100644
--- a/contrib/wpa_supplicant/wpa_supplicant_i.h
+++ b/contrib/wpa_supplicant/wpa_supplicant_i.h
@@ -158,9 +158,9 @@ struct wpa_params {
int dbus_ctrl_interface;
/**
- * wpa_debug_use_file - Write debug to a file (instead of stdout)
+ * wpa_debug_file_path - Path of debug file or %NULL to use stdout
*/
- int wpa_debug_use_file;
+ const char *wpa_debug_file_path;
};
/**
diff --git a/contrib/wpa_supplicant/x509v3.c b/contrib/wpa_supplicant/x509v3.c
index 1283fff04f7d..484c54bad897 100644
--- a/contrib/wpa_supplicant/x509v3.c
+++ b/contrib/wpa_supplicant/x509v3.c
@@ -1,6 +1,6 @@
/*
* X.509v3 certificate parsing and processing (RFC 3280 profile)
- * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -75,8 +75,39 @@ void x509_certificate_chain_free(struct x509_certificate *cert)
}
+static int x509_whitespace(char c)
+{
+ return c == ' ' || c == '\t';
+}
+
+
+static void x509_str_strip_whitespace(char *a)
+{
+ char *ipos, *opos;
+ int remove_whitespace = 1;
+
+ ipos = opos = a;
+
+ while (*ipos) {
+ if (remove_whitespace && x509_whitespace(*ipos))
+ ipos++;
+ else {
+ remove_whitespace = x509_whitespace(*ipos);
+ *opos++ = *ipos++;
+ }
+ }
+
+ *opos-- = '\0';
+ if (opos > a && x509_whitespace(*opos))
+ *opos = '\0';
+}
+
+
static int x509_str_compare(const char *a, const char *b)
{
+ char *aa, *bb;
+ int ret;
+
if (!a && b)
return -1;
if (a && !b)
@@ -84,14 +115,31 @@ static int x509_str_compare(const char *a, const char *b)
if (!a && !b)
return 0;
- return os_strcmp(a, b);
+ aa = os_strdup(a);
+ bb = os_strdup(b);
+
+ if (aa == NULL || bb == NULL) {
+ os_free(aa);
+ os_free(bb);
+ return os_strcasecmp(a, b);
+ }
+
+ x509_str_strip_whitespace(aa);
+ x509_str_strip_whitespace(bb);
+
+ ret = os_strcasecmp(aa, bb);
+
+ os_free(aa);
+ os_free(bb);
+
+ return ret;
}
/**
* x509_name_compare - Compare X.509 certificate names
* @a: Certificate name
- * @b: Certifiatte name
+ * @b: Certificate name
* Returns: <0, 0, or >0 based on whether a is less than, equal to, or
* greater than b
*/
@@ -553,6 +601,17 @@ static int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag,
if (os_mktime(year, month, day, hour, min, sec, val) < 0) {
wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to convert Time",
buf, len);
+ if (year < 1970) {
+ /*
+ * At least some test certificates have been configured
+ * to use dates prior to 1970. Set the date to
+ * beginning of 1970 to handle these case.
+ */
+ wpa_printf(MSG_DEBUG, "X509: Year=%d before epoch - "
+ "assume epoch as the time", year);
+ *val = 0;
+ return 0;
+ }
return -1;
}
@@ -720,7 +779,8 @@ static int x509_parse_ext_basic_constraints(struct x509_certificate *cert,
return 0;
}
- if (asn1_get_next(pos, len, &hdr) < 0 ||
+ if (asn1_get_next(hdr.payload + hdr.length, len - hdr.length,
+ &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL) {
wpa_printf(MSG_DEBUG, "X509: Failed to parse "
"BasicConstraints");
@@ -1443,6 +1503,13 @@ static int x509_valid_issuer(const struct x509_certificate *cert)
return -1;
}
+ if (cert->version == X509_CERT_V3 &&
+ !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) {
+ wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not "
+ "include BasicConstraints extension");
+ return -1;
+ }
+
if ((cert->extensions_present & X509_EXT_KEY_USAGE) &&
!(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) {
wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have "
@@ -1466,7 +1533,8 @@ int x509_certificate_chain_validate(struct x509_certificate *trusted,
struct x509_certificate *chain,
int *reason)
{
- int idx, chain_trusted = 0;
+ long unsigned idx;
+ int chain_trusted = 0;
struct x509_certificate *cert, *trust;
char buf[128];
struct os_time now;
@@ -1478,12 +1546,15 @@ int x509_certificate_chain_validate(struct x509_certificate *trusted,
for (cert = chain, idx = 0; cert; cert = cert->next, idx++) {
x509_name_string(&cert->subject, buf, sizeof(buf));
- wpa_printf(MSG_DEBUG, "X509: %d: %s", idx, buf);
+ wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf);
if (chain_trusted)
continue;
- if (now.sec < cert->not_before || now.sec > cert->not_after) {
+ if ((unsigned long) now.sec <
+ (unsigned long) cert->not_before ||
+ (unsigned long) now.sec >
+ (unsigned long) cert->not_after) {
wpa_printf(MSG_INFO, "X509: Certificate not valid "
"(now=%lu not_before=%lu not_after=%lu)",
now.sec, cert->not_before, cert->not_after);
@@ -1505,7 +1576,16 @@ int x509_certificate_chain_validate(struct x509_certificate *trusted,
return -1;
}
- /* TODO: validate pathLenConstraint */
+ if ((cert->next->extensions_present &
+ X509_EXT_PATH_LEN_CONSTRAINT) &&
+ idx > cert->next->path_len_constraint) {
+ wpa_printf(MSG_DEBUG, "X509: pathLenConstraint"
+ " not met (idx=%lu issuer "
+ "pathLenConstraint=%lu)", idx,
+ cert->next->path_len_constraint);
+ *reason = X509_VALIDATE_BAD_CERTIFICATE;
+ return -1;
+ }
if (x509_certificate_check_signature(cert->next, cert)
< 0) {