WPS: Use separate list of NFC Password Tokens in the Registrar
This adds a cleaner mechanism for handling NFC Password Tokens in the WPS Registrar. There could be more than one active NFC Password Token in use and as such, a list of tokens needs to be maintained. The old WPS_OOB interface is still using the old mechanism that supports only a single active NFC Password Token. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
bb45b6d79a
commit
0e3c16546b
4 changed files with 150 additions and 9 deletions
|
@ -118,6 +118,12 @@ struct wps_data * wps_init(const struct wps_config *cfg)
|
||||||
*/
|
*/
|
||||||
void wps_deinit(struct wps_data *data)
|
void wps_deinit(struct wps_data *data)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_WPS_NFC
|
||||||
|
if (data->registrar && data->nfc_pw_token)
|
||||||
|
wps_registrar_remove_nfc_pw_token(data->wps->registrar,
|
||||||
|
data->nfc_pw_token);
|
||||||
|
#endif /* CONFIG_WPS_NFC */
|
||||||
|
|
||||||
if (data->wps_pin_revealed) {
|
if (data->wps_pin_revealed) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Full PIN information revealed and "
|
wpa_printf(MSG_DEBUG, "WPS: Full PIN information revealed and "
|
||||||
"negotiation failed");
|
"negotiation failed");
|
||||||
|
@ -136,6 +142,7 @@ void wps_deinit(struct wps_data *data)
|
||||||
wps_device_data_free(&data->peer_dev);
|
wps_device_data_free(&data->peer_dev);
|
||||||
os_free(data->new_ap_settings);
|
os_free(data->new_ap_settings);
|
||||||
dh5_free(data->dh_ctx);
|
dh5_free(data->dh_ctx);
|
||||||
|
os_free(data->nfc_pw_token);
|
||||||
os_free(data);
|
os_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -797,6 +797,9 @@ int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
|
||||||
char *buf, size_t buflen);
|
char *buf, size_t buflen);
|
||||||
int wps_registrar_config_ap(struct wps_registrar *reg,
|
int wps_registrar_config_ap(struct wps_registrar *reg,
|
||||||
struct wps_credential *cred);
|
struct wps_credential *cred);
|
||||||
|
int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg,
|
||||||
|
const u8 *pubkey_hash, u16 pw_id,
|
||||||
|
const u8 *dev_pw, size_t dev_pw_len);
|
||||||
int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
|
int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
|
||||||
const u8 *oob_dev_pw,
|
const u8 *oob_dev_pw,
|
||||||
size_t oob_dev_pw_len);
|
size_t oob_dev_pw_len);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Wi-Fi Protected Setup - internal definitions
|
* Wi-Fi Protected Setup - internal definitions
|
||||||
* Copyright (c) 2008-2009, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -12,6 +12,8 @@
|
||||||
#include "wps.h"
|
#include "wps.h"
|
||||||
#include "wps_attr_parse.h"
|
#include "wps_attr_parse.h"
|
||||||
|
|
||||||
|
struct wps_nfc_pw_token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wps_data - WPS registration protocol data
|
* struct wps_data - WPS registration protocol data
|
||||||
*
|
*
|
||||||
|
@ -115,6 +117,8 @@ struct wps_data {
|
||||||
u8 p2p_dev_addr[ETH_ALEN]; /* P2P Device Address of the client or
|
u8 p2p_dev_addr[ETH_ALEN]; /* P2P Device Address of the client or
|
||||||
* 00:00:00:00:00:00 if not a P2p client */
|
* 00:00:00:00:00:00 if not a P2p client */
|
||||||
int pbc_in_m1;
|
int pbc_in_m1;
|
||||||
|
|
||||||
|
struct wps_nfc_pw_token *nfc_pw_token;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,5 +202,7 @@ void wps_registrar_selected_registrar_changed(struct wps_registrar *reg);
|
||||||
const u8 * wps_authorized_macs(struct wps_registrar *reg, size_t *count);
|
const u8 * wps_authorized_macs(struct wps_registrar *reg, size_t *count);
|
||||||
int wps_registrar_pbc_overlap(struct wps_registrar *reg,
|
int wps_registrar_pbc_overlap(struct wps_registrar *reg,
|
||||||
const u8 *addr, const u8 *uuid_e);
|
const u8 *addr, const u8 *uuid_e);
|
||||||
|
void wps_registrar_remove_nfc_pw_token(struct wps_registrar *reg,
|
||||||
|
struct wps_nfc_pw_token *token);
|
||||||
|
|
||||||
#endif /* WPS_I_H */
|
#endif /* WPS_I_H */
|
||||||
|
|
|
@ -26,6 +26,53 @@
|
||||||
#define WPS_WORKAROUNDS
|
#define WPS_WORKAROUNDS
|
||||||
#endif /* CONFIG_WPS_STRICT */
|
#endif /* CONFIG_WPS_STRICT */
|
||||||
|
|
||||||
|
#ifdef CONFIG_WPS_NFC
|
||||||
|
|
||||||
|
struct wps_nfc_pw_token {
|
||||||
|
struct dl_list list;
|
||||||
|
u8 pubkey_hash[WPS_OOB_PUBKEY_HASH_LEN];
|
||||||
|
u16 pw_id;
|
||||||
|
u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN];
|
||||||
|
size_t dev_pw_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void wps_remove_nfc_pw_token(struct wps_nfc_pw_token *token)
|
||||||
|
{
|
||||||
|
dl_list_del(&token->list);
|
||||||
|
os_free(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wps_free_nfc_pw_tokens(struct dl_list *tokens, u16 pw_id)
|
||||||
|
{
|
||||||
|
struct wps_nfc_pw_token *token, *prev;
|
||||||
|
dl_list_for_each_safe(token, prev, tokens, struct wps_nfc_pw_token,
|
||||||
|
list) {
|
||||||
|
if (pw_id == 0 || pw_id == token->pw_id)
|
||||||
|
wps_remove_nfc_pw_token(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct wps_nfc_pw_token * wps_get_nfc_pw_token(struct dl_list *tokens,
|
||||||
|
u16 pw_id)
|
||||||
|
{
|
||||||
|
struct wps_nfc_pw_token *token;
|
||||||
|
dl_list_for_each(token, tokens, struct wps_nfc_pw_token, list) {
|
||||||
|
if (pw_id == token->pw_id)
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* CONFIG_WPS_NFC */
|
||||||
|
|
||||||
|
#define wps_free_nfc_pw_tokens(t, p) do { } while (0)
|
||||||
|
|
||||||
|
#endif /* CONFIG_WPS_NFC */
|
||||||
|
|
||||||
|
|
||||||
struct wps_uuid_pin {
|
struct wps_uuid_pin {
|
||||||
struct dl_list list;
|
struct dl_list list;
|
||||||
u8 uuid[WPS_UUID_LEN];
|
u8 uuid[WPS_UUID_LEN];
|
||||||
|
@ -113,6 +160,7 @@ struct wps_registrar {
|
||||||
void *cb_ctx;
|
void *cb_ctx;
|
||||||
|
|
||||||
struct dl_list pins;
|
struct dl_list pins;
|
||||||
|
struct dl_list nfc_pw_tokens;
|
||||||
struct wps_pbc_session *pbc_sessions;
|
struct wps_pbc_session *pbc_sessions;
|
||||||
|
|
||||||
int skip_cred_build;
|
int skip_cred_build;
|
||||||
|
@ -591,6 +639,7 @@ wps_registrar_init(struct wps_context *wps,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dl_list_init(®->pins);
|
dl_list_init(®->pins);
|
||||||
|
dl_list_init(®->nfc_pw_tokens);
|
||||||
reg->wps = wps;
|
reg->wps = wps;
|
||||||
reg->new_psk_cb = cfg->new_psk_cb;
|
reg->new_psk_cb = cfg->new_psk_cb;
|
||||||
reg->set_ie_cb = cfg->set_ie_cb;
|
reg->set_ie_cb = cfg->set_ie_cb;
|
||||||
|
@ -634,6 +683,7 @@ void wps_registrar_deinit(struct wps_registrar *reg)
|
||||||
eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
|
eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
|
||||||
eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
|
eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
|
||||||
wps_free_pins(®->pins);
|
wps_free_pins(®->pins);
|
||||||
|
wps_free_nfc_pw_tokens(®->nfc_pw_tokens, 0);
|
||||||
wps_free_pbc_sessions(reg->pbc_sessions);
|
wps_free_pbc_sessions(reg->pbc_sessions);
|
||||||
wpabuf_free(reg->extra_cred);
|
wpabuf_free(reg->extra_cred);
|
||||||
wps_free_devices(reg->devices);
|
wps_free_devices(reg->devices);
|
||||||
|
@ -1255,6 +1305,13 @@ static int wps_get_dev_password(struct wps_data *wps)
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC");
|
wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC");
|
||||||
pin = (const u8 *) "00000000";
|
pin = (const u8 *) "00000000";
|
||||||
pin_len = 8;
|
pin_len = 8;
|
||||||
|
#ifdef CONFIG_WPS_NFC
|
||||||
|
} else if (wps->nfc_pw_token) {
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS: Use OOB Device Password from NFC "
|
||||||
|
"Password Token");
|
||||||
|
pin = wps->nfc_pw_token->dev_pw;
|
||||||
|
pin_len = wps->nfc_pw_token->dev_pw_len;
|
||||||
|
#endif /* CONFIG_WPS_NFC */
|
||||||
} else {
|
} else {
|
||||||
pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
|
pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
|
||||||
&pin_len);
|
&pin_len);
|
||||||
|
@ -2441,8 +2498,34 @@ static enum wps_process_res wps_process_m1(struct wps_data *wps,
|
||||||
return WPS_CONTINUE;
|
return WPS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_WPS_NFC
|
||||||
|
if (wps->dev_pw_id >= 0x10) {
|
||||||
|
struct wps_nfc_pw_token *token;
|
||||||
|
const u8 *addr[1];
|
||||||
|
u8 hash[WPS_HASH_LEN];
|
||||||
|
|
||||||
|
token = wps_get_nfc_pw_token(
|
||||||
|
&wps->wps->registrar->nfc_pw_tokens, wps->dev_pw_id);
|
||||||
|
if (token) {
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS: Found matching NFC "
|
||||||
|
"Password Token");
|
||||||
|
dl_list_del(&token->list);
|
||||||
|
wps->nfc_pw_token = token;
|
||||||
|
|
||||||
|
addr[0] = attr->public_key;
|
||||||
|
sha256_vector(1, addr, &attr->public_key_len, hash);
|
||||||
|
if (os_memcmp(hash, wps->nfc_pw_token->pubkey_hash,
|
||||||
|
WPS_OOB_PUBKEY_HASH_LEN) != 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "WPS: Public Key hash "
|
||||||
|
"mismatch");
|
||||||
|
return WPS_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_WPS_NFC */
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_OOB
|
#ifdef CONFIG_WPS_OOB
|
||||||
if (wps->dev_pw_id >= 0x10 &&
|
if (wps->dev_pw_id >= 0x10 && wps->nfc_pw_token == NULL &&
|
||||||
wps->dev_pw_id != wps->wps->oob_dev_pw_id) {
|
wps->dev_pw_id != wps->wps->oob_dev_pw_id) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: OOB Device Password ID "
|
wpa_printf(MSG_DEBUG, "WPS: OOB Device Password ID "
|
||||||
"%d mismatch", wps->dev_pw_id);
|
"%d mismatch", wps->dev_pw_id);
|
||||||
|
@ -3369,6 +3452,43 @@ int wps_registrar_config_ap(struct wps_registrar *reg,
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_NFC
|
#ifdef CONFIG_WPS_NFC
|
||||||
|
|
||||||
|
int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg,
|
||||||
|
const u8 *pubkey_hash, u16 pw_id,
|
||||||
|
const u8 *dev_pw, size_t dev_pw_len)
|
||||||
|
{
|
||||||
|
struct wps_nfc_pw_token *token;
|
||||||
|
|
||||||
|
if (dev_pw_len > WPS_OOB_DEVICE_PASSWORD_LEN)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
wps_free_nfc_pw_tokens(®->nfc_pw_tokens, pw_id);
|
||||||
|
|
||||||
|
token = os_zalloc(sizeof(*token));
|
||||||
|
if (token == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
os_memcpy(token->pubkey_hash, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
|
||||||
|
token->pw_id = pw_id;
|
||||||
|
os_memcpy(token->dev_pw, dev_pw, dev_pw_len);
|
||||||
|
token->dev_pw_len = dev_pw_len;
|
||||||
|
|
||||||
|
dl_list_add(®->nfc_pw_tokens, &token->list);
|
||||||
|
|
||||||
|
reg->selected_registrar = 1;
|
||||||
|
reg->pbc = 0;
|
||||||
|
wps_registrar_add_authorized_mac(reg,
|
||||||
|
(u8 *) "\xff\xff\xff\xff\xff\xff");
|
||||||
|
wps_registrar_selected_registrar_changed(reg);
|
||||||
|
eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
|
||||||
|
eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
|
||||||
|
wps_registrar_set_selected_timeout,
|
||||||
|
reg, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
|
int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
|
||||||
const u8 *oob_dev_pw,
|
const u8 *oob_dev_pw,
|
||||||
size_t oob_dev_pw_len)
|
size_t oob_dev_pw_len)
|
||||||
|
@ -3396,12 +3516,17 @@ int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
|
||||||
hash, WPS_OOB_PUBKEY_HASH_LEN);
|
hash, WPS_OOB_PUBKEY_HASH_LEN);
|
||||||
wpa_hexdump_key(MSG_DEBUG, "WPS: Device Password", dev_pw, dev_pw_len);
|
wpa_hexdump_key(MSG_DEBUG, "WPS: Device Password", dev_pw, dev_pw_len);
|
||||||
|
|
||||||
reg->wps->oob_dev_pw_id = id;
|
return wps_registrar_add_nfc_pw_token(reg, hash, id, dev_pw,
|
||||||
wpabuf_free(reg->wps->oob_conf.pubkey_hash);
|
dev_pw_len);
|
||||||
reg->wps->oob_conf.pubkey_hash = wpabuf_alloc_copy(
|
|
||||||
hash, WPS_OOB_PUBKEY_HASH_LEN);
|
|
||||||
if (reg->wps->oob_conf.pubkey_hash == NULL)
|
|
||||||
return -1;
|
|
||||||
return wps_registrar_add_pin(reg, NULL, NULL, dev_pw, dev_pw_len, 300);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wps_registrar_remove_nfc_pw_token(struct wps_registrar *reg,
|
||||||
|
struct wps_nfc_pw_token *token)
|
||||||
|
{
|
||||||
|
wps_registrar_remove_authorized_mac(reg,
|
||||||
|
(u8 *) "\xff\xff\xff\xff\xff\xff");
|
||||||
|
wps_registrar_selected_registrar_changed(reg);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_WPS_NFC */
|
#endif /* CONFIG_WPS_NFC */
|
||||||
|
|
Loading…
Reference in a new issue