WPS: Fix MAC Address inside Credential be that of Enrollee's
authorJouni Malinen <j@w1.fi>
Wed, 18 Nov 2009 22:31:57 +0000 (00:31 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 18 Nov 2009 22:31:57 +0000 (00:31 +0200)
The WPS 1.0h specification is quite unclear on what exactly should be
used as the MAC Address value in the Credential and AP Settings. It
looks like this should after all be the MAC Address of the Enrollee,
so change Registrar implementation to use that address instead of the
AP BSSID.

In addition, add validation code to the Enrollee implementation to
check the MAC Address value inside Credential (and also inside AP Settings)
to make sure it matches with the Enrollee's own address. However, since
there are deployed implementations that do not follow this interpretation
of the spec, only show the mismatch in debug information to avoid breaking
interoperability with existing devices.

src/wps/wps.h
src/wps/wps_enrollee.c
src/wps/wps_registrar.c

index 85d279c..a85d600 100644 (file)
@@ -43,7 +43,7 @@ struct wps_er;
  * @key_idx: Key index
  * @key: Key
  * @key_len: Key length in octets
- * @mac_addr: MAC address of the peer
+ * @mac_addr: MAC address of the Credential receiver
  * @cred_attr: Unparsed Credential attribute data (used only in cred_cb());
  *     this may be %NULL, if not used
  * @cred_attr_len: Length of cred_attr in octets
index df2c086..a7b8227 100644 (file)
@@ -680,6 +680,21 @@ static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
            wps_process_cred(&attr, &wps->cred))
                return -1;
 
+       if (os_memcmp(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
+           0) {
+               wpa_printf(MSG_DEBUG, "WPS: MAC Address in the Credential ("
+                          MACSTR ") does not match with own address (" MACSTR
+                          ")", MAC2STR(wps->cred.mac_addr),
+                          MAC2STR(wps->wps->dev.mac_addr));
+               /*
+                * In theory, this could be consider fatal error, but there are
+                * number of deployed implementations using other address here
+                * due to unclarity in the specification. For interoperability
+                * reasons, allow this to be processed since we do not really
+                * use the MAC Address information for anything.
+                */
+       }
+
        if (wps->wps->cred_cb) {
                wps->cred.cred_attr = cred - 4;
                wps->cred.cred_attr_len = cred_len + 4;
@@ -730,6 +745,21 @@ static int wps_process_ap_settings_e(struct wps_data *wps,
        wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
                   "Registrar");
 
+       if (os_memcmp(cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
+           0) {
+               wpa_printf(MSG_DEBUG, "WPS: MAC Address in the AP Settings ("
+                          MACSTR ") does not match with own address (" MACSTR
+                          ")", MAC2STR(cred.mac_addr),
+                          MAC2STR(wps->wps->dev.mac_addr));
+               /*
+                * In theory, this could be consider fatal error, but there are
+                * number of deployed implementations using other address here
+                * due to unclarity in the specification. For interoperability
+                * reasons, allow this to be processed since we do not really
+                * use the MAC Address information for anything.
+                */
+       }
+
        if (wps->wps->cred_cb) {
                cred.cred_attr = wpabuf_head(attrs);
                cred.cred_attr_len = wpabuf_len(attrs);
index 4c0107d..edd4b5a 100644 (file)
@@ -1231,8 +1231,10 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
                }
        }
        wps->cred.encr_type = wps->encr_type;
-       /* Set MAC address in the Credential to be the AP's address (BSSID) */
-       os_memcpy(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN);
+       /*
+        * Set MAC address in the Credential to be the Enrollee's MAC address
+        */
+       os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
 
        if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
            !wps->wps->registrar->disable_auto_conf) {