Browse Source

WPS: Added support for wildcard PINs that work with any UUID-E

Since the Registrar may not yet know the UUID-E when a new PIN is
entered, use of a wildcard PIN that works with any UUID-E can be useful.
Such a PIN will be bound to the first Enrollee trying to use it and it
will be invalidated after the first use.
Jouni Malinen 16 years ago
parent
commit
08bec36178
3 changed files with 57 additions and 19 deletions
  1. 6 0
      hostapd/README-WPS
  2. 8 2
      hostapd/wps_hostapd.c
  3. 43 17
      src/wps/wps_registrar.c

+ 6 - 0
hostapd/README-WPS

@@ -154,6 +154,12 @@ Example command to add a PIN (12345670) for an Enrollee:
 
 
 hostapd_cli wps_pin 53b63a98-d29e-4457-a2ed-094d7e6a669c 12345670
 hostapd_cli wps_pin 53b63a98-d29e-4457-a2ed-094d7e6a669c 12345670
 
 
+If the UUID-E is not available (e.g., Enrollee waits for the Registrar
+to be selected before connecting), wildcard UUID may be used to allow the PIN to be used once with any UUID:
+
+hostapd_cli wps_pin any 12345670
+
+
 After this, the Enrollee can connect to the AP again and complete WPS
 After this, the Enrollee can connect to the AP again and complete WPS
 negotiation. At that point, a new, random WPA PSK is generated for the
 negotiation. At that point, a new, random WPA PSK is generated for the
 client device and the client can then use that key to connect to the
 client device and the client can then use that key to connect to the

+ 8 - 2
hostapd/wps_hostapd.c

@@ -543,9 +543,15 @@ int hostapd_wps_add_pin(struct hostapd_data *hapd, const char *uuid,
 			const char *pin)
 			const char *pin)
 {
 {
 	u8 u[UUID_LEN];
 	u8 u[UUID_LEN];
-	if (hapd->wps == NULL || uuid_str2bin(uuid, u))
+	int any = 0;
+
+	if (hapd->wps == NULL)
+		return -1;
+	if (os_strcmp(uuid, "any") == 0)
+		any = 1;
+	else if (uuid_str2bin(uuid, u))
 		return -1;
 		return -1;
-	return wps_registrar_add_pin(hapd->wps->registrar, u,
+	return wps_registrar_add_pin(hapd->wps->registrar, any ? NULL : u,
 				     (const u8 *) pin, os_strlen(pin));
 				     (const u8 *) pin, os_strlen(pin));
 }
 }
 
 

+ 43 - 17
src/wps/wps_registrar.c

@@ -26,6 +26,7 @@
 struct wps_uuid_pin {
 struct wps_uuid_pin {
 	struct wps_uuid_pin *next;
 	struct wps_uuid_pin *next;
 	u8 uuid[WPS_UUID_LEN];
 	u8 uuid[WPS_UUID_LEN];
+	int wildcard_uuid;
 	u8 *pin;
 	u8 *pin;
 	size_t pin_len;
 	size_t pin_len;
 	int locked;
 	int locked;
@@ -339,7 +340,10 @@ int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
 	p = os_zalloc(sizeof(*p));
 	p = os_zalloc(sizeof(*p));
 	if (p == NULL)
 	if (p == NULL)
 		return -1;
 		return -1;
-	os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
+	if (uuid == NULL)
+		p->wildcard_uuid = 1;
+	else
+		os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
 	p->pin = os_malloc(pin_len);
 	p->pin = os_malloc(pin_len);
 	if (p->pin == NULL) {
 	if (p->pin == NULL) {
 		os_free(p);
 		os_free(p);
@@ -394,26 +398,43 @@ static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
 
 
 	pin = reg->pins;
 	pin = reg->pins;
 	while (pin) {
 	while (pin) {
-		if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
-			/*
-			 * Lock the PIN to avoid attacks based on concurrent
-			 * re-use of the PIN that could otherwise avoid PIN
-			 * invalidations.
-			 */
-			if (pin->locked) {
-				wpa_printf(MSG_DEBUG, "WPS: Selected PIN "
-					   "locked - do not allow concurrent "
-					   "re-use");
-				return NULL;
+		if (!pin->wildcard_uuid &&
+		    os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0)
+			break;
+		pin = pin->next;
+	}
+
+	if (!pin) {
+		/* Check for wildcard UUIDs since none of the UUID-specific
+		 * PINs matched */
+		pin = reg->pins;
+		while (pin) {
+			if (pin->wildcard_uuid == 1) {
+				wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
+					   "PIN. Assigned it for this UUID-E");
+				pin->wildcard_uuid = 2;
+				os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
+				break;
 			}
 			}
-			*pin_len = pin->pin_len;
-			pin->locked = 1;
-			return pin->pin;
+			pin = pin->next;
 		}
 		}
-		pin = pin->next;
 	}
 	}
 
 
-	return NULL;
+	if (!pin)
+		return NULL;
+
+	/*
+	 * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
+	 * that could otherwise avoid PIN invalidations.
+	 */
+	if (pin->locked) {
+		wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
+			   "allow concurrent re-use");
+		return NULL;
+	}
+	*pin_len = pin->pin_len;
+	pin->locked = 1;
+	return pin->pin;
 }
 }
 
 
 
 
@@ -424,6 +445,11 @@ int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
 	pin = reg->pins;
 	pin = reg->pins;
 	while (pin) {
 	while (pin) {
 		if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
 		if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
+			if (pin->wildcard_uuid == 2) {
+				wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
+					   "wildcard PIN");
+				return wps_registrar_invalidate_pin(reg, uuid);
+			}
 			pin->locked = 0;
 			pin->locked = 0;
 			return 0;
 			return 0;
 		}
 		}