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:
parent
e205401c72
commit
88c8bf311e
7 changed files with 128 additions and 49 deletions
|
@ -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,
|
||||
const u8 *pin, size_t pin_len,
|
||||
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,
|
||||
const u8 *addr);
|
||||
|
||||
|
|
|
@ -2023,12 +2023,35 @@ int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
|
|||
|
||||
|
||||
#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,
|
||||
const u8 *addr)
|
||||
{
|
||||
struct wps_er_ap *ap;
|
||||
struct wpabuf *ret;
|
||||
struct wps_data data;
|
||||
|
||||
if (er == NULL)
|
||||
return NULL;
|
||||
|
@ -2042,20 +2065,7 @@ struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ret = wpabuf_alloc(500);
|
||||
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;
|
||||
return wps_er_config_token_from_cred(er->wps, ap->ap_settings);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_WPS_NFC */
|
||||
|
|
|
@ -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
|
||||
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
|
||||
media type "application/vnd.wfa.wsc", the NDEF message payload (with or
|
||||
without NDEF encapsulation) can be delivered to wpa_supplicant using the
|
||||
|
|
|
@ -784,7 +784,11 @@ static int wpa_supplicant_ctrl_iface_wps_nfc_config_token(
|
|||
int ndef;
|
||||
struct wpabuf *buf;
|
||||
int res;
|
||||
char *pos;
|
||||
|
||||
pos = os_strchr(cmd, ' ');
|
||||
if (pos)
|
||||
*pos++ = '\0';
|
||||
if (os_strcmp(cmd, "WPS") == 0)
|
||||
ndef = 0;
|
||||
else if (os_strcmp(cmd, "NDEF") == 0)
|
||||
|
@ -792,7 +796,7 @@ static int wpa_supplicant_ctrl_iface_wps_nfc_config_token(
|
|||
else
|
||||
return -1;
|
||||
|
||||
buf = wpas_wps_nfc_config_token(wpa_s, ndef);
|
||||
buf = wpas_wps_nfc_config_token(wpa_s, ndef, pos);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
|
|
|
@ -53,10 +53,12 @@ def wpas_tag_read(message):
|
|||
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()
|
||||
if (wpas == 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")
|
||||
|
||||
|
||||
|
@ -258,9 +260,9 @@ def wps_tag_read(tag):
|
|||
time.sleep(0.1)
|
||||
|
||||
|
||||
def wps_write_config_tag(clf):
|
||||
def wps_write_config_tag(clf, id=None):
|
||||
print "Write WPS config token"
|
||||
data = wpas_get_config_token()
|
||||
data = wpas_get_config_token(id)
|
||||
if (data == None):
|
||||
print "Could not get WPS config token from wpa_supplicant"
|
||||
return
|
||||
|
@ -364,6 +366,10 @@ def main():
|
|||
wps_write_config_tag(clf)
|
||||
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":
|
||||
wps_write_er_config_tag(clf, sys.argv[2])
|
||||
raise SystemExit
|
||||
|
|
|
@ -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 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)
|
||||
return -1;
|
||||
|
||||
os_memset(&cred, 0, sizeof(cred));
|
||||
if (ssid->ssid_len > 32)
|
||||
if (wpas_wps_network_to_cred(ssid, &cred) < 0)
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1886,9 +1896,52 @@ void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
|
|||
|
||||
#ifdef CONFIG_WPS_NFC
|
||||
|
||||
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
|
||||
int ndef)
|
||||
#ifdef CONFIG_WPS_ER
|
||||
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
|
||||
if (wpa_s->ap_iface)
|
||||
return wpas_ap_wps_nfc_config_token(wpa_s, ndef);
|
||||
|
|
|
@ -63,7 +63,7 @@ int wpas_wps_terminate_pending(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);
|
||||
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);
|
||||
int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid);
|
||||
int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
|
||||
|
|
Loading…
Reference in a new issue