Updated to hostap_2_6
[mech_eap.git] / libeap / src / wps / wps_registrar.c
index 4ca3a42..fac8bd8 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.
@@ -703,7 +703,7 @@ void wps_registrar_deinit(struct wps_registrar *reg)
        eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
        eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
        wps_registrar_flush(reg);
-       wpabuf_free(reg->extra_cred);
+       wpabuf_clear_free(reg->extra_cred);
        os_free(reg);
 }
 
@@ -1577,13 +1577,13 @@ int wps_build_credential_wrap(struct wpabuf *msg,
        if (wbuf == NULL)
                return -1;
        if (wps_build_credential(wbuf, cred)) {
-               wpabuf_free(wbuf);
+               wpabuf_clear_free(wbuf);
                return -1;
        }
        wpabuf_put_be16(msg, ATTR_CRED);
        wpabuf_put_be16(msg, wpabuf_len(wbuf));
        wpabuf_put_buf(msg, wbuf);
-       wpabuf_free(wbuf);
+       wpabuf_clear_free(wbuf);
        return 0;
 }
 
@@ -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)
@@ -1740,14 +1751,14 @@ use_provided:
                return -1;
 
        if (wps_build_credential(cred, &wps->cred)) {
-               wpabuf_free(cred);
+               wpabuf_clear_free(cred);
                return -1;
        }
 
        wpabuf_put_be16(msg, ATTR_CRED);
        wpabuf_put_be16(msg, wpabuf_len(cred));
        wpabuf_put_buf(msg, cred);
-       wpabuf_free(cred);
+       wpabuf_clear_free(cred);
 
 skip_cred_build:
        if (wps->wps->registrar->extra_cred) {
@@ -1785,7 +1796,7 @@ static struct wpabuf * wps_build_ap_cred(struct wps_data *wps)
        }
 
        if (wps_build_ap_settings(wps, plain)) {
-               wpabuf_free(plain);
+               wpabuf_clear_free(plain);
                wpabuf_free(msg);
                return NULL;
        }
@@ -1793,7 +1804,7 @@ static struct wpabuf * wps_build_ap_cred(struct wps_data *wps)
        wpabuf_put_be16(msg, ATTR_CRED);
        wpabuf_put_be16(msg, wpabuf_len(plain));
        wpabuf_put_buf(msg, plain);
-       wpabuf_free(plain);
+       wpabuf_clear_free(plain);
 
        return msg;
 }
@@ -1853,10 +1864,10 @@ static struct wpabuf * wps_build_m2(struct wps_data *wps)
                    wps_build_key_wrap_auth(wps, plain) ||
                    wps_build_encr_settings(wps, msg, plain)) {
                        wpabuf_free(msg);
-                       wpabuf_free(plain);
+                       wpabuf_clear_free(plain);
                        return NULL;
                }
-               wpabuf_free(plain);
+               wpabuf_clear_free(plain);
                config_in_m2 = 1;
        }
 #endif /* CONFIG_WPS_NFC */
@@ -1917,7 +1928,8 @@ static struct wpabuf * wps_build_m4(struct wps_data *wps)
 
        wpa_printf(MSG_DEBUG, "WPS: Building Message M4");
 
-       wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
+       if (wps_derive_psk(wps, wps->dev_password, wps->dev_password_len) < 0)
+               return NULL;
 
        plain = wpabuf_alloc(200);
        if (plain == NULL)
@@ -1938,11 +1950,11 @@ static struct wpabuf * wps_build_m4(struct wps_data *wps)
            wps_build_encr_settings(wps, msg, plain) ||
            wps_build_wfa_ext(msg, 0, NULL, 0) ||
            wps_build_authenticator(wps, msg)) {
-               wpabuf_free(plain);
+               wpabuf_clear_free(plain);
                wpabuf_free(msg);
                return NULL;
        }
-       wpabuf_free(plain);
+       wpabuf_clear_free(plain);
 
        wps->state = RECV_M5;
        return msg;
@@ -1973,11 +1985,11 @@ static struct wpabuf * wps_build_m6(struct wps_data *wps)
            wps_build_encr_settings(wps, msg, plain) ||
            wps_build_wfa_ext(msg, 0, NULL, 0) ||
            wps_build_authenticator(wps, msg)) {
-               wpabuf_free(plain);
+               wpabuf_clear_free(plain);
                wpabuf_free(msg);
                return NULL;
        }
-       wpabuf_free(plain);
+       wpabuf_clear_free(plain);
 
        wps->wps_pin_revealed = 1;
        wps->state = RECV_M7;
@@ -2010,11 +2022,11 @@ static struct wpabuf * wps_build_m8(struct wps_data *wps)
            wps_build_encr_settings(wps, msg, plain) ||
            wps_build_wfa_ext(msg, 0, NULL, 0) ||
            wps_build_authenticator(wps, msg)) {
-               wpabuf_free(plain);
-               wpabuf_free(msg);
+               wpabuf_clear_free(plain);
+               wpabuf_clear_free(msg);
                return NULL;
        }
-       wpabuf_free(plain);
+       wpabuf_clear_free(plain);
 
        wps->state = RECV_DONE;
        return msg;
@@ -2343,6 +2355,23 @@ static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth)
 
        wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x",
                   auth_types);
+#ifdef WPS_WORKAROUNDS
+       /*
+        * Some deployed implementations seem to advertise incorrect information
+        * in this attribute. A value of 0x1b (WPA2 + WPA + WPAPSK + OPEN, but
+        * no WPA2PSK) has been reported to be used. Add WPA2PSK to the list to
+        * avoid issues with building Credentials that do not use the strongest
+        * actually supported authentication option (that device does support
+        * WPA2PSK even when it does not claim it here).
+        */
+       if ((auth_types &
+            (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) ==
+           (WPS_AUTH_WPA2 | WPS_AUTH_WPAPSK)) {
+               wpa_printf(MSG_DEBUG,
+                          "WPS: Workaround - assume Enrollee supports WPA2PSK based on claimed WPA2 support");
+               auth_types |= WPS_AUTH_WPA2PSK;
+       }
+#endif /* WPS_WORKAROUNDS */
        wps->auth_type = wps->wps->auth_types & auth_types;
        if (wps->auth_type == 0) {
                wpa_printf(MSG_DEBUG, "WPS: No match in supported "
@@ -2757,7 +2786,7 @@ static enum wps_process_res wps_process_m5(struct wps_data *wps,
        }
 
        if (wps_validate_m5_encr(decrypted, attr->version2 != NULL) < 0) {
-               wpabuf_free(decrypted);
+               wpabuf_clear_free(decrypted);
                wps->state = SEND_WSC_NACK;
                return WPS_CONTINUE;
        }
@@ -2767,11 +2796,11 @@ static enum wps_process_res wps_process_m5(struct wps_data *wps,
        if (wps_parse_msg(decrypted, &eattr) < 0 ||
            wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
            wps_process_e_snonce1(wps, eattr.e_snonce1)) {
-               wpabuf_free(decrypted);
+               wpabuf_clear_free(decrypted);
                wps->state = SEND_WSC_NACK;
                return WPS_CONTINUE;
        }
-       wpabuf_free(decrypted);
+       wpabuf_clear_free(decrypted);
 
        wps->state = SEND_M6;
        return WPS_CONTINUE;
@@ -2909,7 +2938,7 @@ static enum wps_process_res wps_process_m7(struct wps_data *wps,
 
        if (wps_validate_m7_encr(decrypted, wps->wps->ap || wps->er,
                                 attr->version2 != NULL) < 0) {
-               wpabuf_free(decrypted);
+               wpabuf_clear_free(decrypted);
                wps->state = SEND_WSC_NACK;
                return WPS_CONTINUE;
        }
@@ -2920,12 +2949,12 @@ static enum wps_process_res wps_process_m7(struct wps_data *wps,
            wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
            wps_process_e_snonce2(wps, eattr.e_snonce2) ||
            wps_process_ap_settings_r(wps, &eattr)) {
-               wpabuf_free(decrypted);
+               wpabuf_clear_free(decrypted);
                wps->state = SEND_WSC_NACK;
                return WPS_CONTINUE;
        }
 
-       wpabuf_free(decrypted);
+       wpabuf_clear_free(decrypted);
 
        wps->state = SEND_M8;
        return WPS_CONTINUE;