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.
This commit is contained in:
parent
79d7d8efe7
commit
08bec36178
3 changed files with 58 additions and 20 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
return -1;
|
||||||
return wps_registrar_add_pin(hapd->wps->registrar, u,
|
if (os_strcmp(uuid, "any") == 0)
|
||||||
|
any = 1;
|
||||||
|
else if (uuid_str2bin(uuid, u))
|
||||||
|
return -1;
|
||||||
|
return wps_registrar_add_pin(hapd->wps->registrar, any ? NULL : u,
|
||||||
(const u8 *) pin, os_strlen(pin));
|
(const u8 *) pin, os_strlen(pin));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
if (!pin->wildcard_uuid &&
|
||||||
/*
|
os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0)
|
||||||
* Lock the PIN to avoid attacks based on concurrent
|
break;
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
pin = pin->next;
|
pin = pin->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
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 = pin->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue