📄 wps_enrollee.c
字号:
wps_pwd_auth_fail_event(wps->wps, 1, 1); return -1; } wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the first " "half of the device password"); return 0;}static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2){ u8 hash[SHA256_MAC_LEN]; const u8 *addr[4]; size_t len[4]; if (r_snonce2 == NULL) { wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received"); return -1; } wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2, WPS_SECRET_NONCE_LEN); /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */ addr[0] = r_snonce2; len[0] = WPS_SECRET_NONCE_LEN; addr[1] = wps->psk2; len[1] = WPS_PSK_LEN; addr[2] = wpabuf_head(wps->dh_pubkey_e); len[2] = wpabuf_len(wps->dh_pubkey_e); addr[3] = wpabuf_head(wps->dh_pubkey_r); len[3] = wpabuf_len(wps->dh_pubkey_r); hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) { wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does " "not match with the pre-committed value"); wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE; wps_pwd_auth_fail_event(wps->wps, 1, 2); return -1; } wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second " "half of the device password"); return 0;}static int wps_process_cred_e(struct wps_data *wps, const u8 *cred, size_t cred_len){ struct wps_parse_attr attr; struct wpabuf msg; wpa_printf(MSG_DEBUG, "WPS: Received Credential"); os_memset(&wps->cred, 0, sizeof(wps->cred)); wpabuf_set(&msg, cred, cred_len); if (wps_parse_msg(&msg, &attr) < 0 || wps_process_cred(&attr, &wps->cred)) return -1; if (wps->wps->cred_cb) { wps->cred.cred_attr = cred - 4; wps->cred.cred_attr_len = cred_len + 4; wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred); wps->cred.cred_attr = NULL; wps->cred.cred_attr_len = 0; } return 0;}static int wps_process_creds(struct wps_data *wps, const u8 *cred[], size_t cred_len[], size_t num_cred){ size_t i; if (wps->wps->ap) return 0; if (num_cred == 0) { wpa_printf(MSG_DEBUG, "WPS: No Credential attributes " "received"); return -1; } for (i = 0; i < num_cred; i++) { if (wps_process_cred_e(wps, cred[i], cred_len[i])) return -1; } return 0;}static int wps_process_ap_settings_e(struct wps_data *wps, struct wps_parse_attr *attr, struct wpabuf *attrs){ struct wps_credential cred; if (!wps->wps->ap) return 0; if (wps_process_ap_settings(attr, &cred) < 0) return -1; wpa_printf(MSG_INFO, "WPS: Received new AP configuration from " "Registrar"); if (wps->wps->cred_cb) { cred.cred_attr = wpabuf_head(attrs); cred.cred_attr_len = wpabuf_len(attrs); wps->wps->cred_cb(wps->wps->cb_ctx, &cred); } return 0;}static enum wps_process_res wps_process_m2(struct wps_data *wps, const struct wpabuf *msg, struct wps_parse_attr *attr){ wpa_printf(MSG_DEBUG, "WPS: Received M2"); if (wps->state != RECV_M2) { wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " "receiving M2", wps->state); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } if (wps_process_registrar_nonce(wps, attr->registrar_nonce) || 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->state = SEND_WSC_NACK; return WPS_CONTINUE; } if (wps->wps->ap && wps->wps->ap_setup_locked) { wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse " "registration of a new Registrar"); wps->config_error = WPS_CFG_SETUP_LOCKED; wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } wps->state = SEND_M3; return WPS_CONTINUE;}static enum wps_process_res wps_process_m2d(struct wps_data *wps, struct wps_parse_attr *attr){ wpa_printf(MSG_DEBUG, "WPS: Received M2D"); if (wps->state != RECV_M2) { wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " "receiving M2D", wps->state); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer", attr->manufacturer, attr->manufacturer_len); wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name", attr->model_name, attr->model_name_len); wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number", attr->model_number, attr->model_number_len); wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", attr->serial_number, attr->serial_number_len); wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name", attr->dev_name, attr->dev_name_len); if (wps->wps->event_cb) { union wps_event_data data; struct wps_event_m2d *m2d = &data.m2d; os_memset(&data, 0, sizeof(data)); if (attr->config_methods) m2d->config_methods = WPA_GET_BE16(attr->config_methods); m2d->manufacturer = attr->manufacturer; m2d->manufacturer_len = attr->manufacturer_len; m2d->model_name = attr->model_name; m2d->model_name_len = attr->model_name_len; m2d->model_number = attr->model_number; m2d->model_number_len = attr->model_number_len; m2d->serial_number = attr->serial_number; m2d->serial_number_len = attr->serial_number_len; m2d->dev_name = attr->dev_name; m2d->dev_name_len = attr->dev_name_len; m2d->primary_dev_type = attr->primary_dev_type; if (attr->config_error) m2d->config_error = WPA_GET_BE16(attr->config_error); if (attr->dev_password_id) m2d->dev_password_id = WPA_GET_BE16(attr->dev_password_id); wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_M2D, &data); } wps->state = RECEIVED_M2D; return WPS_CONTINUE;}static enum wps_process_res wps_process_m4(struct wps_data *wps, const struct wpabuf *msg, struct wps_parse_attr *attr){ struct wpabuf *decrypted; struct wps_parse_attr eattr; wpa_printf(MSG_DEBUG, "WPS: Received M4"); if (wps->state != RECV_M4) { wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " "receiving M4", wps->state); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) || wps_process_authenticator(wps, attr->authenticator, msg) || wps_process_r_hash1(wps, attr->r_hash1) || wps_process_r_hash2(wps, attr->r_hash2)) { wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings, attr->encr_settings_len); if (decrypted == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted " "Settings attribute"); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings " "attribute"); if (wps_parse_msg(decrypted, &eattr) < 0 || wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) || wps_process_r_snonce1(wps, eattr.r_snonce1)) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } wpabuf_free(decrypted); wps->state = SEND_M5; return WPS_CONTINUE;}static enum wps_process_res wps_process_m6(struct wps_data *wps, const struct wpabuf *msg, struct wps_parse_attr *attr){ struct wpabuf *decrypted; struct wps_parse_attr eattr; wpa_printf(MSG_DEBUG, "WPS: Received M6"); if (wps->state != RECV_M6) { wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " "receiving M6", wps->state); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) || wps_process_authenticator(wps, attr->authenticator, msg)) { wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings, attr->encr_settings_len); if (decrypted == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted " "Settings attribute"); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings " "attribute"); if (wps_parse_msg(decrypted, &eattr) < 0 || wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) || wps_process_r_snonce2(wps, eattr.r_snonce2)) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } wpabuf_free(decrypted); wps->state = SEND_M7; return WPS_CONTINUE;}static enum wps_process_res wps_process_m8(struct wps_data *wps, const struct wpabuf *msg, struct wps_parse_attr *attr){ struct wpabuf *decrypted; struct wps_parse_attr eattr; wpa_printf(MSG_DEBUG, "WPS: Received M8"); if (wps->state != RECV_M8) { wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " "receiving M8", wps->state); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) || wps_process_authenticator(wps, attr->authenticator, msg)) { wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings, attr->encr_settings_len); if (decrypted == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted " "Settings attribute"); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings " "attribute"); if (wps_parse_msg(decrypted, &eattr) < 0 || wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) || wps_process_creds(wps, eattr.cred, eattr.cred_len, eattr.num_cred) || wps_process_ap_settings_e(wps, &eattr, decrypted)) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; } wpabuf_free(decrypted); wps->state = WPS_MSG_DONE; return WPS_CONTINUE;}static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps, const struct wpabuf *msg){ struct wps_parse_attr attr; enum wps_process_res ret = WPS_CONTINUE; wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG"); if (wps_parse_msg(msg, &attr) < 0) return WPS_FAILURE; 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 (attr.enrollee_nonce == NULL || os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) { wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce"); return WPS_FAILURE; } if (attr.msg_type == NULL) { wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute"); return WPS_FAILURE; } switch (*attr.msg_type) { case WPS_M2: ret = wps_process_m2(wps, msg, &attr); break; case WPS_M2D: ret = wps_process_m2d(wps, &attr); break; case WPS_M4: ret = wps_process_m4(wps, msg, &attr); if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) wps_fail_event(wps->wps, WPS_M4); break; case WPS_M6: ret = wps_process_m6(wps, msg, &attr); if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) wps_fail_event(wps->wps, WPS_M6); break; case WPS_M8: ret = wps_process_m8(wps, msg, &attr); if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) wps_fail_event(wps->wps, WPS_M8); break; default: wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d", *attr.msg_type); return WPS_FAILURE; } /* * Save a copy of the last message for Authenticator derivation if we * are continuing. However, skip M2D since it is not authenticated and * neither is the ACK/NACK response frame. This allows the possibly * following M2 to be processed correctly by using the previously sent * M1 in Authenticator derivation. */ if (ret == WPS_CONTINUE && *attr.msg_type != WPS_M2D) { /* Save a copy of the last message for Authenticator derivation */ wpabuf_free(wps->last_msg); wps->last_msg = wpabuf_dup(msg); } return ret;}static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps, const struct wpabuf *msg){ struct wps_parse_attr attr; wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK"); if (wps_parse_msg(msg, &attr) < 0) return WPS_FAILURE; 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 (attr.msg_type == NULL) { wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute"); return WPS_FAILURE; } if (*attr.msg_type != WPS_WSC_ACK) { wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d", *attr.msg_type); return WPS_FAILURE; } if (attr.registrar_nonce == NULL || os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0)) { wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce"); return WPS_FAILURE; } if (attr.enrollee_nonce == NULL || os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) { wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce"); return WPS_FAILURE; } if (wps->state == RECV_ACK && wps->wps->ap) { wpa_printf(MSG_DEBUG, "WPS: External Registrar registration " "completed successfully"); wps_success_event(wps->wps); wps->state = WPS_FINISHED; return WPS_DONE; } return WPS_FAILURE;}static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps, const struct wpabuf *msg){ struct wps_parse_attr attr; wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK"); if (wps_parse_msg(msg, &attr) < 0) return WPS_FAILURE; 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 (attr.msg_type == NULL) { wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute"); return WPS_FAILURE; } if (*attr.msg_type != WPS_WSC_NACK) { wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d", *attr.msg_type); return WPS_FAILURE; } if (attr.registrar_nonce == NULL || os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0)) { wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce"); wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce", attr.registrar_nonce, WPS_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce", wps->nonce_r, WPS_NONCE_LEN); return WPS_FAILURE; } if (attr.enrollee_nonce == NULL || os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) { wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce"); wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce", attr.enrollee_nonce, WPS_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce", wps->nonce_e, WPS_NONCE_LEN); return WPS_FAILURE; } if (attr.config_error == NULL) { wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute " "in WSC_NACK"); return WPS_FAILURE; } wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with " "Configuration Error %d", WPA_GET_BE16(attr.config_error)); switch (wps->state) { case RECV_M4: wps_fail_event(wps->wps, WPS_M3); break; case RECV_M6: wps_fail_event(wps->wps, WPS_M5); break; case RECV_M8: wps_fail_event(wps->wps, WPS_M7); break; default: break; } /* Followed by NACK if Enrollee is Supplicant or EAP-Failure if * Enrollee is Authenticator */ wps->state = SEND_WSC_NACK; return WPS_FAILURE;}enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps, enum wsc_op_code op_code, const struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu " "op_code=%d)", (unsigned long) wpabuf_len(msg), op_code); switch (op_code) { case WSC_MSG: case WSC_UPnP: return wps_process_wsc_msg(wps, msg); case WSC_ACK: return wps_process_wsc_ack(wps, msg); case WSC_NACK: return wps_process_wsc_nack(wps, msg); default: wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code); return WPS_FAILURE; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -