This commit was generated by cvs2svn to compensate for changes in r177576,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
9c6231a737
@ -1,5 +1,25 @@
|
||||
ChangeLog for hostapd
|
||||
|
||||
2008-02-19 - v0.5.10
|
||||
* fixed EAP-SIM and EAP-AKA message parser to validate attribute
|
||||
lengths properly to avoid potential crash caused by invalid messages
|
||||
* fixed Reassociation Response callback processing when using internal
|
||||
MLME (driver_{hostap,devicescape,test}.c)
|
||||
* fixed EAP-SIM/AKA realm processing to allow decorated usernames to
|
||||
be used
|
||||
* added a workaround for EAP-SIM/AKA peers that include incorrect null
|
||||
termination in the username
|
||||
* fixed EAP-SIM Start response processing for fast reauthentication
|
||||
case
|
||||
* copy optional Proxy-State attributes into RADIUS response when acting
|
||||
as a RADIUS authentication server
|
||||
|
||||
2007-12-02 - v0.5.9
|
||||
* updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
|
||||
draft (draft-ietf-emu-eap-gpsk-07.txt)
|
||||
* fixed debugging code not to use potentially unaligned read to fetch
|
||||
IPv4 addresses
|
||||
|
||||
2007-05-28 - v0.5.8
|
||||
* updated driver_devicescape.c to build with the current
|
||||
wireless-dev.git tree and net/d80211 changes
|
||||
|
@ -2,7 +2,7 @@ hostapd - user space IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP
|
||||
Authenticator and RADIUS authentication server
|
||||
================================================================
|
||||
|
||||
Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi> and contributors
|
||||
Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi> and contributors
|
||||
All Rights Reserved.
|
||||
|
||||
This program is dual-licensed under both the GPL version 2 and BSD
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -170,9 +170,10 @@ static int test_driver_send_mgmt_frame(void *priv, const void *buf,
|
||||
u16 fc;
|
||||
|
||||
if (drv->test_socket < 0 || len < 10 || drv->socket_dir == NULL) {
|
||||
wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d len=%d "
|
||||
"socket_dir=%p)",
|
||||
__func__, drv->test_socket, len, drv->socket_dir);
|
||||
wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d len=%lu"
|
||||
" socket_dir=%p)",
|
||||
__func__, drv->test_socket, (unsigned long) len,
|
||||
drv->socket_dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / EAP-AKA (RFC 4187)
|
||||
* Copyright (c) 2005-2007, 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
|
||||
@ -124,6 +124,14 @@ static u8 * eap_aka_build_identity(struct eap_sm *sm,
|
||||
sm->identity_len)) {
|
||||
wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ");
|
||||
eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, NULL, 0);
|
||||
} else {
|
||||
/*
|
||||
* RFC 4187, Chap. 4.1.4 recommends that identity from EAP is
|
||||
* ignored and the AKA/Identity is used to request the
|
||||
* identity.
|
||||
*/
|
||||
wpa_printf(MSG_DEBUG, " AT_ANY_ID_REQ");
|
||||
eap_sim_msg_add(msg, EAP_SIM_AT_ANY_ID_REQ, 0, NULL, 0);
|
||||
}
|
||||
return eap_sim_msg_finish(msg, reqDataLen, NULL, NULL, 0);
|
||||
}
|
||||
@ -445,10 +453,16 @@ static void eap_aka_determine_identity(struct eap_sm *sm,
|
||||
sm->method_pending = METHOD_PENDING_NONE;
|
||||
}
|
||||
|
||||
identity_len = sm->identity_len;
|
||||
while (identity_len > 0 && sm->identity[identity_len - 1] == '\0') {
|
||||
wpa_printf(MSG_DEBUG, "EAP-AKA: Workaround - drop last null "
|
||||
"character from identity");
|
||||
identity_len--;
|
||||
}
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Identity for MK derivation",
|
||||
sm->identity, sm->identity_len);
|
||||
sm->identity, identity_len);
|
||||
|
||||
eap_aka_derive_mk(sm->identity, sm->identity_len, data->ik, data->ck,
|
||||
eap_aka_derive_mk(sm->identity, identity_len, data->ik, data->ck,
|
||||
data->mk);
|
||||
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
|
||||
data->emsk);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* hostapd / EAP-GPSK (draft-ietf-emu-eap-gpsk-03.txt) server
|
||||
* hostapd / EAP-GPSK (draft-ietf-emu-eap-gpsk-08.txt) server
|
||||
* Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -23,15 +23,15 @@
|
||||
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];
|
||||
size_t sk_len;
|
||||
u8 pk[EAP_GPSK_MAX_PK_LEN];
|
||||
size_t pk_len;
|
||||
u8 *id_client;
|
||||
size_t id_client_len;
|
||||
u8 *id_peer;
|
||||
size_t id_peer_len;
|
||||
u8 *id_server;
|
||||
size_t id_server_len;
|
||||
#define MAX_NUM_CSUITES 2
|
||||
@ -85,17 +85,17 @@ static void * eap_gpsk_init(struct eap_sm *sm)
|
||||
data->csuite_count = 0;
|
||||
if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF,
|
||||
EAP_GPSK_CIPHER_AES)) {
|
||||
WPA_PUT_BE24(data->csuite_list[data->csuite_count].vendor,
|
||||
WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor,
|
||||
EAP_GPSK_VENDOR_IETF);
|
||||
WPA_PUT_BE24(data->csuite_list[data->csuite_count].specifier,
|
||||
WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier,
|
||||
EAP_GPSK_CIPHER_AES);
|
||||
data->csuite_count++;
|
||||
}
|
||||
if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF,
|
||||
EAP_GPSK_CIPHER_SHA256)) {
|
||||
WPA_PUT_BE24(data->csuite_list[data->csuite_count].vendor,
|
||||
WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor,
|
||||
EAP_GPSK_VENDOR_IETF);
|
||||
WPA_PUT_BE24(data->csuite_list[data->csuite_count].specifier,
|
||||
WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier,
|
||||
EAP_GPSK_CIPHER_SHA256);
|
||||
data->csuite_count++;
|
||||
}
|
||||
@ -108,7 +108,7 @@ static void eap_gpsk_reset(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_gpsk_data *data = priv;
|
||||
free(data->id_server);
|
||||
free(data->id_client);
|
||||
free(data->id_peer);
|
||||
free(data);
|
||||
}
|
||||
|
||||
@ -174,8 +174,8 @@ static u8 * eap_gpsk_build_gpsk_3(struct eap_sm *sm,
|
||||
wpa_printf(MSG_DEBUG, "EAP-GPSK: Request/GPSK-3");
|
||||
|
||||
miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
|
||||
len = 1 + 2 * EAP_GPSK_RAND_LEN + sizeof(struct eap_gpsk_csuite) + 2 +
|
||||
miclen;
|
||||
len = 1 + 2 * EAP_GPSK_RAND_LEN + 2 + data->id_server_len +
|
||||
sizeof(struct eap_gpsk_csuite) + 2 + miclen;
|
||||
req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, reqDataLen,
|
||||
len, EAP_CODE_REQUEST, id, &pos);
|
||||
if (req == NULL) {
|
||||
@ -188,13 +188,18 @@ static u8 * eap_gpsk_build_gpsk_3(struct eap_sm *sm,
|
||||
*pos++ = EAP_GPSK_OPCODE_GPSK_3;
|
||||
start = pos;
|
||||
|
||||
memcpy(pos, data->rand_client, EAP_GPSK_RAND_LEN);
|
||||
memcpy(pos, data->rand_peer, EAP_GPSK_RAND_LEN);
|
||||
pos += EAP_GPSK_RAND_LEN;
|
||||
memcpy(pos, data->rand_server, EAP_GPSK_RAND_LEN);
|
||||
pos += EAP_GPSK_RAND_LEN;
|
||||
WPA_PUT_BE16(pos, data->id_server_len);
|
||||
pos += 2;
|
||||
if (data->id_server)
|
||||
memcpy(pos, data->id_server, data->id_server_len);
|
||||
pos += data->id_server_len;
|
||||
csuite = (struct eap_gpsk_csuite *) pos;
|
||||
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);
|
||||
pos += sizeof(*csuite);
|
||||
|
||||
/* no PD_Payload_2 */
|
||||
@ -282,7 +287,7 @@ static void eap_gpsk_process_gpsk_2(struct eap_sm *sm,
|
||||
|
||||
if (end - pos < 2) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
|
||||
"ID_Client length");
|
||||
"ID_Peer length");
|
||||
eap_gpsk_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
@ -290,21 +295,21 @@ static void eap_gpsk_process_gpsk_2(struct eap_sm *sm,
|
||||
pos += 2;
|
||||
if (end - pos < alen) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
|
||||
"ID_Client");
|
||||
"ID_Peer");
|
||||
eap_gpsk_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
free(data->id_client);
|
||||
data->id_client = malloc(alen);
|
||||
if (data->id_client == NULL) {
|
||||
free(data->id_peer);
|
||||
data->id_peer = malloc(alen);
|
||||
if (data->id_peer == NULL) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-GPSK: Not enough memory to store "
|
||||
"%d-octet ID_Client", alen);
|
||||
"%d-octet ID_Peer", alen);
|
||||
return;
|
||||
}
|
||||
memcpy(data->id_client, pos, alen);
|
||||
data->id_client_len = alen;
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Client",
|
||||
data->id_client, data->id_client_len);
|
||||
memcpy(data->id_peer, pos, alen);
|
||||
data->id_peer_len = alen;
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Peer",
|
||||
data->id_peer, data->id_peer_len);
|
||||
pos += alen;
|
||||
|
||||
if (end - pos < 2) {
|
||||
@ -332,13 +337,13 @@ static void eap_gpsk_process_gpsk_2(struct eap_sm *sm,
|
||||
|
||||
if (end - pos < EAP_GPSK_RAND_LEN) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
|
||||
"RAND_Client");
|
||||
"RAND_Peer");
|
||||
eap_gpsk_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
memcpy(data->rand_client, pos, EAP_GPSK_RAND_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Client",
|
||||
data->rand_client, EAP_GPSK_RAND_LEN);
|
||||
memcpy(data->rand_peer, pos, EAP_GPSK_RAND_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer",
|
||||
data->rand_peer, EAP_GPSK_RAND_LEN);
|
||||
pos += EAP_GPSK_RAND_LEN;
|
||||
|
||||
if (end - pos < EAP_GPSK_RAND_LEN) {
|
||||
@ -397,13 +402,13 @@ static void eap_gpsk_process_gpsk_2(struct eap_sm *sm,
|
||||
if (i == data->csuite_count) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-GPSK: Peer selected unsupported "
|
||||
"ciphersuite %d:%d",
|
||||
WPA_GET_BE24(csuite->vendor),
|
||||
WPA_GET_BE24(csuite->specifier));
|
||||
WPA_GET_BE32(csuite->vendor),
|
||||
WPA_GET_BE16(csuite->specifier));
|
||||
eap_gpsk_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
data->vendor = WPA_GET_BE24(csuite->vendor);
|
||||
data->specifier = WPA_GET_BE24(csuite->specifier);
|
||||
data->vendor = WPA_GET_BE32(csuite->vendor);
|
||||
data->specifier = WPA_GET_BE16(csuite->specifier);
|
||||
wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_Sel %d:%d",
|
||||
data->vendor, data->specifier);
|
||||
pos += sizeof(*csuite);
|
||||
@ -434,8 +439,8 @@ static void eap_gpsk_process_gpsk_2(struct eap_sm *sm,
|
||||
|
||||
if (eap_gpsk_derive_keys(sm->user->password, sm->user->password_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,
|
||||
|
@ -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
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / EAP-SIM (RFC 4186)
|
||||
* Copyright (c) 2005-2007, 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
|
||||
@ -110,6 +110,13 @@ static u8 * eap_sim_build_start(struct eap_sm *sm, struct eap_sim_data *data,
|
||||
sm->identity_len)) {
|
||||
wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ");
|
||||
eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, NULL, 0);
|
||||
} else {
|
||||
/*
|
||||
* RFC 4186, Chap. 4.2.4 recommends that identity from EAP is
|
||||
* ignored and the SIM/Start is used to request the identity.
|
||||
*/
|
||||
wpa_printf(MSG_DEBUG, " AT_ANY_ID_REQ");
|
||||
eap_sim_msg_add(msg, EAP_SIM_AT_ANY_ID_REQ, 0, NULL, 0);
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, " AT_VERSION_LIST");
|
||||
ver[0] = 0;
|
||||
@ -331,20 +338,6 @@ static void eap_sim_process_start(struct eap_sm *sm,
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-SIM: Receive start response");
|
||||
|
||||
if (attr->nonce_mt == NULL || attr->selected_version < 0) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-SIM: Start/Response missing "
|
||||
"required attributes");
|
||||
eap_sim_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!eap_sim_supported_ver(data, attr->selected_version)) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-SIM: Peer selected unsupported "
|
||||
"version %d", attr->selected_version);
|
||||
eap_sim_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (attr->identity) {
|
||||
free(sm->identity);
|
||||
sm->identity = malloc(attr->identity_len);
|
||||
@ -398,6 +391,20 @@ static void eap_sim_process_start(struct eap_sm *sm,
|
||||
return;
|
||||
}
|
||||
|
||||
if (attr->nonce_mt == NULL || attr->selected_version < 0) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-SIM: Start/Response missing "
|
||||
"required attributes");
|
||||
eap_sim_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!eap_sim_supported_ver(data, attr->selected_version)) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-SIM: Peer selected unsupported "
|
||||
"version %d", attr->selected_version);
|
||||
eap_sim_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
data->counter = 0; /* reset re-auth counter since this is full auth */
|
||||
data->reauth = NULL;
|
||||
|
||||
@ -418,12 +425,18 @@ static void eap_sim_process_start(struct eap_sm *sm,
|
||||
return;
|
||||
}
|
||||
|
||||
identity_len = sm->identity_len;
|
||||
while (identity_len > 0 && sm->identity[identity_len - 1] == '\0') {
|
||||
wpa_printf(MSG_DEBUG, "EAP-SIM: Workaround - drop last null "
|
||||
"character from identity");
|
||||
identity_len--;
|
||||
}
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity for MK derivation",
|
||||
sm->identity, sm->identity_len);
|
||||
sm->identity, identity_len);
|
||||
|
||||
memcpy(data->nonce_mt, attr->nonce_mt, EAP_SIM_NONCE_MT_LEN);
|
||||
WPA_PUT_BE16(ver_list, EAP_SIM_VERSION);
|
||||
eap_sim_derive_mk(sm->identity, sm->identity_len, attr->nonce_mt,
|
||||
eap_sim_derive_mk(sm->identity, identity_len, attr->nonce_mt,
|
||||
attr->selected_version, ver_list, sizeof(ver_list),
|
||||
data->num_chal, (const u8 *) data->kc, data->mk);
|
||||
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
|
||||
|
@ -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",
|
||||
|
@ -554,8 +554,7 @@ int eap_sim_db_get_gsm_triplets(void *priv, const u8 *identity,
|
||||
size_t i;
|
||||
char msg[40];
|
||||
|
||||
if (identity_len < 2 || identity[0] != EAP_SIM_PERMANENT_PREFIX ||
|
||||
identity_len + 1 > sizeof(entry->imsi)) {
|
||||
if (identity_len < 2 || identity[0] != EAP_SIM_PERMANENT_PREFIX) {
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity",
|
||||
identity, identity_len);
|
||||
return EAP_SIM_DB_FAILURE;
|
||||
@ -568,6 +567,11 @@ int eap_sim_db_get_gsm_triplets(void *priv, const u8 *identity,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (identity_len + 1 > sizeof(entry->imsi)) {
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity",
|
||||
identity, identity_len);
|
||||
return EAP_SIM_DB_FAILURE;
|
||||
}
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: Get GSM triplets for IMSI",
|
||||
identity, identity_len);
|
||||
|
||||
@ -1117,8 +1121,7 @@ int eap_sim_db_get_aka_auth(void *priv, const u8 *identity,
|
||||
char msg[40];
|
||||
|
||||
if (identity_len < 2 || identity == NULL ||
|
||||
identity[0] != EAP_AKA_PERMANENT_PREFIX ||
|
||||
identity_len + 1 > sizeof(entry->imsi)) {
|
||||
identity[0] != EAP_AKA_PERMANENT_PREFIX) {
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity",
|
||||
identity, identity_len);
|
||||
return EAP_SIM_DB_FAILURE;
|
||||
@ -1131,6 +1134,11 @@ int eap_sim_db_get_aka_auth(void *priv, const u8 *identity,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (identity_len + 1 > sizeof(entry->imsi)) {
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity",
|
||||
identity, identity_len);
|
||||
return EAP_SIM_DB_FAILURE;
|
||||
}
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI",
|
||||
identity, identity_len);
|
||||
|
||||
@ -1213,9 +1221,23 @@ int eap_sim_db_resynchronize(void *priv, const u8 *identity,
|
||||
const u8 *_rand)
|
||||
{
|
||||
struct eap_sim_db_data *data = priv;
|
||||
size_t i;
|
||||
|
||||
if (identity_len < 2 || identity[0] != EAP_AKA_PERMANENT_PREFIX ||
|
||||
identity_len > 20) {
|
||||
if (identity_len < 2 || identity == NULL ||
|
||||
identity[0] != EAP_AKA_PERMANENT_PREFIX) {
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity",
|
||||
identity, identity_len);
|
||||
return -1;
|
||||
}
|
||||
identity++;
|
||||
identity_len--;
|
||||
for (i = 0; i < identity_len; i++) {
|
||||
if (identity[i] == '@') {
|
||||
identity_len = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (identity_len > 20) {
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity",
|
||||
identity, identity_len);
|
||||
return -1;
|
||||
@ -1226,10 +1248,10 @@ int eap_sim_db_resynchronize(void *priv, const u8 *identity,
|
||||
int len, ret;
|
||||
|
||||
len = snprintf(msg, sizeof(msg), "AKA-AUTS ");
|
||||
if (len < 0 || len + identity_len - 1 >= sizeof(msg))
|
||||
if (len < 0 || len + identity_len >= sizeof(msg))
|
||||
return -1;
|
||||
memcpy(msg + len, identity + 1, identity_len - 1);
|
||||
len += identity_len - 1;
|
||||
memcpy(msg + len, identity, identity_len);
|
||||
len += identity_len;
|
||||
|
||||
ret = snprintf(msg + len, sizeof(msg) - len, " ");
|
||||
if (ret < 0 || (size_t) ret >= sizeof(msg) - len)
|
||||
@ -1244,7 +1266,7 @@ int eap_sim_db_resynchronize(void *priv, const u8 *identity,
|
||||
len += wpa_snprintf_hex(msg + len, sizeof(msg) - len,
|
||||
_rand, EAP_AKA_RAND_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-SIM DB: reporting AKA AUTS for "
|
||||
"IMSI", identity + 1, identity_len - 1);
|
||||
"IMSI", identity, identity_len);
|
||||
if (eap_sim_db_send(data, msg, len) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
@ -113,6 +113,11 @@ int eap_tls_data_reassemble(struct eap_sm *sm, struct eap_ssl_data *data,
|
||||
u8 *buf;
|
||||
|
||||
if (data->tls_in_left > *in_len || data->tls_in) {
|
||||
if (*in_len == 0) {
|
||||
wpa_printf(MSG_INFO, "SSL: Empty fragment when trying "
|
||||
"to reassemble");
|
||||
return -1;
|
||||
}
|
||||
if (data->tls_in_len + *in_len > 65536) {
|
||||
/* Limit length to avoid rogue peers from causing large
|
||||
* memory allocations. */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / Initialization and configuration
|
||||
* Copyright (c) 2002-2007, 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
|
||||
@ -1576,7 +1576,7 @@ static void show_version(void)
|
||||
"hostapd v" VERSION_STR "\n"
|
||||
"User space daemon for IEEE 802.11 AP management,\n"
|
||||
"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
|
||||
"Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi> "
|
||||
"Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi> "
|
||||
"and contributors\n");
|
||||
}
|
||||
|
||||
|
@ -388,7 +388,7 @@ wme_ac_vo_acm=0
|
||||
# Optional displayable message sent with EAP Request-Identity. The first \0
|
||||
# in this string will be converted to ASCII-0 (nul). This can be used to
|
||||
# separate network info (comma separated list of attribute=value pairs); see,
|
||||
# e.g., draft-adrangi-eap-network-discovery-07.txt.
|
||||
# e.g., RFC 4284.
|
||||
#eap_message=hello
|
||||
#eap_message=hello\0networkid=netw,nasid=foo,portid=0,NAIRealms=example.com
|
||||
|
||||
|
@ -1436,8 +1436,8 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
|
||||
return;
|
||||
}
|
||||
|
||||
if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
|
||||
sizeof(mgmt->u.assoc_req))) {
|
||||
if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
|
||||
sizeof(mgmt->u.assoc_resp))) {
|
||||
printf("handle_assoc_cb(reassoc=%d) - too short payload "
|
||||
"(len=%lu)\n", reassoc, (unsigned long) len);
|
||||
return;
|
||||
|
@ -59,7 +59,7 @@ ssid=wpa-test
|
||||
# Optional displayable message sent with EAP Request-Identity. The first \0
|
||||
# in this string will be converted to ASCII-0 (nul). This can be used to
|
||||
# separate network info (comma separated list of attribute=value pairs); see,
|
||||
# e.g., draft-adrangi-eap-network-discovery-07.txt.
|
||||
# e.g., RFC 4284.
|
||||
#eap_message=hello
|
||||
#eap_message=hello\0networkid=netw,nasid=foo,portid=0,NAIRealms=example.com
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / RADIUS authentication server
|
||||
* 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
|
||||
@ -376,6 +376,13 @@ radius_server_encapsulate_eap(struct radius_server_data *data,
|
||||
}
|
||||
}
|
||||
|
||||
if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
|
||||
RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
|
||||
radius_msg_free(msg);
|
||||
os_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
|
||||
client->shared_secret_len,
|
||||
request->hdr->authenticator) < 0) {
|
||||
@ -414,6 +421,12 @@ static int radius_server_reject(struct radius_server_data *data,
|
||||
RADIUS_DEBUG("Failed to add EAP-Message attribute");
|
||||
}
|
||||
|
||||
if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
|
||||
RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
|
||||
radius_msg_free(msg);
|
||||
os_free(msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
|
||||
client->shared_secret_len,
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user