WPS NFC: Allow configuration token to be built from network block

"WPS_NFC_CONFIG_TOKEN <WPS/NDEF> <network id>" can now be used to build
an NFC configuration token from a locally configured network.

Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2013-04-01 21:28:57 +03:00
parent e205401c72
commit 88c8bf311e
7 changed files with 128 additions and 49 deletions

View file

@ -802,6 +802,8 @@ int wps_er_set_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr, int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
const u8 *pin, size_t pin_len, const u8 *pin, size_t pin_len,
const struct wps_credential *cred); const struct wps_credential *cred);
struct wpabuf * wps_er_config_token_from_cred(struct wps_context *wps,
struct wps_credential *cred);
struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid, struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
const u8 *addr); const u8 *addr);

View file

@ -2023,12 +2023,35 @@ int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
#ifdef CONFIG_WPS_NFC #ifdef CONFIG_WPS_NFC
struct wpabuf * wps_er_config_token_from_cred(struct wps_context *wps,
struct wps_credential *cred)
{
struct wpabuf *ret;
struct wps_data data;
ret = wpabuf_alloc(500);
if (ret == NULL)
return NULL;
os_memset(&data, 0, sizeof(data));
data.wps = wps;
data.use_cred = cred;
if (wps_build_version(ret) ||
wps_build_cred(&data, ret) ||
wps_build_wfa_ext(ret, 0, NULL, 0)) {
wpabuf_free(ret);
return NULL;
}
return ret;
}
struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid, struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
const u8 *addr) const u8 *addr)
{ {
struct wps_er_ap *ap; struct wps_er_ap *ap;
struct wpabuf *ret;
struct wps_data data;
if (er == NULL) if (er == NULL)
return NULL; return NULL;
@ -2042,20 +2065,7 @@ struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
return NULL; return NULL;
} }
ret = wpabuf_alloc(500); return wps_er_config_token_from_cred(er->wps, ap->ap_settings);
if (ret == NULL)
return NULL;
os_memset(&data, 0, sizeof(data));
data.wps = er->wps;
data.use_cred = ap->ap_settings;
if (wps_build_version(ret) ||
wps_build_cred(&data, ret) ||
wps_build_wfa_ext(ret, 0, NULL, 0)) {
wpabuf_free(ret);
return NULL;
} }
return ret;
}
#endif /* CONFIG_WPS_NFC */ #endif /* CONFIG_WPS_NFC */

View file

@ -346,6 +346,10 @@ tag with an external program. Once written, the NFC configuration token
can be used to touch an NFC interface on a station to provision the can be used to touch an NFC interface on a station to provision the
credentials needed to access the network. credentials needed to access the network.
The "wps_nfc_config_token <WPS/NDEF> <network id>" command can be used
to build an NFC configuration token based on a locally configured
network.
If the station includes NFC interface and reads an NFC tag with a MIME If the station includes NFC interface and reads an NFC tag with a MIME
media type "application/vnd.wfa.wsc", the NDEF message payload (with or media type "application/vnd.wfa.wsc", the NDEF message payload (with or
without NDEF encapsulation) can be delivered to wpa_supplicant using the without NDEF encapsulation) can be delivered to wpa_supplicant using the

View file

@ -784,7 +784,11 @@ static int wpa_supplicant_ctrl_iface_wps_nfc_config_token(
int ndef; int ndef;
struct wpabuf *buf; struct wpabuf *buf;
int res; int res;
char *pos;
pos = os_strchr(cmd, ' ');
if (pos)
*pos++ = '\0';
if (os_strcmp(cmd, "WPS") == 0) if (os_strcmp(cmd, "WPS") == 0)
ndef = 0; ndef = 0;
else if (os_strcmp(cmd, "NDEF") == 0) else if (os_strcmp(cmd, "NDEF") == 0)
@ -792,7 +796,7 @@ static int wpa_supplicant_ctrl_iface_wps_nfc_config_token(
else else
return -1; return -1;
buf = wpas_wps_nfc_config_token(wpa_s, ndef); buf = wpas_wps_nfc_config_token(wpa_s, ndef, pos);
if (buf == NULL) if (buf == NULL)
return -1; return -1;

View file

@ -53,10 +53,12 @@ def wpas_tag_read(message):
print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex")) print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
def wpas_get_config_token(): def wpas_get_config_token(id=None):
wpas = wpas_connect() wpas = wpas_connect()
if (wpas == None): if (wpas == None):
return None return None
if id:
return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF " + id).rstrip().decode("hex")
return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex") return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
@ -258,9 +260,9 @@ def wps_tag_read(tag):
time.sleep(0.1) time.sleep(0.1)
def wps_write_config_tag(clf): def wps_write_config_tag(clf, id=None):
print "Write WPS config token" print "Write WPS config token"
data = wpas_get_config_token() data = wpas_get_config_token(id)
if (data == None): if (data == None):
print "Could not get WPS config token from wpa_supplicant" print "Could not get WPS config token from wpa_supplicant"
return return
@ -364,6 +366,10 @@ def main():
wps_write_config_tag(clf) wps_write_config_tag(clf)
raise SystemExit raise SystemExit
if len(sys.argv) > 2 and sys.argv[1] == "write-config-id":
wps_write_config_tag(clf, sys.argv[2])
raise SystemExit
if len(sys.argv) > 2 and sys.argv[1] == "write-er-config": if len(sys.argv) > 2 and sys.argv[1] == "write-er-config":
wps_write_er_config_tag(clf, sys.argv[2]) wps_write_er_config_tag(clf, sys.argv[2])
raise SystemExit raise SystemExit

View file

@ -1656,6 +1656,40 @@ int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
} }
static int wpas_wps_network_to_cred(struct wpa_ssid *ssid,
struct wps_credential *cred)
{
os_memset(cred, 0, sizeof(*cred));
if (ssid->ssid_len > 32)
return -1;
os_memcpy(cred->ssid, ssid->ssid, ssid->ssid_len);
cred->ssid_len = ssid->ssid_len;
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
cred->auth_type = (ssid->proto & WPA_PROTO_RSN) ?
WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
cred->encr_type = WPS_ENCR_AES;
else
cred->encr_type = WPS_ENCR_TKIP;
if (ssid->passphrase) {
cred->key_len = os_strlen(ssid->passphrase);
if (cred->key_len >= 64)
return -1;
os_memcpy(cred->key, ssid->passphrase, cred->key_len);
} else if (ssid->psk_set) {
cred->key_len = 32;
os_memcpy(cred->key, ssid->psk, 32);
} else
return -1;
} else {
cred->auth_type = WPS_AUTH_OPEN;
cred->encr_type = WPS_ENCR_NONE;
}
return 0;
}
int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid, int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
int id) int id)
{ {
@ -1674,32 +1708,8 @@ int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
if (ssid == NULL || ssid->ssid == NULL) if (ssid == NULL || ssid->ssid == NULL)
return -1; return -1;
os_memset(&cred, 0, sizeof(cred)); if (wpas_wps_network_to_cred(ssid, &cred) < 0)
if (ssid->ssid_len > 32)
return -1; return -1;
os_memcpy(cred.ssid, ssid->ssid, ssid->ssid_len);
cred.ssid_len = ssid->ssid_len;
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
cred.auth_type = (ssid->proto & WPA_PROTO_RSN) ?
WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
cred.encr_type = WPS_ENCR_AES;
else
cred.encr_type = WPS_ENCR_TKIP;
if (ssid->passphrase) {
cred.key_len = os_strlen(ssid->passphrase);
if (cred.key_len >= 64)
return -1;
os_memcpy(cred.key, ssid->passphrase, cred.key_len);
} else if (ssid->psk_set) {
cred.key_len = 32;
os_memcpy(cred.key, ssid->psk, 32);
} else
return -1;
} else {
cred.auth_type = WPS_AUTH_OPEN;
cred.encr_type = WPS_ENCR_NONE;
}
return wps_er_set_config(wpa_s->wps_er, use_uuid, use_addr, &cred); return wps_er_set_config(wpa_s->wps_er, use_uuid, use_addr, &cred);
} }
@ -1886,9 +1896,52 @@ void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
#ifdef CONFIG_WPS_NFC #ifdef CONFIG_WPS_NFC
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s, #ifdef CONFIG_WPS_ER
int ndef) static struct wpabuf *
wpas_wps_network_config_token(struct wpa_supplicant *wpa_s, int ndef,
struct wpa_ssid *ssid)
{ {
struct wpabuf *ret;
struct wps_credential cred;
if (wpas_wps_network_to_cred(ssid, &cred) < 0)
return NULL;
ret = wps_er_config_token_from_cred(wpa_s->wps, &cred);
if (ndef && ret) {
struct wpabuf *tmp;
tmp = ndef_build_wifi(ret);
wpabuf_free(ret);
if (tmp == NULL)
return NULL;
ret = tmp;
}
return ret;
}
#endif /* CONFIG_WPS_ER */
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
int ndef, const char *id_str)
{
#ifdef CONFIG_WPS_ER
if (id_str) {
int id;
char *end = NULL;
struct wpa_ssid *ssid;
id = strtol(id_str, &end, 10);
if (end && *end)
return NULL;
ssid = wpa_config_get_network(wpa_s->conf, id);
if (ssid == NULL)
return NULL;
return wpas_wps_network_config_token(wpa_s, ndef, ssid);
}
#endif /* CONFIG_WPS_ER */
#ifdef CONFIG_AP #ifdef CONFIG_AP
if (wpa_s->ap_iface) if (wpa_s->ap_iface)
return wpas_ap_wps_nfc_config_token(wpa_s, ndef); return wpas_ap_wps_nfc_config_token(wpa_s, ndef);

View file

@ -63,7 +63,7 @@ int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s);
int wpas_wps_in_progress(struct wpa_supplicant *wpa_s); int wpas_wps_in_progress(struct wpa_supplicant *wpa_s);
void wpas_wps_update_config(struct wpa_supplicant *wpa_s); void wpas_wps_update_config(struct wpa_supplicant *wpa_s);
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s, struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
int ndef); int ndef, const char *id_str);
struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef); struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef);
int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid); int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid);
int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s, int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,