Import of WPA supplicant 0.5.10
This commit is contained in:
parent
7700b89cce
commit
f2afa83e72
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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"/>
|
||||
|
4
contrib/wpa_supplicant/dbus-wpa_supplicant.service
Normal file
4
contrib/wpa_supplicant/dbus-wpa_supplicant.service
Normal file
@ -0,0 +1,4 @@
|
||||
[D-BUS Service]
|
||||
Name=fi.epitest.hostap.WPASupplicant
|
||||
Exec=/sbin/wpa_supplicant -u
|
||||
User=root
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
@ -375,6 +376,13 @@
|
||||
</listitem>
|
||||
</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>
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,6 +77,122 @@ static int eap_gpsk_gkdf(const u8 *psk /* Y */, size_t psk_len,
|
||||
}
|
||||
|
||||
|
||||
#ifdef EAP_GPSK_SHA256
|
||||
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[2];
|
||||
size_t vlen[2];
|
||||
|
||||
hashlen = SHA256_MAC_LEN;
|
||||
/* M_i = MAC_Y (i || Z); (MAC = HMAC-SHA256) */
|
||||
addr[0] = ibuf;
|
||||
vlen[0] = sizeof(ibuf);
|
||||
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);
|
||||
hmac_sha256_vector(psk, 32, 2, addr, vlen, hash);
|
||||
clen = left > hashlen ? hashlen : left;
|
||||
os_memcpy(opos, hash, clen);
|
||||
opos += clen;
|
||||
left -= clen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* EAP_GPSK_SHA256 */
|
||||
|
||||
|
||||
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 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (psk_len < mk_len)
|
||||
return -1;
|
||||
|
||||
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_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",
|
||||
data, data_len);
|
||||
|
||||
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, mk_len);
|
||||
|
||||
if (gkdf(mk, seed, seed_len, kdf_out, kdf_out_len) < 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, sk_len);
|
||||
os_memcpy(sk, pos, sk_len);
|
||||
pos += sk_len;
|
||||
|
||||
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,
|
||||
@ -85,223 +200,93 @@ static int eap_gpsk_derive_keys_aes(const u8 *psk, size_t psk_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
|
||||
* inputString = RAND_Peer || ID_Peer || RAND_Server || ID_Server
|
||||
* (= seed)
|
||||
* KS = 16, PL = psk_len, CSuite_Sel = 0x000000 0x000001
|
||||
* MK = GKDF-32 (0x00, PL || PSK || CSuite_Sel || inputString)
|
||||
* 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]
|
||||
* MID = GKDF-16(0x00, "Method ID" || EAP_Method_Type || CSuite_Sel ||
|
||||
* inputString)
|
||||
* Hash-Function = SHA-1 (see [RFC3174])
|
||||
* hashlen = 20 octets (160 bits)
|
||||
* zero = 0x00 || 0x00 || ... || 0x00 (16 times)
|
||||
* Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type ||
|
||||
* CSuite_Sel || inputString)
|
||||
*/
|
||||
|
||||
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;
|
||||
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_gkdf_sha256(const u8 *psk /* Y */, size_t psk_len,
|
||||
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];
|
||||
|
||||
hashlen = SHA256_MAC_LEN;
|
||||
/* M_i = Hash-Function (i || Y || Z); */
|
||||
addr[0] = ibuf;
|
||||
vlen[0] = sizeof(ibuf);
|
||||
addr[1] = psk;
|
||||
vlen[1] = psk_len;
|
||||
addr[2] = data;
|
||||
vlen[2] = 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);
|
||||
clen = left > hashlen ? hashlen : left;
|
||||
os_memcpy(opos, hash, clen);
|
||||
opos += clen;
|
||||
left -= clen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
u8 *pk, size_t *pk_len)
|
||||
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 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;
|
||||
|
||||
/*
|
||||
* inputString = RAND_Client || ID_Client || RAND_Server || ID_Server
|
||||
* inputString = RAND_Peer || ID_Peer || 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)
|
||||
* 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)
|
||||
*/
|
||||
|
||||
os_memset(zero_string, 0, sizeof(zero_string));
|
||||
*sk_len = EAP_GPSK_SK_LEN_SHA256;
|
||||
|
||||
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_SHA256); /* CSuite/Specifier */
|
||||
pos += 3;
|
||||
os_memcpy(pos, seed, seed_len); /* inputString */
|
||||
wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: Data to MK derivation (SHA256)",
|
||||
data, data_len);
|
||||
|
||||
if (eap_gpsk_gkdf_sha256(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_sha256(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_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: PK",
|
||||
pos, EAP_GPSK_PK_LEN_SHA256);
|
||||
os_memcpy(pk, pos, EAP_GPSK_PK_LEN_SHA256);
|
||||
*pk_len = EAP_GPSK_PK_LEN_SHA256;
|
||||
|
||||
return 0;
|
||||
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:
|
||||
|
@ -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
|
||||
|
@ -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 @@ static int eap_peap_decrypt(struct eap_sm *sm, struct eap_peap_data *data,
|
||||
/* 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;
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
306
contrib/wpa_supplicant/tests/test_aes.c
Normal file
306
contrib/wpa_supplicant/tests/test_aes.c
Normal file
@ -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;
|
||||
}
|
53
contrib/wpa_supplicant/tests/test_eap_sim_common.c
Normal file
53
contrib/wpa_supplicant/tests/test_eap_sim_common.c
Normal file
@ -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;
|
||||
}
|
99
contrib/wpa_supplicant/tests/test_md4.c
Normal file
99
contrib/wpa_supplicant/tests/test_md4.c
Normal file
@ -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;
|
||||
}
|
99
contrib/wpa_supplicant/tests/test_md5.c
Normal file
99
contrib/wpa_supplicant/tests/test_md5.c
Normal file
@ -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;
|
||||
}
|
119
contrib/wpa_supplicant/tests/test_ms_funcs.c
Normal file
119
contrib/wpa_supplicant/tests/test_ms_funcs.c
Normal file
@ -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;
|
||||
}
|
328
contrib/wpa_supplicant/tests/test_sha1.c
Normal file
328
contrib/wpa_supplicant/tests/test_sha1.c
Normal file
@ -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;
|
||||
}
|
330
contrib/wpa_supplicant/tests/test_sha256.c
Normal file
330
contrib/wpa_supplicant/tests/test_sha256.c
Normal file
@ -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;
|
||||
}
|
69
contrib/wpa_supplicant/tests/test_x509v3.c
Normal file
69
contrib/wpa_supplicant/tests/test_x509v3.c
Normal file
@ -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;
|
||||
}
|
@ -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) +
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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";
|
||||
|
@ -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"
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user