Browse Source

WPS UFD: Use pre-configured DH keys only with OOB

The old behavior of generating new DH keys can be maintained for non-OOB
cases and only OOB (in this case, with UFD) will use the pre-configured
DH keys to allow the public key hash to be checked.
Jouni Malinen 16 years ago
parent
commit
d5e2b2d274
4 changed files with 59 additions and 25 deletions
  1. 27 12
      hostapd/wps_hostapd.c
  2. 12 2
      src/wps/wps_attr_build.c
  3. 2 1
      src/wps/wps_enrollee.c
  4. 18 10
      wpa_supplicant/wps_supplicant.c

+ 27 - 12
hostapd/wps_hostapd.c

@@ -649,16 +649,6 @@ int hostapd_init_wps(struct hostapd_data *hapd,
 	}
 #endif /* CONFIG_WPS_UPNP */
 
-	wps->dh_pubkey = dh_init(dh_groups_get(WPS_DH_GROUP),
-				 &wps->dh_privkey);
-	wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192);
-	if (wps->dh_pubkey == NULL) {
-		wpa_printf(MSG_ERROR, "WPS: Failed to initialize "
-			   "Diffie-Hellman handshake");
-		os_free(wps);
-		return -1;
-	}
-
 	hapd->wps = wps;
 
 	return 0;
@@ -721,16 +711,41 @@ int hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type,
 	oob_dev->device_path = path;
 	wps->oob_conf.oob_method = wps_get_oob_method(method);
 
+	if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) {
+		/*
+		 * Use pre-configured DH keys in order to be able to write the
+		 * key hash into the OOB file.
+		 */
+		wpabuf_free(wps->dh_pubkey);
+		wpabuf_free(wps->dh_privkey);
+		wps->dh_privkey = NULL;
+		wps->dh_pubkey = dh_init(dh_groups_get(WPS_DH_GROUP),
+					 &wps->dh_privkey);
+		wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192);
+		if (wps->dh_pubkey == NULL) {
+			wpa_printf(MSG_ERROR, "WPS: Failed to initialize "
+				   "Diffie-Hellman handshake");
+			return -1;
+		}
+	}
+
 	if (wps_process_oob(wps, oob_dev, 1) < 0)
-		return -1;
+		goto error;
 
 	if ((wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E ||
 	     wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) &&
 	    hostapd_wps_add_pin(hapd, "any",
 				wpabuf_head(wps->oob_conf.dev_password)) < 0)
-			return -1;
+		goto error;
 
 	return 0;
+
+error:
+	wpabuf_free(wps->dh_pubkey);
+	wps->dh_pubkey = NULL;
+	wpabuf_free(wps->dh_privkey);
+	wps->dh_privkey = NULL;
+	return -1;
 }
 
 

+ 12 - 2
src/wps/wps_attr_build.c

@@ -15,6 +15,7 @@
 #include "includes.h"
 
 #include "common.h"
+#include "dh_groups.h"
 #include "crypto.h"
 #include "sha256.h"
 #include "aes_wrap.h"
@@ -27,8 +28,17 @@ int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
 
 	wpa_printf(MSG_DEBUG, "WPS:  * Public Key");
 	wpabuf_free(wps->dh_privkey);
-	wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey);
-	pubkey = wpabuf_dup(wps->wps->dh_pubkey);
+	if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey) {
+		wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys");
+		wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey);
+		pubkey = wpabuf_dup(wps->wps->dh_pubkey);
+	} else {
+		wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys");
+		wps->dh_privkey = NULL;
+		pubkey = dh_init(dh_groups_get(WPS_DH_GROUP),
+				 &wps->dh_privkey);
+		pubkey = wpabuf_zeropad(pubkey, 192);
+	}
 	if (wps->dh_privkey == NULL || pubkey == NULL) {
 		wpa_printf(MSG_DEBUG, "WPS: Failed to initialize "
 			   "Diffie-Hellman handshake");

+ 2 - 1
src/wps/wps_enrollee.c

@@ -517,7 +517,8 @@ static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
 		return -1;
 	}
 
-	if (wps->wps->oob_conf.pubkey_hash != NULL) {
+	if (wps->dev_pw_id != DEV_PW_DEFAULT &&
+	    wps->wps->oob_conf.pubkey_hash) {
 		const u8 *addr[1];
 		u8 hash[WPS_HASH_LEN];
 

+ 18 - 10
wpa_supplicant/wps_supplicant.c

@@ -474,6 +474,24 @@ int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type,
 	oob_dev->device_path = path;
 	wps->oob_conf.oob_method = wps_get_oob_method(method);
 
+	if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E) {
+		/*
+		 * Use pre-configured DH keys in order to be able to write the
+		 * key hash into the OOB file.
+		 */
+		wpabuf_free(wps->dh_pubkey);
+		wpabuf_free(wps->dh_privkey);
+		wps->dh_privkey = NULL;
+		wps->dh_pubkey = dh_init(dh_groups_get(WPS_DH_GROUP),
+					 &wps->dh_privkey);
+		wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192);
+		if (wps->dh_pubkey == NULL) {
+			wpa_printf(MSG_ERROR, "WPS: Failed to initialize "
+				   "Diffie-Hellman handshake");
+			return -1;
+		}
+	}
+
 	if (wps->oob_conf.oob_method == OOB_METHOD_CRED)
 		wpas_clear_wps(wpa_s);
 
@@ -613,16 +631,6 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
 		return -1;
 	}
 
-	wps->dh_pubkey = dh_init(dh_groups_get(WPS_DH_GROUP),
-				 &wps->dh_privkey);
-	wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192);
-	if (wps->dh_pubkey == NULL) {
-		wpa_printf(MSG_ERROR, "WPS: Failed to initialize "
-			   "Diffie-Hellman handshake");
-		os_free(wps);
-		return -1;
-	}
-
 	wpa_s->wps = wps;
 
 	return 0;