]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Extend per-station PSK to support ER case as well
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 13 Mar 2014 11:26:21 +0000 (13:26 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 13 Mar 2014 16:22:25 +0000 (18:22 +0200)
When wpa_psk_file is used instead of wpa_psk/wpa_passphrase, each WPS
Enrollee was given a unique PSK. This did not work for the
station-as-Registrar case where ER would learn the current AP settings
instead of enrolling itself (i.e., when using the AP PIN instead of
station PIN). That case can be covered with a similar design, so
generate a per-device PSK when building M7 as an AP in wpa_psk_file
configuration.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/wps/wps_enrollee.c
src/wps/wps_i.h
src/wps/wps_registrar.c

index 70d6a1781c96aad3bcd1822c5924b5905552f883..89f13664583128aa6baedba0c6845528c2c7f431 100644 (file)
@@ -265,6 +265,29 @@ static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
 
 static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
 {
+       if ((wps->wps->ap_auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) &&
+           wps->wps->network_key_len == 0) {
+               char hex[65];
+               u8 psk[32];
+               /* Generate a random per-device PSK */
+               if (random_get_bytes(psk, sizeof(psk)) < 0)
+                       return -1;
+               wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
+                               psk, sizeof(psk));
+               wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%u)",
+                          (unsigned int) wps->new_psk_len * 2);
+               wpa_snprintf_hex(hex, sizeof(hex), psk, sizeof(psk));
+               wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
+               wpabuf_put_be16(msg, sizeof(psk) * 2);
+               wpabuf_put_data(msg, hex, sizeof(psk) * 2);
+               if (wps->wps->registrar) {
+                       wps_cb_new_psk(wps->wps->registrar,
+                                      wps->peer_dev.mac_addr,
+                                      wps->p2p_dev_addr, psk, sizeof(psk));
+               }
+               return 0;
+       }
+
        wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%u)",
                   (unsigned int) wps->wps->network_key_len);
        wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
index 22070db9bda41aa8b3166bce72930eb81761bf09..f7154f8734bbdd81f6f948619464206bf41be03f 100644 (file)
@@ -212,5 +212,7 @@ 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);
+int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
+                  const u8 *p2p_dev_addr, const u8 *psk, size_t psk_len);
 
 #endif /* WPS_I_H */
index 6d879be278233f619dbcaee018c4d86b6e7e8f1a..900dd5a1fdfc813f6abdbbb1022179ca87fa7c52 100644 (file)
@@ -1170,8 +1170,8 @@ void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
 }
 
 
-static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
-                         const u8 *p2p_dev_addr, const u8 *psk, size_t psk_len)
+int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
+                  const u8 *p2p_dev_addr, const u8 *psk, size_t psk_len)
 {
        if (reg->new_psk_cb == NULL)
                return 0;