Commit 33e38bfa authored by Dmitry Shmidt's avatar Dmitry Shmidt
Browse files

Accumulative patch from commit f8361e3d681e55efead2aac79fedf4b232d533fb


TDLS: Pass peer's VHT Capability information during sta_add
WPS: Clear sent_carrier to avoid errors in python script
WPS: Fix OOB Device Password use in PSK1,PSK1 derivation
WPS: Add AP mode NFC connection handover with wpa_supplicant/nfcpy
WPS NFC: Add connection handover support for ER
WPS: Add wps-er-config command for writing config token from ER

Change-Id: I8934dcffb9f66bd3a2f840b78d72c9dd6cecf61d
Signed-off-by: default avatarDmitry Shmidt <dimitrysh@google.com>
parent 33077b18
......@@ -120,6 +120,7 @@ def wps_handover_resp(peer):
print "Trying to handle WPS handover"
srv = HandoverServer()
srv.sent_carrier = None
nfc.llcp.activate(peer);
......
......@@ -1612,6 +1612,7 @@ struct wpabuf * hostapd_wps_nfc_token_gen(struct hostapd_data *hapd, int ndef)
int hostapd_wps_nfc_token_enable(struct hostapd_data *hapd)
{
struct wps_context *wps = hapd->wps;
struct wpabuf *pw;
if (wps == NULL)
return -1;
......@@ -1626,7 +1627,16 @@ int hostapd_wps_nfc_token_enable(struct hostapd_data *hapd)
wps->ap_nfc_dev_pw_id = hapd->conf->wps_nfc_dev_pw_id;
wps->ap_nfc_dh_pubkey = wpabuf_dup(hapd->conf->wps_nfc_dh_pubkey);
wps->ap_nfc_dh_privkey = wpabuf_dup(hapd->conf->wps_nfc_dh_privkey);
wps->ap_nfc_dev_pw = wpabuf_dup(hapd->conf->wps_nfc_dev_pw);
pw = hapd->conf->wps_nfc_dev_pw;
wps->ap_nfc_dev_pw = wpabuf_alloc(
wpabuf_len(pw) * 2 + 1);
if (wps->ap_nfc_dev_pw) {
wpa_snprintf_hex_uppercase(
(char *) wpabuf_put(wps->ap_nfc_dev_pw,
wpabuf_len(pw) * 2),
wpabuf_len(pw) * 2 + 1,
wpabuf_head(pw), wpabuf_len(pw));
}
if (!wps->ap_nfc_dh_pubkey || !wps->ap_nfc_dh_privkey ||
!wps->ap_nfc_dev_pw) {
......
......@@ -137,7 +137,6 @@ static void * eap_wsc_init(struct eap_sm *sm)
struct wps_context *wps;
struct wps_credential new_ap_settings;
int res;
u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN];
int nfc = 0;
wps = sm->wps;
......@@ -186,14 +185,6 @@ static void * eap_wsc_init(struct eap_sm *sm)
while (*pos != '\0' && *pos != ' ')
pos++;
cfg.pin_len = pos - (const char *) cfg.pin;
if (cfg.pin_len >= WPS_OOB_DEVICE_PASSWORD_MIN_LEN * 2 &&
cfg.pin_len <= WPS_OOB_DEVICE_PASSWORD_LEN * 2 &&
hexstr2bin((const char *) cfg.pin, dev_pw,
cfg.pin_len / 2) == 0) {
/* Convert OOB Device Password to binary */
cfg.pin = dev_pw;
cfg.pin_len /= 2;
}
if (cfg.pin_len == 6 &&
os_strncmp((const char *) cfg.pin, "nfc-pw", 6) == 0) {
cfg.pin = NULL;
......
......@@ -122,6 +122,7 @@ struct wpa_tdls_peer {
size_t supp_rates_len;
struct ieee80211_ht_capabilities *ht_capabilities;
struct ieee80211_vht_capabilities *vht_capabilities;
u8 qos_info;
......@@ -620,6 +621,8 @@ static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
peer->sm_tmr.buf = NULL;
os_free(peer->ht_capabilities);
peer->ht_capabilities = NULL;
os_free(peer->vht_capabilities);
peer->vht_capabilities = NULL;
os_free(peer->ext_capab);
peer->ext_capab = NULL;
peer->rsnie_i_len = peer->rsnie_p_len = 0;
......@@ -1370,6 +1373,34 @@ static int copy_peer_ht_capab(const struct wpa_eapol_ie_parse *kde,
}
static int copy_peer_vht_capab(const struct wpa_eapol_ie_parse *kde,
struct wpa_tdls_peer *peer)
{
if (!kde->vht_capabilities ||
kde->vht_capabilities_len <
sizeof(struct ieee80211_vht_capabilities) ) {
wpa_printf(MSG_DEBUG, "TDLS: No supported vht capabilities "
"received");
return 0;
}
if (!peer->vht_capabilities) {
peer->vht_capabilities =
os_zalloc(sizeof(struct ieee80211_vht_capabilities));
if (peer->vht_capabilities == NULL)
return -1;
}
os_memcpy(peer->vht_capabilities, kde->vht_capabilities,
sizeof(struct ieee80211_vht_capabilities));
wpa_hexdump(MSG_DEBUG, "TDLS: Peer VHT capabilities",
(u8 *) peer->vht_capabilities,
sizeof(struct ieee80211_vht_capabilities));
return 0;
}
static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde,
struct wpa_tdls_peer *peer)
{
......@@ -1466,6 +1497,9 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
if (copy_peer_ht_capab(&kde, peer) < 0)
goto error;
if (copy_peer_vht_capab(&kde, peer) < 0)
goto error;
if (copy_peer_ext_capab(&kde, peer) < 0)
goto error;
......@@ -1694,7 +1728,7 @@ skip_rsn:
skip_rsn_check:
/* add the peer to the driver as a "setup in progress" peer */
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, 0,
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, NULL, 0,
NULL, 0);
wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
......@@ -1738,8 +1772,9 @@ static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
/* add supported rates, capabilities, and qos_info to the TDLS peer */
wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
peer->supp_rates, peer->supp_rates_len,
peer->ht_capabilities, peer->qos_info,
peer->ext_capab, peer->ext_capab_len);
peer->ht_capabilities, peer->vht_capabilities,
peer->qos_info, peer->ext_capab,
peer->ext_capab_len);
wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
}
......@@ -1838,6 +1873,9 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
if (copy_peer_ht_capab(&kde, peer) < 0)
goto error;
if (copy_peer_vht_capab(&kde, peer) < 0)
goto error;
if (copy_peer_ext_capab(&kde, peer) < 0)
goto error;
......@@ -2146,7 +2184,7 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
peer->initiator = 1;
/* add the peer to the driver as a "setup in progress" peer */
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, 0,
wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, NULL, 0,
NULL, 0);
if (wpa_tdls_send_tpk_m1(sm, peer) < 0) {
......
......@@ -60,6 +60,7 @@ struct wpa_sm_ctx {
u16 capability, const u8 *supp_rates,
size_t supp_rates_len,
const struct ieee80211_ht_capabilities *ht_capab,
const struct ieee80211_vht_capabilities *vht_capab,
u8 qosinfo, const u8 *ext_capab,
size_t ext_capab_len);
#endif /* CONFIG_TDLS */
......
......@@ -285,14 +285,15 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add,
u16 capability, const u8 *supp_rates,
size_t supp_rates_len,
const struct ieee80211_ht_capabilities *ht_capab,
const struct ieee80211_vht_capabilities *vht_capab,
u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len)
{
if (sm->ctx->tdls_peer_addset)
return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add,
capability, supp_rates,
supp_rates_len, ht_capab,
qosinfo, ext_capab,
ext_capab_len);
vht_capab, qosinfo,
ext_capab, ext_capab_len);
return -1;
}
#endif /* CONFIG_TDLS */
......
......@@ -430,6 +430,9 @@ int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
} else if (*pos == WLAN_EID_HT_CAP) {
ie->ht_capabilities = pos + 2;
ie->ht_capabilities_len = pos[1];
} else if (*pos == WLAN_EID_VHT_CAP) {
ie->vht_capabilities = pos + 2;
ie->vht_capabilities_len = pos[1];
} else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
ie->qosinfo = pos[2];
} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
......
......@@ -51,6 +51,8 @@ struct wpa_eapol_ie_parse {
size_t ext_supp_rates_len;
const u8 *ht_capabilities;
size_t ht_capabilities_len;
const u8 *vht_capabilities;
size_t vht_capabilities_len;
u8 qosinfo;
};
......
......@@ -32,7 +32,7 @@ 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];
u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN * 2 + 1];
size_t dev_pw_len;
};
......@@ -3503,8 +3503,10 @@ int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg,
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;
wpa_snprintf_hex_uppercase((char *) token->dev_pw,
sizeof(token->dev_pw),
dev_pw, dev_pw_len);
token->dev_pw_len = dev_pw_len * 2;
dl_list_add(&reg->nfc_pw_tokens, &token->list);
......
......@@ -910,12 +910,12 @@ static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant *wpa_s,
static int wpas_ctrl_nfc_get_handover_sel_wps(struct wpa_supplicant *wpa_s,
char *reply, size_t max_len,
int ndef, int cr)
int ndef, int cr, char *uuid)
{
struct wpabuf *buf;
int res;
buf = wpas_wps_nfc_handover_sel(wpa_s, ndef, cr);
buf = wpas_wps_nfc_handover_sel(wpa_s, ndef, cr, uuid);
if (buf == NULL)
return -1;
......@@ -934,7 +934,7 @@ static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s,
char *cmd, char *reply,
size_t max_len)
{
char *pos;
char *pos, *pos2;
int ndef;
pos = os_strchr(cmd, ' ');
......@@ -949,10 +949,13 @@ static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s,
else
return -1;
pos2 = os_strchr(pos, ' ');
if (pos2)
*pos2++ = '\0';
if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) {
return wpas_ctrl_nfc_get_handover_sel_wps(
wpa_s, reply, max_len, ndef,
os_strcmp(pos, "WPS-CR") == 0);
os_strcmp(pos, "WPS-CR") == 0, pos2);
}
return -1;
......
......@@ -61,6 +61,13 @@ def wpas_get_config_token():
return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
def wpas_get_er_config_token(uuid):
wpas = wpas_connect()
if (wpas == None):
return None
return wpas.request("WPS_ER_NFC_CONFIG_TOKEN NDEF " + uuid).rstrip().decode("hex")
def wpas_get_password_token():
wpas = wpas_connect()
if (wpas == None):
......@@ -75,15 +82,91 @@ def wpas_get_handover_req():
return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip().decode("hex")
def wpas_report_handover(req, sel):
def wpas_get_handover_sel(uuid):
wpas = wpas_connect()
if (wpas == None):
return None
return wpas.request("NFC_REPORT_HANDOVER INIT WPS " +
if uuid is None:
return wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip().decode("hex")
return wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR " + uuid).rstrip().decode("hex")
def wpas_report_handover(req, sel, type):
wpas = wpas_connect()
if (wpas == None):
return None
return wpas.request("NFC_REPORT_HANDOVER " + type + " WPS " +
str(req).encode("hex") + " " +
str(sel).encode("hex"))
class HandoverServer(nfc.handover.HandoverServer):
def __init__(self):
super(HandoverServer, self).__init__()
def process_request(self, request):
print "HandoverServer - request received"
print "Parsed handover request: " + request.pretty()
sel = nfc.ndef.HandoverSelectMessage(version="1.2")
for carrier in request.carriers:
print "Remote carrier type: " + carrier.type
if carrier.type == "application/vnd.wfa.wsc":
print "WPS carrier type match - add WPS carrier record"
self.received_carrier = carrier.record
data = wpas_get_handover_sel(self.uuid)
if data is None:
print "Could not get handover select carrier record from wpa_supplicant"
continue
print "Handover select carrier record from wpa_supplicant:"
print data.encode("hex")
self.sent_carrier = data
message = nfc.ndef.Message(data);
sel.add_carrier(message[0], "active", message[1:])
print "Handover select:"
print sel.pretty()
print str(sel).encode("hex")
print "Sending handover select"
return sel
def wps_handover_resp(peer, uuid):
if uuid is None:
print "Trying to handle WPS handover"
else:
print "Trying to handle WPS handover with AP " + uuid
srv = HandoverServer()
srv.sent_carrier = None
srv.uuid = uuid
nfc.llcp.activate(peer);
try:
print "Trying handover";
srv.start()
print "Wait for disconnect"
while nfc.llcp.connected():
time.sleep(0.1)
print "Disconnected after handover"
except nfc.llcp.ConnectRefused:
print "Handover connection refused"
nfc.llcp.shutdown()
return
if srv.sent_carrier:
wpas_report_handover(srv.received_carrier, srv.sent_carrier, "RESP")
print "Remove peer"
nfc.llcp.shutdown()
print "Done with handover"
time.sleep(1)
def wps_handover_init(peer):
print "Trying to initiate WPS handover"
......@@ -147,7 +230,7 @@ def wps_handover_init(peer):
print "Remote carrier type: " + carrier.type
if carrier.type == "application/vnd.wfa.wsc":
print "WPS carrier type match - send to wpa_supplicant"
wpas_report_handover(data, carrier.record)
wpas_report_handover(data, carrier.record, "INIT")
wifi = nfc.ndef.WifiConfigRecord(carrier.record)
print wifi.pretty()
......@@ -198,6 +281,28 @@ def wps_write_config_tag(clf):
time.sleep(0.1)
def wps_write_er_config_tag(clf, uuid):
print "Write WPS ER config token"
data = wpas_get_er_config_token(uuid)
if (data == None):
print "Could not get WPS config token from wpa_supplicant"
return
print "Touch an NFC tag"
while True:
tag = clf.poll()
if tag == None:
time.sleep(0.1)
continue
break
print "Tag found - writing"
tag.ndef.message = data
print "Done - remove tag"
while tag.is_present:
time.sleep(0.1)
def wps_write_password_tag(clf):
print "Write WPS password token"
data = wpas_get_password_token()
......@@ -252,10 +357,18 @@ def main():
clf = nfc.ContactlessFrontend()
try:
arg_uuid = None
if len(sys.argv) > 1:
arg_uuid = sys.argv[1]
if len(sys.argv) > 1 and sys.argv[1] == "write-config":
wps_write_config_tag(clf)
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
if len(sys.argv) > 1 and sys.argv[1] == "write-password":
wps_write_password_tag(clf)
raise SystemExit
......@@ -265,7 +378,12 @@ def main():
tag = find_peer(clf)
if isinstance(tag, nfc.DEP):
wps_handover_init(tag)
if arg_uuid is None:
wps_handover_init(tag)
elif arg_uuid is "ap":
wps_handover_resp(tag, None)
else:
wps_handover_resp(tag, arg_uuid)
continue
if tag.ndef:
......
......@@ -554,6 +554,7 @@ static int wpa_supplicant_tdls_peer_addset(
void *ctx, const u8 *peer, int add, u16 capability,
const u8 *supp_rates, size_t supp_rates_len,
const struct ieee80211_ht_capabilities *ht_capab,
const struct ieee80211_vht_capabilities *vht_capab,
u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len)
{
struct wpa_supplicant *wpa_s = ctx;
......@@ -574,6 +575,7 @@ static int wpa_supplicant_tdls_peer_addset(
params.flags |= WPA_STA_WMM;
params.ht_capabilities = ht_capab;
params.vht_capabilities = vht_capab;
params.qosinfo = qosinfo;
params.listen_interval = 0;
params.supp_rates = supp_rates;
......
......@@ -2003,12 +2003,48 @@ struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s, int cr)
}
#ifdef CONFIG_WPS_NFC
struct wpabuf * wpas_wps_er_nfc_handover_sel(struct wpa_supplicant *wpa_s,
int ndef, const char *uuid)
{
struct wpabuf *ret;
u8 u[UUID_LEN];
if (!wpa_s->wps_er)
return NULL;
if (uuid == NULL || uuid_str2bin(uuid, u))
return NULL;
/*
* Handover Select carrier record for WPS uses the same format as
* configuration token.
*/
ret = wps_er_nfc_config_token(wpa_s->wps_er, u);
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_NFC */
struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
int ndef, int cr)
int ndef, int cr, const char *uuid)
{
struct wpabuf *ret;
if (!cr)
return NULL;
return wpas_ap_wps_nfc_handover_sel(wpa_s, ndef);
ret = wpas_ap_wps_nfc_handover_sel(wpa_s, ndef);
if (ret)
return ret;
return wpas_wps_er_nfc_handover_sel(wpa_s, ndef, uuid);
}
......
......@@ -70,7 +70,7 @@ int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
const struct wpabuf *data);
struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s, int cr);
struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
int ndef, int cr);
int ndef, int cr, const char *uuid);
int wpas_wps_nfc_rx_handover_req(struct wpa_supplicant *wpa_s,
const struct wpabuf *data);
int wpas_wps_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment