]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Do not build Credential with unsupported encr combination on AP
authorJouni Malinen <j@w1.fi>
Fri, 1 Jan 2016 09:59:20 +0000 (11:59 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 1 Jan 2016 11:42:04 +0000 (13:42 +0200)
It was possible for the Registrar code to generate a Credential with
auth type WPAPSK (i.e., WPA v1) with encr type AES if the Enrollee
claimed support for WPAPSK and not WPA2PSK while the AP was configured
in mixed mode WPAPSK+WPA2PSK regardless of how wpa_pairwise (vs.
rsn_pairwise) was set since encr type was selected from the union of
wpa_pairwise and rsn_pairwise. This could result in the Enrollee
receiving a Credential that it could then not use with the AP.

Fix this by masking the encryption types separately on AP based on the
wpa_pairwise/rsn_pairwise configuration. In the example case described
above, the Credential would get auth=WPAPSK encr=TKIP instead of
auth=WPAPSK encr=AES.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/ap/wps_hostapd.c
src/wps/wps.h
src/wps/wps_registrar.c

index 66a43eb816b946ae330d5e41b2b91423ca0d3409..ba58f3e579d8543446f3bcb23cfeede8555f6c6a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * hostapd / WPS integration
- * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2008-2016, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -445,6 +445,8 @@ static int hapd_wps_cred_cb(struct hostapd_data *hapd, void *ctx)
        os_memcpy(hapd->wps->ssid, cred->ssid, cred->ssid_len);
        hapd->wps->ssid_len = cred->ssid_len;
        hapd->wps->encr_types = cred->encr_type;
+       hapd->wps->encr_types_rsn = cred->encr_type;
+       hapd->wps->encr_types_wpa = cred->encr_type;
        hapd->wps->auth_types = cred->auth_type;
        hapd->wps->ap_encr_type = cred->encr_type;
        hapd->wps->ap_auth_type = cred->auth_type;
@@ -1068,10 +1070,14 @@ int hostapd_init_wps(struct hostapd_data *hapd,
                if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
                        wps->auth_types |= WPS_AUTH_WPA2;
 
-               if (conf->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP))
+               if (conf->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) {
                        wps->encr_types |= WPS_ENCR_AES;
-               if (conf->rsn_pairwise & WPA_CIPHER_TKIP)
+                       wps->encr_types_rsn |= WPS_ENCR_AES;
+               }
+               if (conf->rsn_pairwise & WPA_CIPHER_TKIP) {
                        wps->encr_types |= WPS_ENCR_TKIP;
+                       wps->encr_types_rsn |= WPS_ENCR_TKIP;
+               }
        }
 
        if (conf->wpa & WPA_PROTO_WPA) {
@@ -1080,10 +1086,14 @@ int hostapd_init_wps(struct hostapd_data *hapd,
                if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
                        wps->auth_types |= WPS_AUTH_WPA;
 
-               if (conf->wpa_pairwise & WPA_CIPHER_CCMP)
+               if (conf->wpa_pairwise & WPA_CIPHER_CCMP) {
                        wps->encr_types |= WPS_ENCR_AES;
-               if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
+                       wps->encr_types_wpa |= WPS_ENCR_AES;
+               }
+               if (conf->wpa_pairwise & WPA_CIPHER_TKIP) {
                        wps->encr_types |= WPS_ENCR_TKIP;
+                       wps->encr_types_wpa |= WPS_ENCR_TKIP;
+               }
        }
 
        if (conf->ssid.security_policy == SECURITY_PLAINTEXT) {
@@ -1123,6 +1133,8 @@ int hostapd_init_wps(struct hostapd_data *hapd,
                /* Override parameters to enable security by default */
                wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
                wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;
+               wps->encr_types_rsn = WPS_ENCR_AES | WPS_ENCR_TKIP;
+               wps->encr_types_wpa = WPS_ENCR_AES | WPS_ENCR_TKIP;
        }
 
        wps->ap_settings = conf->ap_settings;
index 2c91d1678c157e07498631097ccb6e8ea09f91f8..ff4dd103ce1415ebb64d1b2e559158847c4bbabb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Wi-Fi Protected Setup
- * Copyright (c) 2007-2013, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2007-2016, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -663,6 +663,16 @@ struct wps_context {
         */
        u16 encr_types;
 
+       /**
+        * encr_types_rsn - Enabled encryption types for RSN (WPS_ENCR_*)
+        */
+       u16 encr_types_rsn;
+
+       /**
+        * encr_types_wpa - Enabled encryption types for WPA (WPS_ENCR_*)
+        */
+       u16 encr_types_wpa;
+
        /**
         * auth_types - Authentication types (bit field of WPS_AUTH_*)
         */
index 4ca3a42d4c738a90dd552eb092f1315907d076e8..22b68afe3438ca0e950a52f7b77db1d91646b6f8 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Wi-Fi Protected Setup - Registrar
- * Copyright (c) 2008-2013, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2008-2016, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -1606,6 +1606,9 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
        wps->cred.ssid_len = wps->wps->ssid_len;
 
        /* Select the best authentication and encryption type */
+       wpa_printf(MSG_DEBUG,
+                  "WPS: Own auth types 0x%x - masked Enrollee auth types 0x%x",
+                  wps->wps->auth_types, wps->auth_type);
        if (wps->auth_type & WPS_AUTH_WPA2PSK)
                wps->auth_type = WPS_AUTH_WPA2PSK;
        else if (wps->auth_type & WPS_AUTH_WPAPSK)
@@ -1619,6 +1622,14 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
        }
        wps->cred.auth_type = wps->auth_type;
 
+       wpa_printf(MSG_DEBUG,
+                  "WPS: Own encr types 0x%x (rsn: 0x%x, wpa: 0x%x) - masked Enrollee encr types 0x%x",
+                  wps->wps->encr_types, wps->wps->encr_types_rsn,
+                  wps->wps->encr_types_wpa, wps->encr_type);
+       if (wps->wps->ap && wps->auth_type == WPS_AUTH_WPA2PSK)
+               wps->encr_type &= wps->wps->encr_types_rsn;
+       else if (wps->wps->ap && wps->auth_type == WPS_AUTH_WPAPSK)
+               wps->encr_type &= wps->wps->encr_types_wpa;
        if (wps->auth_type == WPS_AUTH_WPA2PSK ||
            wps->auth_type == WPS_AUTH_WPAPSK) {
                if (wps->encr_type & WPS_ENCR_AES)