#include "includes.h"
#include "common.h"
-#include "sha256.h"
+#include "crypto/crypto.h"
+#include "crypto/sha256.h"
#include "wps_i.h"
#include "wps_dev_attr.h"
state);
wpabuf_put_be16(msg, ATTR_WPS_STATE);
wpabuf_put_be16(msg, 1);
- wpabuf_put_u8(msg, WPS_STATE_NOT_CONFIGURED);
+ wpabuf_put_u8(msg, state);
return 0;
}
return NULL;
methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
+#ifdef CONFIG_WPS_UFD
+ methods |= WPS_CONFIG_USBA;
+#endif /* CONFIG_WPS_UFD */
+#ifdef CONFIG_WPS_NFC
+ methods |= WPS_CONFIG_NFC_INTERFACE;
+#endif /* CONFIG_WPS_NFC */
if (wps->pbc)
methods |= WPS_CONFIG_PUSHBUTTON;
}
wpabuf_free(plain);
+ if (wps->wps->ap && wps->wps->registrar) {
+ /*
+ * If the Registrar is only learning our current configuration,
+ * it may not continue protocol run to successful completion.
+ * Store information here to make sure it remains available.
+ */
+ wps_device_store(wps->wps->registrar, &wps->peer_dev,
+ wps->uuid_r);
+ }
+
wps->state = RECV_M8;
return msg;
}
return -1;
}
+#ifdef CONFIG_WPS_OOB
+ if (wps->dev_pw_id != DEV_PW_DEFAULT &&
+ wps->wps->oob_conf.pubkey_hash) {
+ const u8 *addr[1];
+ u8 hash[WPS_HASH_LEN];
+
+ addr[0] = pk;
+ sha256_vector(1, addr, &pk_len, hash);
+ if (os_memcmp(hash,
+ wpabuf_head(wps->wps->oob_conf.pubkey_hash),
+ WPS_OOB_PUBKEY_HASH_LEN) != 0) {
+ wpa_printf(MSG_ERROR, "WPS: Public Key hash error");
+ return -1;
+ }
+ }
+#endif /* CONFIG_WPS_OOB */
+
wpabuf_free(wps->dh_pubkey_r);
wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);
if (wps->dh_pubkey_r == NULL)
if (wps_derive_keys(wps) < 0)
return -1;
- if (wps->request_type == WPS_REQ_WLAN_MANAGER_REGISTRAR &&
- wps_derive_mgmt_keys(wps) < 0)
- return -1;
-
return 0;
}
wps_process_cred(&attr, &wps->cred))
return -1;
+ if (os_memcmp(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
+ 0) {
+ wpa_printf(MSG_DEBUG, "WPS: MAC Address in the Credential ("
+ MACSTR ") does not match with own address (" MACSTR
+ ")", MAC2STR(wps->cred.mac_addr),
+ MAC2STR(wps->wps->dev.mac_addr));
+ /*
+ * In theory, this could be consider fatal error, but there are
+ * number of deployed implementations using other address here
+ * due to unclarity in the specification. For interoperability
+ * reasons, allow this to be processed since we do not really
+ * use the MAC Address information for anything.
+ */
+ }
+
if (wps->wps->cred_cb) {
wps->cred.cred_attr = cred - 4;
wps->cred.cred_attr_len = cred_len + 4;
wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
"Registrar");
+ if (os_memcmp(cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
+ 0) {
+ wpa_printf(MSG_DEBUG, "WPS: MAC Address in the AP Settings ("
+ MACSTR ") does not match with own address (" MACSTR
+ ")", MAC2STR(cred.mac_addr),
+ MAC2STR(wps->wps->dev.mac_addr));
+ /*
+ * In theory, this could be consider fatal error, but there are
+ * number of deployed implementations using other address here
+ * due to unclarity in the specification. For interoperability
+ * reasons, allow this to be processed since we do not really
+ * use the MAC Address information for anything.
+ */
+ }
+
if (wps->wps->cred_cb) {
cred.cred_attr = wpabuf_head(attrs);
cred.cred_attr_len = wpabuf_len(attrs);
wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
wps_process_uuid_r(wps, attr->uuid_r) ||
wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
- wps_process_authenticator(wps, attr->authenticator, msg)) {
+ wps_process_authenticator(wps, attr->authenticator, msg) ||
+ wps_process_device_attrs(&wps->peer_dev, attr)) {
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
if (wps_parse_msg(msg, &attr) < 0)
return WPS_FAILURE;
- if (attr.version == NULL || *attr.version != WPS_VERSION) {
+ if (!wps_version_supported(attr.version)) {
wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
attr.version ? *attr.version : 0);
return WPS_FAILURE;
if (wps_parse_msg(msg, &attr) < 0)
return WPS_FAILURE;
- if (attr.version == NULL || *attr.version != WPS_VERSION) {
+ if (!wps_version_supported(attr.version)) {
wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
attr.version ? *attr.version : 0);
return WPS_FAILURE;
if (wps_parse_msg(msg, &attr) < 0)
return WPS_FAILURE;
- if (attr.version == NULL || *attr.version != WPS_VERSION) {
+ if (!wps_version_supported(attr.version)) {
wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
attr.version ? *attr.version : 0);
return WPS_FAILURE;
"op_code=%d)",
(unsigned long) wpabuf_len(msg), op_code);
+ if (op_code == WSC_UPnP) {
+ /* Determine the OpCode based on message type attribute */
+ struct wps_parse_attr attr;
+ if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
+ if (*attr.msg_type == WPS_WSC_ACK)
+ op_code = WSC_ACK;
+ else if (*attr.msg_type == WPS_WSC_NACK)
+ op_code = WSC_NACK;
+ }
+ }
+
switch (op_code) {
case WSC_MSG:
case WSC_UPnP: