aboutsummaryrefslogtreecommitdiffstats
path: root/src/wps
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-06-27 22:15:55 +0300
committerJouni Malinen <j@w1.fi>2012-06-27 22:15:55 +0300
commit0e3c16546b419fc95cd6c0e7131a9114c075f34b (patch)
tree9a06aa8e594e900871e2754892f950fb73bba06a /src/wps
parentbb45b6d79ae71274e7f8936a73cc9926c914bc10 (diff)
downloadexternal_wpa_supplicant_8_ti-0e3c16546b419fc95cd6c0e7131a9114c075f34b.zip
external_wpa_supplicant_8_ti-0e3c16546b419fc95cd6c0e7131a9114c075f34b.tar.gz
external_wpa_supplicant_8_ti-0e3c16546b419fc95cd6c0e7131a9114c075f34b.tar.bz2
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>
Diffstat (limited to 'src/wps')
-rw-r--r--src/wps/wps.c7
-rw-r--r--src/wps/wps.h3
-rw-r--r--src/wps/wps_i.h8
-rw-r--r--src/wps/wps_registrar.c141
4 files changed, 150 insertions, 9 deletions
diff --git a/src/wps/wps.c b/src/wps/wps.c
index 64b80d8..26542a0 100644
--- a/src/wps/wps.c
+++ b/src/wps/wps.c
@@ -118,6 +118,12 @@ struct wps_data * wps_init(const struct wps_config *cfg)
*/
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) {
wpa_printf(MSG_DEBUG, "WPS: Full PIN information revealed and "
"negotiation failed");
@@ -136,6 +142,7 @@ void wps_deinit(struct wps_data *data)
wps_device_data_free(&data->peer_dev);
os_free(data->new_ap_settings);
dh5_free(data->dh_ctx);
+ os_free(data->nfc_pw_token);
os_free(data);
}
diff --git a/src/wps/wps.h b/src/wps/wps.h
index 66fccd7..927102f 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -797,6 +797,9 @@ int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
char *buf, size_t buflen);
int wps_registrar_config_ap(struct wps_registrar *reg,
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,
const u8 *oob_dev_pw,
size_t oob_dev_pw_len);
diff --git a/src/wps/wps_i.h b/src/wps/wps_i.h
index a50db3f..86ad248 100644
--- a/src/wps/wps_i.h
+++ b/src/wps/wps_i.h
@@ -1,6 +1,6 @@
/*
* 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.
* See README for more details.
@@ -12,6 +12,8 @@
#include "wps.h"
#include "wps_attr_parse.h"
+struct wps_nfc_pw_token;
+
/**
* 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
* 00:00:00:00:00:00 if not a P2p client */
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);
int wps_registrar_pbc_overlap(struct wps_registrar *reg,
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 */
diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c
index 1bef660..154c2b4 100644
--- a/src/wps/wps_registrar.c
+++ b/src/wps/wps_registrar.c
@@ -26,6 +26,53 @@
#define WPS_WORKAROUNDS
#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 dl_list list;
u8 uuid[WPS_UUID_LEN];
@@ -113,6 +160,7 @@ struct wps_registrar {
void *cb_ctx;
struct dl_list pins;
+ struct dl_list nfc_pw_tokens;
struct wps_pbc_session *pbc_sessions;
int skip_cred_build;
@@ -591,6 +639,7 @@ wps_registrar_init(struct wps_context *wps,
return NULL;
dl_list_init(&reg->pins);
+ dl_list_init(&reg->nfc_pw_tokens);
reg->wps = wps;
reg->new_psk_cb = cfg->new_psk_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_set_selected_timeout, reg, NULL);
wps_free_pins(&reg->pins);
+ wps_free_nfc_pw_tokens(&reg->nfc_pw_tokens, 0);
wps_free_pbc_sessions(reg->pbc_sessions);
wpabuf_free(reg->extra_cred);
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");
pin = (const u8 *) "00000000";
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 {
pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
&pin_len);
@@ -2441,8 +2498,34 @@ static enum wps_process_res wps_process_m1(struct wps_data *wps,
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
- 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) {
wpa_printf(MSG_DEBUG, "WPS: OOB Device Password ID "
"%d mismatch", wps->dev_pw_id);
@@ -3369,6 +3452,43 @@ int wps_registrar_config_ap(struct wps_registrar *reg,
#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(&reg->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(&reg->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,
const u8 *oob_dev_pw,
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);
wpa_hexdump_key(MSG_DEBUG, "WPS: Device Password", dev_pw, dev_pw_len);
- reg->wps->oob_dev_pw_id = id;
- wpabuf_free(reg->wps->oob_conf.pubkey_hash);
- 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);
+ return wps_registrar_add_nfc_pw_token(reg, hash, id, dev_pw,
+ dev_pw_len);
}
+
+
+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 */