WPS: Split wps_common.c into parts
authorJouni Malinen <j@w1.fi>
Sat, 29 Nov 2008 11:16:26 +0000 (13:16 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 29 Nov 2008 11:16:26 +0000 (13:16 +0200)
To make it easier to find various functions, attribute functions were
split into wps_attr_{build,parse,process}.c.

hostapd/Makefile
src/wps/wps_attr_build.c [new file with mode: 0644]
src/wps/wps_attr_parse.c [new file with mode: 0644]
src/wps/wps_attr_process.c [new file with mode: 0644]
src/wps/wps_common.c
src/wps/wps_i.h
wpa_supplicant/Makefile

index d1c42d6..a1c182c 100644 (file)
@@ -265,6 +265,9 @@ OBJS += wps_hostapd.o
 OBJS += ../src/eap_server/eap_wsc.o ../src/eap_common/eap_wsc_common.o
 OBJS += ../src/wps/wps.o
 OBJS += ../src/wps/wps_common.o
+OBJS += ../src/wps/wps_attr_parse.o
+OBJS += ../src/wps/wps_attr_build.o
+OBJS += ../src/wps/wps_attr_process.o
 OBJS += ../src/wps/wps_dev_attr.o
 OBJS += ../src/wps/wps_enrollee.o
 OBJS += ../src/wps/wps_registrar.o
diff --git a/src/wps/wps_attr_build.c b/src/wps/wps_attr_build.c
new file mode 100644 (file)
index 0000000..c30e17b
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Wi-Fi Protected Setup - attribute building
+ * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "dh_groups.h"
+#include "sha256.h"
+#include "aes_wrap.h"
+#include "wps_i.h"
+
+
+int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
+{
+       struct wpabuf *pubkey;
+
+       wpa_printf(MSG_DEBUG, "WPS:  * Public Key");
+       pubkey = dh_init(dh_groups_get(WPS_DH_GROUP), &wps->dh_privkey);
+       if (pubkey == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS: Failed to initialize "
+                          "Diffie-Hellman handshake");
+               return -1;
+       }
+
+       wpabuf_put_be16(msg, ATTR_PUBLIC_KEY);
+       wpabuf_put_be16(msg, wpabuf_len(pubkey));
+       wpabuf_put_buf(msg, pubkey);
+
+       if (wps->registrar) {
+               wpabuf_free(wps->dh_pubkey_r);
+               wps->dh_pubkey_r = pubkey;
+       } else {
+               wpabuf_free(wps->dh_pubkey_e);
+               wps->dh_pubkey_e = pubkey;
+       }
+
+       return 0;
+}
+
+
+int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Request Type");
+       wpabuf_put_be16(msg, ATTR_REQUEST_TYPE);
+       wpabuf_put_be16(msg, 1);
+       wpabuf_put_u8(msg, type);
+       return 0;
+}
+
+
+int wps_build_config_methods(struct wpabuf *msg, u16 methods)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Config Methods (%x)", methods);
+       wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
+       wpabuf_put_be16(msg, 2);
+       wpabuf_put_be16(msg, methods);
+       return 0;
+}
+
+
+int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * UUID-E");
+       wpabuf_put_be16(msg, ATTR_UUID_E);
+       wpabuf_put_be16(msg, WPS_UUID_LEN);
+       wpabuf_put_data(msg, uuid, WPS_UUID_LEN);
+       return 0;
+}
+
+
+int wps_build_dev_password_id(struct wpabuf *msg, u16 id)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID (%d)", id);
+       wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
+       wpabuf_put_be16(msg, 2);
+       wpabuf_put_be16(msg, id);
+       return 0;
+}
+
+
+int wps_build_config_error(struct wpabuf *msg, u16 err)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Configuration Error (%d)", err);
+       wpabuf_put_be16(msg, ATTR_CONFIG_ERROR);
+       wpabuf_put_be16(msg, 2);
+       wpabuf_put_be16(msg, err);
+       return 0;
+}
+
+
+int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg)
+{
+       u8 hash[SHA256_MAC_LEN];
+       const u8 *addr[2];
+       size_t len[2];
+
+       if (wps->last_msg == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
+                          "building authenticator");
+               return -1;
+       }
+
+       /* Authenticator = HMAC-SHA256_AuthKey(M_prev || M_curr*)
+        * (M_curr* is M_curr without the Authenticator attribute)
+        */
+       addr[0] = wpabuf_head(wps->last_msg);
+       len[0] = wpabuf_len(wps->last_msg);
+       addr[1] = wpabuf_head(msg);
+       len[1] = wpabuf_len(msg);
+       hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
+
+       wpa_printf(MSG_DEBUG, "WPS:  * Authenticator");
+       wpabuf_put_be16(msg, ATTR_AUTHENTICATOR);
+       wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN);
+       wpabuf_put_data(msg, hash, WPS_AUTHENTICATOR_LEN);
+
+       return 0;
+}
+
+
+int wps_build_version(struct wpabuf *msg)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Version");
+       wpabuf_put_be16(msg, ATTR_VERSION);
+       wpabuf_put_be16(msg, 1);
+       wpabuf_put_u8(msg, WPS_VERSION);
+       return 0;
+}
+
+
+int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Message Type (%d)", msg_type);
+       wpabuf_put_be16(msg, ATTR_MSG_TYPE);
+       wpabuf_put_be16(msg, 1);
+       wpabuf_put_u8(msg, msg_type);
+       return 0;
+}
+
+
+int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Enrollee Nonce");
+       wpabuf_put_be16(msg, ATTR_ENROLLEE_NONCE);
+       wpabuf_put_be16(msg, WPS_NONCE_LEN);
+       wpabuf_put_data(msg, wps->nonce_e, WPS_NONCE_LEN);
+       return 0;
+}
+
+
+int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Registrar Nonce");
+       wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
+       wpabuf_put_be16(msg, WPS_NONCE_LEN);
+       wpabuf_put_data(msg, wps->nonce_r, WPS_NONCE_LEN);
+       return 0;
+}
+
+
+int wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type Flags");
+       wpabuf_put_be16(msg, ATTR_AUTH_TYPE_FLAGS);
+       wpabuf_put_be16(msg, 2);
+       wpabuf_put_be16(msg, WPS_AUTH_TYPES);
+       return 0;
+}
+
+
+int wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type Flags");
+       wpabuf_put_be16(msg, ATTR_ENCR_TYPE_FLAGS);
+       wpabuf_put_be16(msg, 2);
+       wpabuf_put_be16(msg, WPS_ENCR_TYPES);
+       return 0;
+}
+
+
+int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Connection Type Flags");
+       wpabuf_put_be16(msg, ATTR_CONN_TYPE_FLAGS);
+       wpabuf_put_be16(msg, 1);
+       wpabuf_put_u8(msg, WPS_CONN_ESS);
+       return 0;
+}
+
+
+int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * Association State");
+       wpabuf_put_be16(msg, ATTR_ASSOC_STATE);
+       wpabuf_put_be16(msg, 2);
+       wpabuf_put_be16(msg, WPS_ASSOC_NOT_ASSOC);
+       return 0;
+}
+
+
+int wps_build_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg)
+{
+       u8 hash[SHA256_MAC_LEN];
+
+       wpa_printf(MSG_DEBUG, "WPS:  * Key Wrap Authenticator");
+       hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg),
+                   wpabuf_len(msg), hash);
+
+       wpabuf_put_be16(msg, ATTR_KEY_WRAP_AUTH);
+       wpabuf_put_be16(msg, WPS_KWA_LEN);
+       wpabuf_put_data(msg, hash, WPS_KWA_LEN);
+       return 0;
+}
+
+
+int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg,
+                           struct wpabuf *plain)
+{
+       size_t pad_len;
+       const size_t block_size = 16;
+       u8 *iv, *data;
+
+       wpa_printf(MSG_DEBUG, "WPS:  * Encrypted Settings");
+
+       /* PKCS#5 v2.0 pad */
+       pad_len = block_size - wpabuf_len(plain) % block_size;
+       os_memset(wpabuf_put(plain, pad_len), pad_len, pad_len);
+
+       wpabuf_put_be16(msg, ATTR_ENCR_SETTINGS);
+       wpabuf_put_be16(msg, block_size + wpabuf_len(plain));
+
+       iv = wpabuf_put(msg, block_size);
+       if (os_get_random(iv, block_size) < 0)
+               return -1;
+
+       data = wpabuf_put(msg, 0);
+       wpabuf_put_buf(msg, plain);
+       if (aes_128_cbc_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain)))
+               return -1;
+
+       return 0;
+}
diff --git a/src/wps/wps_attr_parse.c b/src/wps/wps_attr_parse.c
new file mode 100644 (file)
index 0000000..25ff251
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * Wi-Fi Protected Setup - attribute parsing
+ * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "wps_i.h"
+
+
+static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
+                       const u8 *pos, u16 len)
+{
+       switch (type) {
+       case ATTR_VERSION:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Version length %u",
+                                  len);
+                       return -1;
+               }
+               attr->version = pos;
+               break;
+       case ATTR_MSG_TYPE:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->msg_type = pos;
+               break;
+       case ATTR_ENROLLEE_NONCE:
+               if (len != WPS_NONCE_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->enrollee_nonce = pos;
+               break;
+       case ATTR_REGISTRAR_NONCE:
+               if (len != WPS_NONCE_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->registrar_nonce = pos;
+               break;
+       case ATTR_UUID_E:
+               if (len != WPS_UUID_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-E length %u",
+                                  len);
+                       return -1;
+               }
+               attr->uuid_e = pos;
+               break;
+       case ATTR_UUID_R:
+               if (len != WPS_UUID_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-R length %u",
+                                  len);
+                       return -1;
+               }
+               attr->uuid_r = pos;
+               break;
+       case ATTR_AUTH_TYPE_FLAGS:
+               if (len != 2) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
+                                  "Type Flags length %u", len);
+                       return -1;
+               }
+               attr->auth_type_flags = pos;
+               break;
+       case ATTR_ENCR_TYPE_FLAGS:
+               if (len != 2) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption Type "
+                                  "Flags length %u", len);
+                       return -1;
+               }
+               attr->encr_type_flags = pos;
+               break;
+       case ATTR_CONN_TYPE_FLAGS:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Connection Type "
+                                  "Flags length %u", len);
+                       return -1;
+               }
+               attr->conn_type_flags = pos;
+               break;
+       case ATTR_CONFIG_METHODS:
+               if (len != 2) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Config Methods "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->config_methods = pos;
+               break;
+       case ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
+               if (len != 2) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Selected "
+                                  "Registrar Config Methods length %u", len);
+                       return -1;
+               }
+               attr->sel_reg_config_methods = pos;
+               break;
+       case ATTR_PRIMARY_DEV_TYPE:
+               if (len != sizeof(struct wps_dev_type)) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device "
+                                  "Type length %u", len);
+                       return -1;
+               }
+               attr->primary_dev_type = pos;
+               break;
+       case ATTR_RF_BANDS:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid RF Bands length "
+                                  "%u", len);
+                       return -1;
+               }
+               attr->rf_bands = pos;
+               break;
+       case ATTR_ASSOC_STATE:
+               if (len != 2) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Association State "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->assoc_state = pos;
+               break;
+       case ATTR_CONFIG_ERROR:
+               if (len != 2) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Configuration "
+                                  "Error length %u", len);
+                       return -1;
+               }
+               attr->config_error = pos;
+               break;
+       case ATTR_DEV_PASSWORD_ID:
+               if (len != 2) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Device Password "
+                                  "ID length %u", len);
+                       return -1;
+               }
+               attr->dev_password_id = pos;
+               break;
+       case ATTR_OS_VERSION:
+               if (len != 4) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid OS Version length "
+                                  "%u", len);
+                       return -1;
+               }
+               attr->os_version = pos;
+               break;
+       case ATTR_WPS_STATE:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Wi-Fi Protected "
+                                  "Setup State length %u", len);
+                       return -1;
+               }
+               attr->wps_state = pos;
+               break;
+       case ATTR_AUTHENTICATOR:
+               if (len != WPS_AUTHENTICATOR_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Authenticator "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->authenticator = pos;
+               break;
+       case ATTR_R_HASH1:
+               if (len != WPS_HASH_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash1 length %u",
+                                  len);
+                       return -1;
+               }
+               attr->r_hash1 = pos;
+               break;
+       case ATTR_R_HASH2:
+               if (len != WPS_HASH_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash2 length %u",
+                                  len);
+                       return -1;
+               }
+               attr->r_hash2 = pos;
+               break;
+       case ATTR_E_HASH1:
+               if (len != WPS_HASH_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash1 length %u",
+                                  len);
+                       return -1;
+               }
+               attr->e_hash1 = pos;
+               break;
+       case ATTR_E_HASH2:
+               if (len != WPS_HASH_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash2 length %u",
+                                  len);
+                       return -1;
+               }
+               attr->e_hash2 = pos;
+               break;
+       case ATTR_R_SNONCE1:
+               if (len != WPS_SECRET_NONCE_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce1 length "
+                                  "%u", len);
+                       return -1;
+               }
+               attr->r_snonce1 = pos;
+               break;
+       case ATTR_R_SNONCE2:
+               if (len != WPS_SECRET_NONCE_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce2 length "
+                                  "%u", len);
+                       return -1;
+               }
+               attr->r_snonce2 = pos;
+               break;
+       case ATTR_E_SNONCE1:
+               if (len != WPS_SECRET_NONCE_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce1 length "
+                                  "%u", len);
+                       return -1;
+               }
+               attr->e_snonce1 = pos;
+               break;
+       case ATTR_E_SNONCE2:
+               if (len != WPS_SECRET_NONCE_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce2 length "
+                                  "%u", len);
+                       return -1;
+               }
+               attr->e_snonce2 = pos;
+               break;
+       case ATTR_KEY_WRAP_AUTH:
+               if (len != WPS_KWA_LEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Key Wrap "
+                                  "Authenticator length %u", len);
+                       return -1;
+               }
+               attr->key_wrap_auth = pos;
+               break;
+       case ATTR_AUTH_TYPE:
+               if (len != 2) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
+                                  "Type length %u", len);
+                       return -1;
+               }
+               attr->auth_type = pos;
+               break;
+       case ATTR_ENCR_TYPE:
+               if (len != 2) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption "
+                                  "Type length %u", len);
+                       return -1;
+               }
+               attr->encr_type = pos;
+               break;
+       case ATTR_NETWORK_INDEX:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Network Index "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->network_idx = pos;
+               break;
+       case ATTR_NETWORK_KEY_INDEX:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key Index "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->network_key_idx = pos;
+               break;
+       case ATTR_MAC_ADDR:
+               if (len != ETH_ALEN) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid MAC Address "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->mac_addr = pos;
+               break;
+       case ATTR_KEY_PROVIDED_AUTO:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Key Provided "
+                                  "Automatically length %u", len);
+                       return -1;
+               }
+               attr->key_prov_auto = pos;
+               break;
+       case ATTR_802_1X_ENABLED:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid 802.1X Enabled "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->dot1x_enabled = pos;
+               break;
+       case ATTR_SELECTED_REGISTRAR:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Selected Registrar"
+                                  " length %u", len);
+                       return -1;
+               }
+               attr->selected_registrar = pos;
+               break;
+       case ATTR_REQUEST_TYPE:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Request Type "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->request_type = pos;
+               break;
+       case ATTR_RESPONSE_TYPE:
+               if (len != 1) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid Response Type "
+                                  "length %u", len);
+                       return -1;
+               }
+               attr->request_type = pos;
+               break;
+       case ATTR_MANUFACTURER:
+               attr->manufacturer = pos;
+               attr->manufacturer_len = len;
+               break;
+       case ATTR_MODEL_NAME:
+               attr->model_name = pos;
+               attr->model_name_len = len;
+               break;
+       case ATTR_MODEL_NUMBER:
+               attr->model_number = pos;
+               attr->model_number_len = len;
+               break;
+       case ATTR_SERIAL_NUMBER:
+               attr->serial_number = pos;
+               attr->serial_number_len = len;
+               break;
+       case ATTR_DEV_NAME:
+               attr->dev_name = pos;
+               attr->dev_name_len = len;
+               break;
+       case ATTR_PUBLIC_KEY:
+               attr->public_key = pos;
+               attr->public_key_len = len;
+               break;
+       case ATTR_ENCR_SETTINGS:
+               attr->encr_settings = pos;
+               attr->encr_settings_len = len;
+               break;
+       case ATTR_CRED:
+               if (attr->num_cred >= MAX_CRED_COUNT) {
+                       wpa_printf(MSG_DEBUG, "WPS: Skipped Credential "
+                                  "attribute (max %d credentials)",
+                                  MAX_CRED_COUNT);
+                       break;
+               }
+               attr->cred[attr->num_cred] = pos;
+               attr->cred_len[attr->num_cred] = len;
+               attr->num_cred++;
+               break;
+       case ATTR_SSID:
+               attr->ssid = pos;
+               attr->ssid_len = len;
+               break;
+       case ATTR_NETWORK_KEY:
+               attr->network_key = pos;
+               attr->network_key_len = len;
+               break;
+       case ATTR_EAP_TYPE:
+               attr->eap_type = pos;
+               attr->eap_type_len = len;
+               break;
+       case ATTR_EAP_IDENTITY:
+               attr->eap_identity = pos;
+               attr->eap_identity_len = len;
+               break;
+       default:
+               wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
+                          "len=%u", type, len);
+               break;
+       }
+
+       return 0;
+}
+
+
+int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
+{
+       const u8 *pos, *end;
+       u16 type, len;
+
+       os_memset(attr, 0, sizeof(*attr));
+       pos = wpabuf_head(msg);
+       end = pos + wpabuf_len(msg);
+
+       while (pos < end) {
+               if (end - pos < 4) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid message - "
+                                  "%lu bytes remaining",
+                                  (unsigned long) (end - pos));
+                       return -1;
+               }
+
+               type = WPA_GET_BE16(pos);
+               pos += 2;
+               len = WPA_GET_BE16(pos);
+               pos += 2;
+               wpa_printf(MSG_MSGDUMP, "WPS: attr type=0x%x len=%u",
+                          type, len);
+               if (len > end - pos) {
+                       wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");
+                       return -1;
+               }
+
+               if (wps_set_attr(attr, type, pos, len) < 0)
+                       return -1;
+
+               pos += len;
+       }
+
+       return 0;
+}
diff --git a/src/wps/wps_attr_process.c b/src/wps/wps_attr_process.c
new file mode 100644 (file)
index 0000000..c1b59f7
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * Wi-Fi Protected Setup - attribute processing
+ * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "sha256.h"
+#include "wps_i.h"
+
+
+int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
+                             const struct wpabuf *msg)
+{
+       u8 hash[SHA256_MAC_LEN];
+       const u8 *addr[2];
+       size_t len[2];
+
+       if (authenticator == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS: No Authenticator attribute "
+                          "included");
+               return -1;
+       }
+
+       if (wps->last_msg == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
+                          "validating authenticator");
+               return -1;
+       }
+
+       /* Authenticator = HMAC-SHA256_AuthKey(M_prev || M_curr*)
+        * (M_curr* is M_curr without the Authenticator attribute)
+        */
+       addr[0] = wpabuf_head(wps->last_msg);
+       len[0] = wpabuf_len(wps->last_msg);
+       addr[1] = wpabuf_head(msg);
+       len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN;
+       hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
+
+       if (os_memcmp(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
+               wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator");
+               return -1;
+       }
+
+       return 0;
+}
+
+
+int wps_process_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg,
+                             const u8 *key_wrap_auth)
+{
+       u8 hash[SHA256_MAC_LEN];
+       const u8 *head;
+       size_t len;
+
+       if (key_wrap_auth == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS: No KWA in decrypted attribute");
+               return -1;
+       }
+
+       head = wpabuf_head(msg);
+       len = wpabuf_len(msg) - 4 - WPS_KWA_LEN;
+       if (head + len != key_wrap_auth - 4) {
+               wpa_printf(MSG_DEBUG, "WPS: KWA not in the end of the "
+                          "decrypted attribute");
+               return -1;
+       }
+
+       hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash);
+       if (os_memcmp(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
+               wpa_printf(MSG_DEBUG, "WPS: Invalid KWA");
+               return -1;
+       }
+
+       return 0;
+}
+
+
+static int wps_process_cred_network_idx(struct wps_credential *cred,
+                                       const u8 *idx)
+{
+       if (idx == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
+                          "Network Index");
+               return -1;
+       }
+
+       wpa_printf(MSG_DEBUG, "WPS: Network Index: %d", *idx);
+
+       return 0;
+}
+
+
+static int wps_process_cred_ssid(struct wps_credential *cred, const u8 *ssid,
+                                size_t ssid_len)
+{
+       if (ssid == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS: Credential did not include SSID");
+               return -1;
+       }
+
+       /* Remove zero-padding since some Registrar implementations seem to use
+        * hardcoded 32-octet length for this attribute */
+       while (ssid_len > 0 && ssid[ssid_len - 1] == 0)
+               ssid_len--;
+
+       wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", ssid, ssid_len);
+       if (ssid_len <= sizeof(cred->ssid)) {
+               os_memcpy(cred->ssid, ssid, ssid_len);
+               cred->ssid_len = ssid_len;
+       }
+
+       return 0;
+}
+
+
+static int wps_process_cred_auth_type(struct wps_credential *cred,
+                                     const u8 *auth_type)
+{
+       if (auth_type == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
+                          "Authentication Type");
+               return -1;
+       }
+
+       cred->auth_type = WPA_GET_BE16(auth_type);
+       wpa_printf(MSG_DEBUG, "WPS: Authentication Type: 0x%x",
+                  cred->auth_type);
+
+       return 0;
+}
+
+
+static int wps_process_cred_encr_type(struct wps_credential *cred,
+                                     const u8 *encr_type)
+{
+       if (encr_type == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
+                          "Encryption Type");
+               return -1;
+       }
+
+       cred->encr_type = WPA_GET_BE16(encr_type);
+       wpa_printf(MSG_DEBUG, "WPS: Encryption Type: 0x%x",
+                  cred->encr_type);
+
+       return 0;
+}
+
+
+static int wps_process_cred_network_key_idx(struct wps_credential *cred,
+                                           const u8 *key_idx)
+{
+       if (key_idx == NULL)
+               return 0; /* optional attribute */
+
+       wpa_printf(MSG_DEBUG, "WPS: Network Key Index: %d", *key_idx);
+       cred->key_idx = *key_idx;
+
+       return 0;
+}
+
+
+static int wps_process_cred_network_key(struct wps_credential *cred,
+                                       const u8 *key, size_t key_len)
+{
+       if (key == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
+                          "Network Key");
+               return -1;
+       }
+
+       wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key", key, key_len);
+       if (key_len <= sizeof(cred->key)) {
+               os_memcpy(cred->key, key, key_len);
+               cred->key_len = key_len;
+       }
+
+       return 0;
+}
+
+
+static int wps_process_cred_mac_addr(struct wps_credential *cred,
+                                    const u8 *mac_addr)
+{
+       if (mac_addr == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
+                          "MAC Address");
+               return -1;
+       }
+
+       wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR, MAC2STR(mac_addr));
+       os_memcpy(cred->mac_addr, mac_addr, ETH_ALEN);
+
+       return 0;
+}
+
+
+static int wps_process_cred_eap_type(struct wps_credential *cred,
+                                    const u8 *eap_type, size_t eap_type_len)
+{
+       if (eap_type == NULL)
+               return 0; /* optional attribute */
+
+       wpa_hexdump(MSG_DEBUG, "WPS: EAP Type", eap_type, eap_type_len);
+
+       return 0;
+}
+
+
+static int wps_process_cred_eap_identity(struct wps_credential *cred,
+                                        const u8 *identity,
+                                        size_t identity_len)
+{
+       if (identity == NULL)
+               return 0; /* optional attribute */
+
+       wpa_hexdump_ascii(MSG_DEBUG, "WPS: EAP Identity",
+                         identity, identity_len);
+
+       return 0;
+}
+
+
+static int wps_process_cred_key_prov_auto(struct wps_credential *cred,
+                                         const u8 *key_prov_auto)
+{
+       if (key_prov_auto == NULL)
+               return 0; /* optional attribute */
+
+       wpa_printf(MSG_DEBUG, "WPS: Key Provided Automatically: %d",
+                  *key_prov_auto);
+
+       return 0;
+}
+
+
+static int wps_process_cred_802_1x_enabled(struct wps_credential *cred,
+                                          const u8 *dot1x_enabled)
+{
+       if (dot1x_enabled == NULL)
+               return 0; /* optional attribute */
+
+       wpa_printf(MSG_DEBUG, "WPS: 802.1X Enabled: %d", *dot1x_enabled);
+
+       return 0;
+}
+
+
+int wps_process_cred(struct wps_parse_attr *attr,
+                    struct wps_credential *cred)
+{
+       wpa_printf(MSG_DEBUG, "WPS: Process Credential");
+
+       /* TODO: support multiple Network Keys */
+       if (wps_process_cred_network_idx(cred, attr->network_idx) ||
+           wps_process_cred_ssid(cred, attr->ssid, attr->ssid_len) ||
+           wps_process_cred_auth_type(cred, attr->auth_type) ||
+           wps_process_cred_encr_type(cred, attr->encr_type) ||
+           wps_process_cred_network_key_idx(cred, attr->network_key_idx) ||
+           wps_process_cred_network_key(cred, attr->network_key,
+                                        attr->network_key_len) ||
+           wps_process_cred_mac_addr(cred, attr->mac_addr) ||
+           wps_process_cred_eap_type(cred, attr->eap_type,
+                                     attr->eap_type_len) ||
+           wps_process_cred_eap_identity(cred, attr->eap_identity,
+                                         attr->eap_identity_len) ||
+           wps_process_cred_key_prov_auto(cred, attr->key_prov_auto) ||
+           wps_process_cred_802_1x_enabled(cred, attr->dot1x_enabled))
+               return -1;
+
+       return 0;
+}
+
+
+int wps_process_ap_settings(struct wps_parse_attr *attr,
+                           struct wps_credential *cred)
+{
+       wpa_printf(MSG_DEBUG, "WPS: Processing AP Settings");
+       os_memset(cred, 0, sizeof(*cred));
+       /* TODO: optional attributes New Password and Device Password ID */
+       if (wps_process_cred_ssid(cred, attr->ssid, attr->ssid_len) ||
+           wps_process_cred_auth_type(cred, attr->auth_type) ||
+           wps_process_cred_encr_type(cred, attr->encr_type) ||
+           wps_process_cred_network_key_idx(cred, attr->network_key_idx) ||
+           wps_process_cred_network_key(cred, attr->network_key,
+                                        attr->network_key_len) ||
+           wps_process_cred_mac_addr(cred, attr->mac_addr))
+               return -1;
+
+       return 0;
+}
index 7eda594..3edb1e3 100644 (file)
 #include "wps_dev_attr.h"
 
 
-static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
-                       const u8 *pos, u16 len)
-{
-       switch (type) {
-       case ATTR_VERSION:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Version length %u",
-                                  len);
-                       return -1;
-               }
-               attr->version = pos;
-               break;
-       case ATTR_MSG_TYPE:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->msg_type = pos;
-               break;
-       case ATTR_ENROLLEE_NONCE:
-               if (len != WPS_NONCE_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->enrollee_nonce = pos;
-               break;
-       case ATTR_REGISTRAR_NONCE:
-               if (len != WPS_NONCE_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->registrar_nonce = pos;
-               break;
-       case ATTR_UUID_E:
-               if (len != WPS_UUID_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-E length %u",
-                                  len);
-                       return -1;
-               }
-               attr->uuid_e = pos;
-               break;
-       case ATTR_UUID_R:
-               if (len != WPS_UUID_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-R length %u",
-                                  len);
-                       return -1;
-               }
-               attr->uuid_r = pos;
-               break;
-       case ATTR_AUTH_TYPE_FLAGS:
-               if (len != 2) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
-                                  "Type Flags length %u", len);
-                       return -1;
-               }
-               attr->auth_type_flags = pos;
-               break;
-       case ATTR_ENCR_TYPE_FLAGS:
-               if (len != 2) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption Type "
-                                  "Flags length %u", len);
-                       return -1;
-               }
-               attr->encr_type_flags = pos;
-               break;
-       case ATTR_CONN_TYPE_FLAGS:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Connection Type "
-                                  "Flags length %u", len);
-                       return -1;
-               }
-               attr->conn_type_flags = pos;
-               break;
-       case ATTR_CONFIG_METHODS:
-               if (len != 2) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Config Methods "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->config_methods = pos;
-               break;
-       case ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
-               if (len != 2) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Selected "
-                                  "Registrar Config Methods length %u", len);
-                       return -1;
-               }
-               attr->sel_reg_config_methods = pos;
-               break;
-       case ATTR_PRIMARY_DEV_TYPE:
-               if (len != sizeof(struct wps_dev_type)) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device "
-                                  "Type length %u", len);
-                       return -1;
-               }
-               attr->primary_dev_type = pos;
-               break;
-       case ATTR_RF_BANDS:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid RF Bands length "
-                                  "%u", len);
-                       return -1;
-               }
-               attr->rf_bands = pos;
-               break;
-       case ATTR_ASSOC_STATE:
-               if (len != 2) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Association State "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->assoc_state = pos;
-               break;
-       case ATTR_CONFIG_ERROR:
-               if (len != 2) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Configuration "
-                                  "Error length %u", len);
-                       return -1;
-               }
-               attr->config_error = pos;
-               break;
-       case ATTR_DEV_PASSWORD_ID:
-               if (len != 2) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Device Password "
-                                  "ID length %u", len);
-                       return -1;
-               }
-               attr->dev_password_id = pos;
-               break;
-       case ATTR_OS_VERSION:
-               if (len != 4) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid OS Version length "
-                                  "%u", len);
-                       return -1;
-               }
-               attr->os_version = pos;
-               break;
-       case ATTR_WPS_STATE:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Wi-Fi Protected "
-                                  "Setup State length %u", len);
-                       return -1;
-               }
-               attr->wps_state = pos;
-               break;
-       case ATTR_AUTHENTICATOR:
-               if (len != WPS_AUTHENTICATOR_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Authenticator "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->authenticator = pos;
-               break;
-       case ATTR_R_HASH1:
-               if (len != WPS_HASH_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash1 length %u",
-                                  len);
-                       return -1;
-               }
-               attr->r_hash1 = pos;
-               break;
-       case ATTR_R_HASH2:
-               if (len != WPS_HASH_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash2 length %u",
-                                  len);
-                       return -1;
-               }
-               attr->r_hash2 = pos;
-               break;
-       case ATTR_E_HASH1:
-               if (len != WPS_HASH_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash1 length %u",
-                                  len);
-                       return -1;
-               }
-               attr->e_hash1 = pos;
-               break;
-       case ATTR_E_HASH2:
-               if (len != WPS_HASH_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash2 length %u",
-                                  len);
-                       return -1;
-               }
-               attr->e_hash2 = pos;
-               break;
-       case ATTR_R_SNONCE1:
-               if (len != WPS_SECRET_NONCE_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce1 length "
-                                  "%u", len);
-                       return -1;
-               }
-               attr->r_snonce1 = pos;
-               break;
-       case ATTR_R_SNONCE2:
-               if (len != WPS_SECRET_NONCE_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce2 length "
-                                  "%u", len);
-                       return -1;
-               }
-               attr->r_snonce2 = pos;
-               break;
-       case ATTR_E_SNONCE1:
-               if (len != WPS_SECRET_NONCE_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce1 length "
-                                  "%u", len);
-                       return -1;
-               }
-               attr->e_snonce1 = pos;
-               break;
-       case ATTR_E_SNONCE2:
-               if (len != WPS_SECRET_NONCE_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce2 length "
-                                  "%u", len);
-                       return -1;
-               }
-               attr->e_snonce2 = pos;
-               break;
-       case ATTR_KEY_WRAP_AUTH:
-               if (len != WPS_KWA_LEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Key Wrap "
-                                  "Authenticator length %u", len);
-                       return -1;
-               }
-               attr->key_wrap_auth = pos;
-               break;
-       case ATTR_AUTH_TYPE:
-               if (len != 2) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
-                                  "Type length %u", len);
-                       return -1;
-               }
-               attr->auth_type = pos;
-               break;
-       case ATTR_ENCR_TYPE:
-               if (len != 2) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption "
-                                  "Type length %u", len);
-                       return -1;
-               }
-               attr->encr_type = pos;
-               break;
-       case ATTR_NETWORK_INDEX:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Network Index "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->network_idx = pos;
-               break;
-       case ATTR_NETWORK_KEY_INDEX:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key Index "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->network_key_idx = pos;
-               break;
-       case ATTR_MAC_ADDR:
-               if (len != ETH_ALEN) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid MAC Address "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->mac_addr = pos;
-               break;
-       case ATTR_KEY_PROVIDED_AUTO:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Key Provided "
-                                  "Automatically length %u", len);
-                       return -1;
-               }
-               attr->key_prov_auto = pos;
-               break;
-       case ATTR_802_1X_ENABLED:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid 802.1X Enabled "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->dot1x_enabled = pos;
-               break;
-       case ATTR_SELECTED_REGISTRAR:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Selected Registrar"
-                                  " length %u", len);
-                       return -1;
-               }
-               attr->selected_registrar = pos;
-               break;
-       case ATTR_REQUEST_TYPE:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Request Type "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->request_type = pos;
-               break;
-       case ATTR_RESPONSE_TYPE:
-               if (len != 1) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid Response Type "
-                                  "length %u", len);
-                       return -1;
-               }
-               attr->request_type = pos;
-               break;
-       case ATTR_MANUFACTURER:
-               attr->manufacturer = pos;
-               attr->manufacturer_len = len;
-               break;
-       case ATTR_MODEL_NAME:
-               attr->model_name = pos;
-               attr->model_name_len = len;
-               break;
-       case ATTR_MODEL_NUMBER:
-               attr->model_number = pos;
-               attr->model_number_len = len;
-               break;
-       case ATTR_SERIAL_NUMBER:
-               attr->serial_number = pos;
-               attr->serial_number_len = len;
-               break;
-       case ATTR_DEV_NAME:
-               attr->dev_name = pos;
-               attr->dev_name_len = len;
-               break;
-       case ATTR_PUBLIC_KEY:
-               attr->public_key = pos;
-               attr->public_key_len = len;
-               break;
-       case ATTR_ENCR_SETTINGS:
-               attr->encr_settings = pos;
-               attr->encr_settings_len = len;
-               break;
-       case ATTR_CRED:
-               if (attr->num_cred >= MAX_CRED_COUNT) {
-                       wpa_printf(MSG_DEBUG, "WPS: Skipped Credential "
-                                  "attribute (max %d credentials)",
-                                  MAX_CRED_COUNT);
-                       break;
-               }
-               attr->cred[attr->num_cred] = pos;
-               attr->cred_len[attr->num_cred] = len;
-               attr->num_cred++;
-               break;
-       case ATTR_SSID:
-               attr->ssid = pos;
-               attr->ssid_len = len;
-               break;
-       case ATTR_NETWORK_KEY:
-               attr->network_key = pos;
-               attr->network_key_len = len;
-               break;
-       case ATTR_EAP_TYPE:
-               attr->eap_type = pos;
-               attr->eap_type_len = len;
-               break;
-       case ATTR_EAP_IDENTITY:
-               attr->eap_identity = pos;
-               attr->eap_identity_len = len;
-               break;
-       default:
-               wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
-                          "len=%u", type, len);
-               break;
-       }
-
-       return 0;
-}
-
-
-int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
-{
-       const u8 *pos, *end;
-       u16 type, len;
-
-       os_memset(attr, 0, sizeof(*attr));
-       pos = wpabuf_head(msg);
-       end = pos + wpabuf_len(msg);
-
-       while (pos < end) {
-               if (end - pos < 4) {
-                       wpa_printf(MSG_DEBUG, "WPS: Invalid message - "
-                                  "%lu bytes remaining",
-                                  (unsigned long) (end - pos));
-                       return -1;
-               }
-
-               type = WPA_GET_BE16(pos);
-               pos += 2;
-               len = WPA_GET_BE16(pos);
-               pos += 2;
-               wpa_printf(MSG_MSGDUMP, "WPS: attr type=0x%x len=%u",
-                          type, len);
-               if (len > end - pos) {
-                       wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");
-                       return -1;
-               }
-
-               if (wps_set_attr(attr, type, pos, len) < 0)
-                       return -1;
-
-               pos += len;
-       }
-
-       return 0;
-}
-
-
 void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
             const char *label, u8 *res, size_t res_len)
 {
@@ -473,84 +62,6 @@ void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
 }
 
 
-int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
-{
-       struct wpabuf *pubkey;
-
-       wpa_printf(MSG_DEBUG, "WPS:  * Public Key");
-       pubkey = dh_init(dh_groups_get(WPS_DH_GROUP), &wps->dh_privkey);
-       if (pubkey == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS: Failed to initialize "
-                          "Diffie-Hellman handshake");
-               return -1;
-       }
-
-       wpabuf_put_be16(msg, ATTR_PUBLIC_KEY);
-       wpabuf_put_be16(msg, wpabuf_len(pubkey));
-       wpabuf_put_buf(msg, pubkey);
-
-       if (wps->registrar) {
-               wpabuf_free(wps->dh_pubkey_r);
-               wps->dh_pubkey_r = pubkey;
-       } else {
-               wpabuf_free(wps->dh_pubkey_e);
-               wps->dh_pubkey_e = pubkey;
-       }
-
-       return 0;
-}
-
-
-static int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Request Type");
-       wpabuf_put_be16(msg, ATTR_REQUEST_TYPE);
-       wpabuf_put_be16(msg, 1);
-       wpabuf_put_u8(msg, type);
-       return 0;
-}
-
-
-int wps_build_config_methods(struct wpabuf *msg, u16 methods)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Config Methods (%x)", methods);
-       wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
-       wpabuf_put_be16(msg, 2);
-       wpabuf_put_be16(msg, methods);
-       return 0;
-}
-
-
-int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * UUID-E");
-       wpabuf_put_be16(msg, ATTR_UUID_E);
-       wpabuf_put_be16(msg, WPS_UUID_LEN);
-       wpabuf_put_data(msg, uuid, WPS_UUID_LEN);
-       return 0;
-}
-
-
-int wps_build_dev_password_id(struct wpabuf *msg, u16 id)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID (%d)", id);
-       wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
-       wpabuf_put_be16(msg, 2);
-       wpabuf_put_be16(msg, id);
-       return 0;
-}
-
-
-int wps_build_config_error(struct wpabuf *msg, u16 err)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Configuration Error (%d)", err);
-       wpabuf_put_be16(msg, ATTR_CONFIG_ERROR);
-       wpabuf_put_be16(msg, 2);
-       wpabuf_put_be16(msg, err);
-       return 0;
-}
-
-
 struct wpabuf * wps_build_assoc_req_ie(void)
 {
        struct wpabuf *ie;
@@ -737,73 +248,6 @@ int wps_derive_mgmt_keys(struct wps_data *wps)
 }
 
 
-int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg)
-{
-       u8 hash[SHA256_MAC_LEN];
-       const u8 *addr[2];
-       size_t len[2];
-
-       if (wps->last_msg == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
-                          "building authenticator");
-               return -1;
-       }
-
-       /* Authenticator = HMAC-SHA256_AuthKey(M_prev || M_curr*)
-        * (M_curr* is M_curr without the Authenticator attribute)
-        */
-       addr[0] = wpabuf_head(wps->last_msg);
-       len[0] = wpabuf_len(wps->last_msg);
-       addr[1] = wpabuf_head(msg);
-       len[1] = wpabuf_len(msg);
-       hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
-
-       wpa_printf(MSG_DEBUG, "WPS:  * Authenticator");
-       wpabuf_put_be16(msg, ATTR_AUTHENTICATOR);
-       wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN);
-       wpabuf_put_data(msg, hash, WPS_AUTHENTICATOR_LEN);
-
-       return 0;
-}
-
-
-int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
-                             const struct wpabuf *msg)
-{
-       u8 hash[SHA256_MAC_LEN];
-       const u8 *addr[2];
-       size_t len[2];
-
-       if (authenticator == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS: No Authenticator attribute "
-                          "included");
-               return -1;
-       }
-
-       if (wps->last_msg == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
-                          "validating authenticator");
-               return -1;
-       }
-
-       /* Authenticator = HMAC-SHA256_AuthKey(M_prev || M_curr*)
-        * (M_curr* is M_curr without the Authenticator attribute)
-        */
-       addr[0] = wpabuf_head(wps->last_msg);
-       len[0] = wpabuf_len(wps->last_msg);
-       addr[1] = wpabuf_head(msg);
-       len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN;
-       hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
-
-       if (os_memcmp(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
-               wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator");
-               return -1;
-       }
-
-       return 0;
-}
-
-
 void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
                    size_t dev_passwd_len)
 {
@@ -874,373 +318,3 @@ struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
 
        return decrypted;
 }
-
-
-int wps_process_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg,
-                             const u8 *key_wrap_auth)
-{
-       u8 hash[SHA256_MAC_LEN];
-       const u8 *head;
-       size_t len;
-
-       if (key_wrap_auth == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS: No KWA in decrypted attribute");
-               return -1;
-       }
-
-       head = wpabuf_head(msg);
-       len = wpabuf_len(msg) - 4 - WPS_KWA_LEN;
-       if (head + len != key_wrap_auth - 4) {
-               wpa_printf(MSG_DEBUG, "WPS: KWA not in the end of the "
-                          "decrypted attribute");
-               return -1;
-       }
-
-       hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash);
-       if (os_memcmp(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
-               wpa_printf(MSG_DEBUG, "WPS: Invalid KWA");
-               return -1;
-       }
-
-       return 0;
-}
-
-
-int wps_build_version(struct wpabuf *msg)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Version");
-       wpabuf_put_be16(msg, ATTR_VERSION);
-       wpabuf_put_be16(msg, 1);
-       wpabuf_put_u8(msg, WPS_VERSION);
-       return 0;
-}
-
-
-int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Message Type (%d)", msg_type);
-       wpabuf_put_be16(msg, ATTR_MSG_TYPE);
-       wpabuf_put_be16(msg, 1);
-       wpabuf_put_u8(msg, msg_type);
-       return 0;
-}
-
-
-int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Enrollee Nonce");
-       wpabuf_put_be16(msg, ATTR_ENROLLEE_NONCE);
-       wpabuf_put_be16(msg, WPS_NONCE_LEN);
-       wpabuf_put_data(msg, wps->nonce_e, WPS_NONCE_LEN);
-       return 0;
-}
-
-
-int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Registrar Nonce");
-       wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
-       wpabuf_put_be16(msg, WPS_NONCE_LEN);
-       wpabuf_put_data(msg, wps->nonce_r, WPS_NONCE_LEN);
-       return 0;
-}
-
-
-int wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type Flags");
-       wpabuf_put_be16(msg, ATTR_AUTH_TYPE_FLAGS);
-       wpabuf_put_be16(msg, 2);
-       wpabuf_put_be16(msg, WPS_AUTH_TYPES);
-       return 0;
-}
-
-
-int wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type Flags");
-       wpabuf_put_be16(msg, ATTR_ENCR_TYPE_FLAGS);
-       wpabuf_put_be16(msg, 2);
-       wpabuf_put_be16(msg, WPS_ENCR_TYPES);
-       return 0;
-}
-
-
-int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Connection Type Flags");
-       wpabuf_put_be16(msg, ATTR_CONN_TYPE_FLAGS);
-       wpabuf_put_be16(msg, 1);
-       wpabuf_put_u8(msg, WPS_CONN_ESS);
-       return 0;
-}
-
-
-int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg)
-{
-       wpa_printf(MSG_DEBUG, "WPS:  * Association State");
-       wpabuf_put_be16(msg, ATTR_ASSOC_STATE);
-       wpabuf_put_be16(msg, 2);
-       wpabuf_put_be16(msg, WPS_ASSOC_NOT_ASSOC);
-       return 0;
-}
-
-
-int wps_build_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg)
-{
-       u8 hash[SHA256_MAC_LEN];
-
-       wpa_printf(MSG_DEBUG, "WPS:  * Key Wrap Authenticator");
-       hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg),
-                   wpabuf_len(msg), hash);
-
-       wpabuf_put_be16(msg, ATTR_KEY_WRAP_AUTH);
-       wpabuf_put_be16(msg, WPS_KWA_LEN);
-       wpabuf_put_data(msg, hash, WPS_KWA_LEN);
-       return 0;
-}
-
-
-int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg,
-                           struct wpabuf *plain)
-{
-       size_t pad_len;
-       const size_t block_size = 16;
-       u8 *iv, *data;
-
-       wpa_printf(MSG_DEBUG, "WPS:  * Encrypted Settings");
-
-       /* PKCS#5 v2.0 pad */
-       pad_len = block_size - wpabuf_len(plain) % block_size;
-       os_memset(wpabuf_put(plain, pad_len), pad_len, pad_len);
-
-       wpabuf_put_be16(msg, ATTR_ENCR_SETTINGS);
-       wpabuf_put_be16(msg, block_size + wpabuf_len(plain));
-
-       iv = wpabuf_put(msg, block_size);
-       if (os_get_random(iv, block_size) < 0)
-               return -1;
-
-       data = wpabuf_put(msg, 0);
-       wpabuf_put_buf(msg, plain);
-       if (aes_128_cbc_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain)))
-               return -1;
-
-       return 0;
-}
-
-
-static int wps_process_cred_network_idx(struct wps_credential *cred,
-                                       const u8 *idx)
-{
-       if (idx == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
-                          "Network Index");
-               return -1;
-       }
-
-       wpa_printf(MSG_DEBUG, "WPS: Network Index: %d", *idx);
-
-       return 0;
-}
-
-
-static int wps_process_cred_ssid(struct wps_credential *cred, const u8 *ssid,
-                                size_t ssid_len)
-{
-       if (ssid == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS: Credential did not include SSID");
-               return -1;
-       }
-
-       /* Remove zero-padding since some Registrar implementations seem to use
-        * hardcoded 32-octet length for this attribute */
-       while (ssid_len > 0 && ssid[ssid_len - 1] == 0)
-               ssid_len--;
-
-       wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", ssid, ssid_len);
-       if (ssid_len <= sizeof(cred->ssid)) {
-               os_memcpy(cred->ssid, ssid, ssid_len);
-               cred->ssid_len = ssid_len;
-       }
-
-       return 0;
-}
-
-
-static int wps_process_cred_auth_type(struct wps_credential *cred,
-                                     const u8 *auth_type)
-{
-       if (auth_type == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
-                          "Authentication Type");
-               return -1;
-       }
-
-       cred->auth_type = WPA_GET_BE16(auth_type);
-       wpa_printf(MSG_DEBUG, "WPS: Authentication Type: 0x%x",
-                  cred->auth_type);
-
-       return 0;
-}
-
-
-static int wps_process_cred_encr_type(struct wps_credential *cred,
-                                     const u8 *encr_type)
-{
-       if (encr_type == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
-                          "Encryption Type");
-               return -1;
-       }
-
-       cred->encr_type = WPA_GET_BE16(encr_type);
-       wpa_printf(MSG_DEBUG, "WPS: Encryption Type: 0x%x",
-                  cred->encr_type);
-
-       return 0;
-}
-
-
-static int wps_process_cred_network_key_idx(struct wps_credential *cred,
-                                           const u8 *key_idx)
-{
-       if (key_idx == NULL)
-               return 0; /* optional attribute */
-
-       wpa_printf(MSG_DEBUG, "WPS: Network Key Index: %d", *key_idx);
-       cred->key_idx = *key_idx;
-
-       return 0;
-}
-
-
-static int wps_process_cred_network_key(struct wps_credential *cred,
-                                       const u8 *key, size_t key_len)
-{
-       if (key == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
-                          "Network Key");
-               return -1;
-       }
-
-       wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key", key, key_len);
-       if (key_len <= sizeof(cred->key)) {
-               os_memcpy(cred->key, key, key_len);
-               cred->key_len = key_len;
-       }
-
-       return 0;
-}
-
-
-static int wps_process_cred_mac_addr(struct wps_credential *cred,
-                                    const u8 *mac_addr)
-{
-       if (mac_addr == NULL) {
-               wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
-                          "MAC Address");
-               return -1;
-       }
-
-       wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR, MAC2STR(mac_addr));
-       os_memcpy(cred->mac_addr, mac_addr, ETH_ALEN);
-
-       return 0;
-}
-
-
-static int wps_process_cred_eap_type(struct wps_credential *cred,
-                                    const u8 *eap_type, size_t eap_type_len)
-{
-       if (eap_type == NULL)
-               return 0; /* optional attribute */
-
-       wpa_hexdump(MSG_DEBUG, "WPS: EAP Type", eap_type, eap_type_len);
-
-       return 0;
-}
-
-
-static int wps_process_cred_eap_identity(struct wps_credential *cred,
-                                        const u8 *identity,
-                                        size_t identity_len)
-{
-       if (identity == NULL)
-               return 0; /* optional attribute */
-
-       wpa_hexdump_ascii(MSG_DEBUG, "WPS: EAP Identity",
-                         identity, identity_len);
-
-       return 0;
-}
-
-
-static int wps_process_cred_key_prov_auto(struct wps_credential *cred,
-                                         const u8 *key_prov_auto)
-{
-       if (key_prov_auto == NULL)
-               return 0; /* optional attribute */
-
-       wpa_printf(MSG_DEBUG, "WPS: Key Provided Automatically: %d",
-                  *key_prov_auto);
-
-       return 0;
-}
-
-
-static int wps_process_cred_802_1x_enabled(struct wps_credential *cred,
-                                          const u8 *dot1x_enabled)
-{
-       if (dot1x_enabled == NULL)
-               return 0; /* optional attribute */
-
-       wpa_printf(MSG_DEBUG, "WPS: 802.1X Enabled: %d", *dot1x_enabled);
-
-       return 0;
-}
-
-
-int wps_process_cred(struct wps_parse_attr *attr,
-                    struct wps_credential *cred)
-{
-       wpa_printf(MSG_DEBUG, "WPS: Process Credential");
-
-       /* TODO: support multiple Network Keys */
-       if (wps_process_cred_network_idx(cred, attr->network_idx) ||
-           wps_process_cred_ssid(cred, attr->ssid, attr->ssid_len) ||
-           wps_process_cred_auth_type(cred, attr->auth_type) ||
-           wps_process_cred_encr_type(cred, attr->encr_type) ||
-           wps_process_cred_network_key_idx(cred, attr->network_key_idx) ||
-           wps_process_cred_network_key(cred, attr->network_key,
-                                        attr->network_key_len) ||
-           wps_process_cred_mac_addr(cred, attr->mac_addr) ||
-           wps_process_cred_eap_type(cred, attr->eap_type,
-                                     attr->eap_type_len) ||
-           wps_process_cred_eap_identity(cred, attr->eap_identity,
-                                         attr->eap_identity_len) ||
-           wps_process_cred_key_prov_auto(cred, attr->key_prov_auto) ||
-           wps_process_cred_802_1x_enabled(cred, attr->dot1x_enabled))
-               return -1;
-
-       return 0;
-}
-
-
-int wps_process_ap_settings(struct wps_parse_attr *attr,
-                           struct wps_credential *cred)
-{
-       wpa_printf(MSG_DEBUG, "WPS: Processing AP Settings");
-       os_memset(cred, 0, sizeof(*cred));
-       /* TODO: optional attributes New Password and Device Password ID */
-       if (wps_process_cred_ssid(cred, attr->ssid, attr->ssid_len) ||
-           wps_process_cred_auth_type(cred, attr->auth_type) ||
-           wps_process_cred_encr_type(cred, attr->encr_type) ||
-           wps_process_cred_network_key_idx(cred, attr->network_key_idx) ||
-           wps_process_cred_network_key(cred, attr->network_key,
-                                        attr->network_key_len) ||
-           wps_process_cred_mac_addr(cred, attr->mac_addr))
-               return -1;
-
-       return 0;
-}
index 2c2c364..693a24f 100644 (file)
@@ -155,25 +155,26 @@ struct wps_parse_attr {
 };
 
 /* wps_common.c */
-int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
 void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
             const char *label, u8 *res, size_t res_len);
-int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg);
-int wps_build_config_methods(struct wpabuf *msg, u16 methods);
-int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid);
-int wps_build_dev_password_id(struct wpabuf *msg, u16 id);
-int wps_build_config_error(struct wpabuf *msg, u16 err);
 int wps_derive_keys(struct wps_data *wps);
 int wps_derive_mgmt_keys(struct wps_data *wps);
-int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg);
-int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
-                             const struct wpabuf *msg);
 void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
                    size_t dev_passwd_len);
 struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
                                          size_t encr_len);
-int wps_process_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg,
-                             const u8 *key_wrap_auth);
+
+/* wps_attr_parse.c */
+int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
+
+/* wps_attr_build.c */
+int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg);
+int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type);
+int wps_build_config_methods(struct wpabuf *msg, u16 methods);
+int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid);
+int wps_build_dev_password_id(struct wpabuf *msg, u16 id);
+int wps_build_config_error(struct wpabuf *msg, u16 err);
+int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg);
 int wps_build_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg);
 int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg,
                            struct wpabuf *plain);
@@ -185,6 +186,12 @@ int wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg);
 int wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg);
 int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg);
 int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg);
+
+/* wps_attr_process.c */
+int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
+                             const struct wpabuf *msg);
+int wps_process_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg,
+                             const u8 *key_wrap_auth);
 int wps_process_cred(struct wps_parse_attr *attr,
                     struct wps_credential *cred);
 int wps_process_ap_settings(struct wps_parse_attr *attr,
index d6a5b87..eb17ee1 100644 (file)
@@ -505,6 +505,9 @@ OBJS += ../src/utils/uuid.o
 OBJS += ../src/eap_peer/eap_wsc.o ../src/eap_common/eap_wsc_common.o
 OBJS += ../src/wps/wps.o
 OBJS += ../src/wps/wps_common.o
+OBJS += ../src/wps/wps_attr_parse.o
+OBJS += ../src/wps/wps_attr_build.o
+OBJS += ../src/wps/wps_attr_process.o
 OBJS += ../src/wps/wps_dev_attr.o
 OBJS += ../src/wps/wps_enrollee.o
 OBJS += ../src/wps/wps_registrar.o