Browse Source

WPS: Add support for OOB dev password lengths 16..31

Previously, only the maximum length 32 octets for OOB device password
was accepted. Since the specification allows a shorter password to be
used with limited OOB mechanism (e.g., small NFC tag), we should accept
lengths 16..32.

Signed-hostap: Jouni Malinen <j@w1.fi>
Jouni Malinen 13 years ago
parent
commit
4e0131d351
4 changed files with 13 additions and 9 deletions
  1. 5 1
      src/wps/wps_attr_parse.c
  2. 5 5
      src/wps/wps_common.c
  3. 1 1
      src/wps/wps_defs.h
  4. 2 2
      src/wps/wps_i.h

+ 5 - 1
src/wps/wps_attr_parse.c

@@ -262,12 +262,16 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
 		attr->dev_password_id = pos;
 		break;
 	case ATTR_OOB_DEVICE_PASSWORD:
-		if (len != WPS_OOB_DEVICE_PASSWORD_ATTR_LEN) {
+		if (len < WPS_OOB_PUBKEY_HASH_LEN + 2 +
+		    WPS_OOB_DEVICE_PASSWORD_MIN_LEN ||
+		    len > WPS_OOB_PUBKEY_HASH_LEN + 2 +
+		    WPS_OOB_DEVICE_PASSWORD_LEN) {
 			wpa_printf(MSG_DEBUG, "WPS: Invalid OOB Device "
 				   "Password length %u", len);
 			return -1;
 		}
 		attr->oob_dev_password = pos;
+		attr->oob_dev_password_len = len;
 		break;
 	case ATTR_OS_VERSION:
 		if (len != 4) {

+ 5 - 5
src/wps/wps_common.c

@@ -375,6 +375,7 @@ static int wps_parse_oob_dev_pwd(struct wps_context *wps,
 	struct oob_conf_data *oob_conf = &wps->oob_conf;
 	struct wps_parse_attr attr;
 	const u8 *pos;
+	size_t pw_len;
 
 	if (wps_parse_msg(data, &attr) < 0 ||
 	    attr.oob_dev_password == NULL) {
@@ -397,17 +398,16 @@ static int wps_parse_oob_dev_pwd(struct wps_context *wps,
 	wps->oob_dev_pw_id = WPA_GET_BE16(pos);
 	pos += sizeof(wps->oob_dev_pw_id);
 
-	oob_conf->dev_password =
-		wpabuf_alloc(WPS_OOB_DEVICE_PASSWORD_LEN * 2 + 1);
+	pw_len = attr.oob_dev_password_len - WPS_OOB_PUBKEY_HASH_LEN - 2;
+	oob_conf->dev_password = wpabuf_alloc(pw_len * 2 + 1);
 	if (oob_conf->dev_password == NULL) {
 		wpa_printf(MSG_ERROR, "WPS: Failed to allocate memory for OOB "
 			   "device password");
 		return -1;
 	}
 	wpa_snprintf_hex_uppercase(wpabuf_put(oob_conf->dev_password,
-				   wpabuf_size(oob_conf->dev_password)),
-				   wpabuf_size(oob_conf->dev_password), pos,
-				   WPS_OOB_DEVICE_PASSWORD_LEN);
+					      pw_len * 2 + 1),
+				   pw_len * 2 + 1, pos, pw_len);
 
 	return 0;
 }

+ 1 - 1
src/wps/wps_defs.h

@@ -41,7 +41,7 @@ extern int wps_testing_dummy_cred;
 #define WPS_MGMTAUTHKEY_LEN 32
 #define WPS_MGMTENCKEY_LEN 16
 #define WPS_MGMT_KEY_ID_LEN 16
-#define WPS_OOB_DEVICE_PASSWORD_ATTR_LEN 54
+#define WPS_OOB_DEVICE_PASSWORD_MIN_LEN 16
 #define WPS_OOB_DEVICE_PASSWORD_LEN 32
 #define WPS_OOB_PUBKEY_HASH_LEN 20
 

+ 2 - 2
src/wps/wps_i.h

@@ -136,8 +136,6 @@ struct wps_parse_attr {
 	const u8 *assoc_state; /* 2 octets */
 	const u8 *config_error; /* 2 octets */
 	const u8 *dev_password_id; /* 2 octets */
-	const u8 *oob_dev_password; /* WPS_OOB_DEVICE_PASSWORD_ATTR_LEN (54)
-				     * octets */
 	const u8 *os_version; /* 4 octets */
 	const u8 *wps_state; /* 1 octet */
 	const u8 *authenticator; /* WPS_AUTHENTICATOR_LEN (8) octets */
@@ -192,6 +190,8 @@ struct wps_parse_attr {
 	size_t authorized_macs_len;
 	const u8 *sec_dev_type_list; /* <= 128 octets */
 	size_t sec_dev_type_list_len;
+	const u8 *oob_dev_password; /* 38..54 octets */
+	size_t oob_dev_password_len;
 
 	/* attributes that can occur multiple times */
 #define MAX_CRED_COUNT 10