📄 eap_gpsk.c
字号:
rpos += 2; if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor, data->specifier, start, rpos - start, rpos) < 0) { eap_gpsk_state(data, FAILURE); os_free(resp); return NULL; } return (u8 *) resp;}const u8 * eap_gpsk_validate_rand(struct eap_gpsk_data *data, const u8 *pos, const u8 *end){ if (end - pos < EAP_GPSK_RAND_LEN) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " "RAND_Peer"); return NULL; } if (os_memcmp(pos, data->rand_peer, EAP_GPSK_RAND_LEN) != 0) { wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Peer in GPSK-2 and " "GPSK-3 did not match"); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer in GPSK-2", data->rand_peer, EAP_GPSK_RAND_LEN); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer in GPSK-3", pos, EAP_GPSK_RAND_LEN); return NULL; } pos += EAP_GPSK_RAND_LEN; if (end - pos < EAP_GPSK_RAND_LEN) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " "RAND_Server"); return NULL; } if (os_memcmp(pos, data->rand_server, EAP_GPSK_RAND_LEN) != 0) { wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1 and " "GPSK-3 did not match"); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1", data->rand_server, EAP_GPSK_RAND_LEN); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-3", pos, EAP_GPSK_RAND_LEN); return NULL; } pos += EAP_GPSK_RAND_LEN; return pos;}const u8 * eap_gpsk_validate_id_server(struct eap_gpsk_data *data, const u8 *pos, const u8 *end){ size_t len; if (pos == NULL) return NULL; if (end - pos < (int) 2) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " "length(ID_Server)"); return NULL; } len = WPA_GET_BE16(pos); pos += 2; if (end - pos < (int) len) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " "ID_Server"); return NULL; } if (len != data->id_server_len || os_memcmp(pos, data->id_server, len) != 0) { wpa_printf(MSG_INFO, "EAP-GPSK: ID_Server did not match with " "the one used in GPSK-1"); wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-1", data->id_server, data->id_server_len); wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-3", pos, len); } pos += len; return pos;}const u8 * eap_gpsk_validate_csuite(struct eap_gpsk_data *data, const u8 *pos, const u8 *end){ int vendor, specifier; const struct eap_gpsk_csuite *csuite; if (pos == NULL) return NULL; if (end - pos < (int) sizeof(*csuite)) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " "CSuite_Sel"); return NULL; } csuite = (const struct eap_gpsk_csuite *) pos; vendor = WPA_GET_BE32(csuite->vendor); specifier = WPA_GET_BE16(csuite->specifier); pos += sizeof(*csuite); if (vendor != data->vendor || specifier != data->specifier) { wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_Sel (%d:%d) does not " "match with the one sent in GPSK-2 (%d:%d)", vendor, specifier, data->vendor, data->specifier); return NULL; } return pos;}const u8 * eap_gpsk_validate_pd_payload_2(struct eap_gpsk_data *data, const u8 *pos, const u8 *end){ u16 alen; if (pos == NULL) return NULL; if (end - pos < 2) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " "PD_Payload_2 length"); return NULL; } alen = WPA_GET_BE16(pos); pos += 2; if (end - pos < alen) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for " "%d-octet PD_Payload_2", alen); return NULL; } wpa_hexdump(MSG_DEBUG, "EAP-GPSK: PD_Payload_2", pos, alen); pos += alen; return pos;}const u8 * eap_gpsk_validate_gpsk_3_mic(struct eap_gpsk_data *data, const u8 *payload, const u8 *pos, const u8 *end){ size_t miclen; u8 mic[EAP_GPSK_MAX_MIC_LEN]; if (pos == NULL) return NULL; miclen = eap_gpsk_mic_len(data->vendor, data->specifier); if (end - pos < (int) miclen) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC " "(left=%d miclen=%d)", end - pos, miclen); return NULL; } if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor, data->specifier, payload, pos - payload, mic) < 0) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to compute MIC"); return NULL; } if (os_memcmp(mic, pos, miclen) != 0) { wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-3"); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen); return NULL; } pos += miclen; return pos;}static u8 * eap_gpsk_process_gpsk_3(struct eap_sm *sm, struct eap_gpsk_data *data, struct eap_method_ret *ret, const u8 *reqData, size_t reqDataLen, const u8 *payload, size_t payload_len, size_t *respDataLen){ u8 *resp; const struct eap_hdr *req; const u8 *pos, *end; if (data->state != GPSK_3) { ret->ignore = TRUE; return NULL; } wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Request/GPSK-3"); end = payload + payload_len; pos = eap_gpsk_validate_rand(data, payload, end); pos = eap_gpsk_validate_id_server(data, pos, end); pos = eap_gpsk_validate_csuite(data, pos, end); pos = eap_gpsk_validate_pd_payload_2(data, pos, end); pos = eap_gpsk_validate_gpsk_3_mic(data, payload, pos, end); if (pos == NULL) { eap_gpsk_state(data, FAILURE); return NULL; } if (pos != end) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %d bytes of extra " "data in the end of GPSK-2", end - pos); } req = (const struct eap_hdr *) reqData; resp = eap_gpsk_send_gpsk_4(data, req->identifier, respDataLen); if (resp == NULL) return NULL; eap_gpsk_state(data, SUCCESS); ret->methodState = METHOD_DONE; ret->decision = DECISION_UNCOND_SUCC; return (u8 *) resp;}static u8 * eap_gpsk_send_gpsk_4(struct eap_gpsk_data *data, u8 identifier, size_t *respDataLen){ struct eap_hdr *resp; u8 *rpos, *start; size_t len; wpa_printf(MSG_DEBUG, "EAP-GPSK: Sending Response/GPSK-4"); len = 1 + 2 + eap_gpsk_mic_len(data->vendor, data->specifier); resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respDataLen, len, EAP_CODE_RESPONSE, identifier, &rpos); if (resp == NULL) return NULL; *rpos++ = EAP_GPSK_OPCODE_GPSK_4; start = rpos; /* No PD_Payload_3 */ WPA_PUT_BE16(rpos, 0); rpos += 2; if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor, data->specifier, start, rpos - start, rpos) < 0) { eap_gpsk_state(data, FAILURE); os_free(resp); return NULL; } return (u8 *) resp;}static u8 * eap_gpsk_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, const u8 *reqData, size_t reqDataLen, size_t *respDataLen){ struct eap_gpsk_data *data = priv; u8 *resp; const u8 *pos; size_t len; pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, reqData, reqDataLen, &len); if (pos == NULL || len < 1) { ret->ignore = TRUE; return NULL; } wpa_printf(MSG_DEBUG, "EAP-GPSK: Received frame: opcode %d", *pos); ret->ignore = FALSE; ret->methodState = METHOD_MAY_CONT; ret->decision = DECISION_FAIL; ret->allowNotifications = FALSE; switch (*pos) { case EAP_GPSK_OPCODE_GPSK_1: resp = eap_gpsk_process_gpsk_1(sm, data, ret, reqData, reqDataLen, pos + 1, len - 1, respDataLen); break; case EAP_GPSK_OPCODE_GPSK_3: resp = eap_gpsk_process_gpsk_3(sm, data, ret, reqData, reqDataLen, pos + 1, len - 1, respDataLen); break; default: wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignoring message with " "unknown opcode %d", *pos); ret->ignore = TRUE; return NULL; } return resp;}static Boolean eap_gpsk_isKeyAvailable(struct eap_sm *sm, void *priv){ struct eap_gpsk_data *data = priv; return data->state == SUCCESS;}static u8 * eap_gpsk_getKey(struct eap_sm *sm, void *priv, size_t *len){ struct eap_gpsk_data *data = priv; u8 *key; if (data->state != SUCCESS) return NULL; key = os_malloc(EAP_MSK_LEN); if (key == NULL) return NULL; os_memcpy(key, data->msk, EAP_MSK_LEN); *len = EAP_MSK_LEN; return key;}static u8 * eap_gpsk_get_emsk(struct eap_sm *sm, void *priv, size_t *len){ struct eap_gpsk_data *data = priv; u8 *key; if (data->state != SUCCESS) return NULL; key = os_malloc(EAP_EMSK_LEN); if (key == NULL) return NULL; os_memcpy(key, data->emsk, EAP_EMSK_LEN); *len = EAP_EMSK_LEN; return key;}int eap_peer_gpsk_register(void){ struct eap_method *eap; int ret; eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, EAP_VENDOR_IETF, EAP_TYPE_GPSK, "GPSK"); if (eap == NULL) return -1; eap->init = eap_gpsk_init; eap->deinit = eap_gpsk_deinit; eap->process = eap_gpsk_process; eap->isKeyAvailable = eap_gpsk_isKeyAvailable; eap->getKey = eap_gpsk_getKey; eap->get_emsk = eap_gpsk_get_emsk; ret = eap_peer_method_register(eap); if (ret) eap_peer_method_free(eap); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -