WPS NFC: Allow configuration token to be built from network block
authorJouni Malinen <j@w1.fi>
Mon, 1 Apr 2013 18:28:57 +0000 (21:28 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 1 Apr 2013 18:28:57 +0000 (21:28 +0300)
"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>

src/wps/wps.h
src/wps/wps_er.c
wpa_supplicant/README-WPS
wpa_supplicant/ctrl_iface.c
wpa_supplicant/examples/wps-nfc.py
wpa_supplicant/wps_supplicant.c
wpa_supplicant/wps_supplicant.h

index 6e74a41..cb03dbd 100644 (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,
                  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);
 
index 31ba450..14c1b77 100644 (file)
@@ -2023,32 +2023,20 @@ int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
 
 
 #ifdef CONFIG_WPS_NFC
-struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
-                                       const u8 *addr)
+
+struct wpabuf * wps_er_config_token_from_cred(struct wps_context *wps,
+                                             struct wps_credential *cred)
 {
-       struct wps_er_ap *ap;
        struct wpabuf *ret;
        struct wps_data data;
 
-       if (er == NULL)
-               return NULL;
-
-       ap = wps_er_ap_get(er, NULL, uuid, addr);
-       if (ap == NULL)
-               return NULL;
-       if (ap->ap_settings == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS ER: No settings known for the "
-                          "selected AP");
-               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;
+       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)) {
@@ -2058,4 +2046,26 @@ struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
 
        return ret;
 }
+
+
+struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
+                                       const u8 *addr)
+{
+       struct wps_er_ap *ap;
+
+       if (er == NULL)
+               return NULL;
+
+       ap = wps_er_ap_get(er, NULL, uuid, addr);
+       if (ap == NULL)
+               return NULL;
+       if (ap->ap_settings == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS ER: No settings known for the "
+                          "selected AP");
+               return NULL;
+       }
+
+       return wps_er_config_token_from_cred(er->wps, ap->ap_settings);
+}
+
 #endif /* CONFIG_WPS_NFC */
index 0615466..3d07109 100644 (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
 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
index 4949771..27220a9 100644 (file)
@@ -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;
 
index 86473cd..dbc143a 100755 (executable)
@@ -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
index d9b1b29..9af6084 100644 (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 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
 
+#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)
+                                         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);
index 8bb9546..2a212ca 100644 (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);
 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,