Lines Matching +full:entry +full:- +full:method

2  * EAP peer method: EAP-TEAP (RFC 7170)
3 * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
85 wpa_printf(MSG_DEBUG, "EAP-TEAP: SessionTicket callback");
89 "EAP-TEAP: SessionTicket failed - fall back to full TLS handshake");
90 data->session_ticket_used = 0;
91 if (data->provisioning_allowed) {
93 "EAP-TEAP: Try to provision a new PAC-Key");
94 data->provisioning = 1;
95 data->current_pac = NULL;
100 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: SessionTicket", ticket, len);
102 if (!data->current_pac) {
104 "EAP-TEAP: No PAC-Key available for using SessionTicket");
105 data->session_ticket_used = 0;
109 /* EAP-TEAP uses PAC-Key as the TLS master_secret */
110 os_memcpy(master_secret, data->current_pac->pac_key,
113 data->session_ticket_used = 1;
126 data->provisioning_allowed = atoi(pos + 18);
128 "EAP-TEAP: Automatic PAC provisioning mode: %d",
129 data->provisioning_allowed);
134 data->max_pac_list_len = atoi(pos + 22);
135 if (data->max_pac_list_len == 0)
136 data->max_pac_list_len = 1;
137 wpa_printf(MSG_DEBUG, "EAP-TEAP: Maximum PAC list length: %lu",
138 (unsigned long) data->max_pac_list_len);
142 data->use_pac_binary_format = 1;
144 "EAP-TEAP: Using binary format for PAC list");
149 data->test_outer_tlvs = 1;
165 data->teap_version = EAP_TEAP_VERSION;
166 data->max_pac_list_len = 10;
168 if (config->phase1)
169 eap_teap_parse_phase1(data, config->phase1);
171 if ((data->provisioning_allowed & EAP_TEAP_PROV_AUTH) &&
172 !config->cert.ca_cert && !config->cert.ca_path) {
175 * inner EAP method). */
177 "EAP-TEAP: Disable authenticated provisioning due to no ca_cert/ca_path");
178 data->provisioning_allowed &= ~EAP_TEAP_PROV_AUTH;
182 &data->phase2_types,
183 &data->num_phase2_types, 0) < 0) {
188 data->phase2_type.vendor = EAP_VENDOR_IETF;
189 data->phase2_type.method = EAP_TYPE_NONE;
191 config->teap_anon_dh = !!(data->provisioning_allowed &
193 if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TEAP)) {
194 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to initialize SSL");
199 if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn,
203 "EAP-TEAP: Failed to set SessionTicket callback");
208 if (!config->pac_file) {
209 wpa_printf(MSG_INFO, "EAP-TEAP: No PAC file configured");
214 if (data->use_pac_binary_format &&
215 eap_teap_load_pac_bin(sm, &data->pac, config->pac_file) < 0) {
216 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to load PAC file");
221 if (!data->use_pac_binary_format &&
222 eap_teap_load_pac(sm, &data->pac, config->pac_file) < 0) {
223 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to load PAC file");
227 eap_teap_pac_list_truncate(data->pac, data->max_pac_list_len);
235 forced_memzero(data->key_data, EAP_TEAP_KEY_LEN);
236 forced_memzero(data->emsk, EAP_EMSK_LEN);
237 os_free(data->session_id);
238 data->session_id = NULL;
239 wpabuf_free(data->pending_phase2_req);
240 data->pending_phase2_req = NULL;
241 wpabuf_free(data->pending_resp);
242 data->pending_resp = NULL;
243 wpabuf_free(data->server_outer_tlvs);
244 data->server_outer_tlvs = NULL;
245 wpabuf_free(data->peer_outer_tlvs);
246 data->peer_outer_tlvs = NULL;
247 forced_memzero(data->simck_msk, EAP_TEAP_SIMCK_LEN);
248 forced_memzero(data->simck_emsk, EAP_TEAP_SIMCK_LEN);
259 if (data->phase2_priv && data->phase2_method)
260 data->phase2_method->deinit(sm, data->phase2_priv);
262 os_free(data->phase2_types);
263 eap_peer_tls_ssl_deinit(sm, &data->ssl);
265 pac = data->pac;
269 pac = pac->next;
279 /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j]
281 if (eap_teap_derive_eap_msk(data->tls_cs, data->simck_msk,
282 data->key_data) < 0 ||
283 eap_teap_derive_eap_emsk(data->tls_cs, data->simck_msk,
284 data->emsk) < 0)
285 return -1;
286 data->success = 1;
297 res = tls_connection_export_key(sm->ssl_ctx, data->ssl.conn,
299 data->simck_msk, EAP_TEAP_SIMCK_LEN);
303 "EAP-TEAP: session_key_seed (S-IMCK[0])",
304 data->simck_msk, EAP_TEAP_SIMCK_LEN);
305 os_memcpy(data->simck_emsk, data->simck_msk, EAP_TEAP_SIMCK_LEN);
306 data->simck_idx = 0;
314 data->inner_method_done = 0;
315 data->iresult_verified = 0;
316 data->phase2_method =
317 eap_peer_get_eap_method(data->phase2_type.vendor,
318 data->phase2_type.method);
319 if (!data->phase2_method)
320 return -1;
322 /* While RFC 7170 does not describe this, EAP-TEAP has been deployed
323 * with implementations that use the EAP-FAST-MSCHAPv2, instead of the
324 * EAP-MSCHAPv2, way of deriving the MSK for IMSK. Use that design here
327 sm->eap_fast_mschapv2 = true;
329 sm->init_phase2 = 1;
330 data->phase2_priv = data->phase2_method->init(sm);
331 sm->init_phase2 = 0;
333 return data->phase2_priv == NULL ? -1 : 0;
343 * completed inner EAP authentication (EAP-pwd or EAP-EKE) and TNC */
345 if (data->anon_provisioning &&
348 "EAP-TEAP: EAP type %u:%u not allowed during unauthenticated provisioning",
350 return -1;
355 data->phase2_type.vendor = EAP_VENDOR_IETF;
356 data->phase2_type.method = EAP_TYPE_TNC;
358 "EAP-TEAP: Selected Phase 2 EAP vendor %d method %d for TNC",
359 data->phase2_type.vendor,
360 data->phase2_type.method);
365 for (i = 0; i < data->num_phase2_types; i++) {
366 if (data->phase2_types[i].vendor != vendor ||
367 data->phase2_types[i].method != type)
370 data->phase2_type.vendor = data->phase2_types[i].vendor;
371 data->phase2_type.method = data->phase2_types[i].method;
373 "EAP-TEAP: Selected Phase 2 EAP vendor %d method %d",
374 data->phase2_type.vendor,
375 data->phase2_type.method);
379 if (vendor != data->phase2_type.vendor ||
380 type != data->phase2_type.method ||
382 return -1;
391 if (!data->phase2_priv || !data->phase2_method)
395 "EAP-TEAP: Phase 2 EAP sequence - deinitialize previous method");
396 data->phase2_method->deinit(sm, data->phase2_priv);
397 data->phase2_method = NULL;
398 data->phase2_priv = NULL;
399 data->phase2_type.vendor = EAP_VENDOR_IETF;
400 data->phase2_type.method = EAP_TYPE_NONE;
410 size_t len = be_to_host16(hdr->length);
416 enum eap_type method;
420 "EAP-TEAP: too short Phase 2 request (len=%lu)",
422 return -1;
425 method = *pos;
426 if (method == EAP_TYPE_EXPANDED) {
429 "EAP-TEAP: Too short Phase 2 request (expanded header) (len=%lu)",
431 return -1;
434 method = WPA_GET_BE32(pos + 4);
436 wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 Request: type=%u:%u",
437 vendor, method);
438 if (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_IDENTITY) {
440 *resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
444 if (data->phase2_priv && data->phase2_method &&
445 (vendor != data->phase2_type.vendor ||
446 method != data->phase2_type.method))
449 if (data->phase2_type.vendor == EAP_VENDOR_IETF &&
450 data->phase2_type.method == EAP_TYPE_NONE &&
451 eap_teap_select_phase2_method(data, vendor, method) < 0) {
452 if (eap_peer_tls_phase2_nak(data->phase2_types,
453 data->num_phase2_types,
455 return -1;
459 if ((!data->phase2_priv && eap_teap_init_phase2_method(sm, data) < 0) ||
460 !data->phase2_method) {
462 "EAP-TEAP: Failed to initialize Phase 2 EAP method %u:%u",
463 vendor, method);
464 ret->methodState = METHOD_DONE;
465 ret->decision = DECISION_FAIL;
466 return -1;
471 *resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
474 data->inner_method_done = 1;
479 ret->methodState = METHOD_MAY_CONT;
480 ret->decision = DECISION_FAIL;
485 data->phase2_success = 1;
489 (config->pending_req_identity || config->pending_req_password ||
490 config->pending_req_otp || config->pending_req_new_password ||
491 config->pending_req_sim)) {
492 wpabuf_free(data->pending_phase2_req);
493 data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
495 return -1;
507 "EAP-TEAP: Add NAK TLV (Vendor-Id %u NAK-Type %u)",
513 nak->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | TEAP_TLV_NAK);
514 nak->length = host_to_be16(6);
515 nak->vendor_id = host_to_be32(vendor_id);
516 nak->nak_type = host_to_be16(tlv_type);
531 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV (ack)");
533 ack->tlv_type = host_to_be16(TEAP_TLV_PAC | TEAP_TLV_MANDATORY);
534 ack->length = host_to_be16(sizeof(*ack) - sizeof(struct teap_tlv_hdr));
535 ack->pac_type = host_to_be16(PAC_TYPE_PAC_ACKNOWLEDGEMENT);
536 ack->pac_len = host_to_be16(2);
537 ack->result = host_to_be16(TEAP_STATUS_SUCCESS);
548 tlv = eap_teap_tlv_identity_type(sm->use_machine_cred ?
566 "EAP-TEAP: too short EAP Payload TLV (len=%lu)",
572 if (be_to_host16(hdr->length) > eap_payload_tlv_len) {
574 "EAP-TEAP: EAP packet overflow in EAP Payload TLV");
578 if (hdr->code != EAP_CODE_REQUEST) {
580 "EAP-TEAP: Unexpected code=%d in Phase 2 EAP header",
581 hdr->code);
587 "EAP-TEAP: Phase 2 Request processing failed");
608 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: Basic-Password-Auth-Req prompt",
617 "EAP-TEAP: No username/password suitable for Basic-Password-Auth");
630 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Basic-Password-Auth-Resp",
637 data->phase2_success = 1;
649 subtype = cb->subtype & 0x0f;
650 flags = cb->subtype >> 4;
653 "EAP-TEAP: Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
654 cb->version, cb->received_version, flags, subtype);
655 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
656 cb->nonce, sizeof(cb->nonce));
657 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
658 cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac));
659 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
660 cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
662 if (cb->version != EAP_TEAP_VERSION ||
663 cb->received_version != data->received_version ||
667 "EAP-TEAP: Invalid Version/Flags/Sub-Type in Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
668 cb->version, cb->received_version, flags, subtype);
669 return -1;
672 if (cb->nonce[EAP_TEAP_NONCE_LEN - 1] & 0x01) {
674 "EAP-TEAP: Invalid Crypto-Binding TLV Nonce in request");
675 return -1;
690 rbind->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
692 rbind->length = host_to_be16(sizeof(*rbind) -
694 rbind->version = EAP_TEAP_VERSION;
695 rbind->received_version = data->received_version;
697 * Crypto-Binding TLV is used with Basic-Password-Auth */
701 rbind->subtype = (flags << 4) | subtype;
702 os_memcpy(rbind->nonce, cb->nonce, sizeof(cb->nonce));
703 inc_byte_array(rbind->nonce, sizeof(rbind->nonce));
704 os_memset(rbind->emsk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN);
705 os_memset(rbind->msk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN);
707 if (eap_teap_compound_mac(data->tls_cs, rbind, data->server_outer_tlvs,
708 data->peer_outer_tlvs, cmk_msk,
709 rbind->msk_compound_mac) < 0)
710 return -1;
712 eap_teap_compound_mac(data->tls_cs, rbind, data->server_outer_tlvs,
713 data->peer_outer_tlvs, cmk_emsk,
714 rbind->emsk_compound_mac) < 0)
715 return -1;
718 "EAP-TEAP: Reply Crypto-Binding TLV: Version %u Received Version %u Flags %u SubType %u",
719 rbind->version, rbind->received_version, flags, subtype);
720 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
721 rbind->nonce, sizeof(rbind->nonce));
722 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
723 rbind->emsk_compound_mac, sizeof(rbind->emsk_compound_mac));
724 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
725 rbind->msk_compound_mac, sizeof(rbind->msk_compound_mac));
739 "EAP-TEAP: Determining CMK[%d] for Compound MAC calculation",
740 data->simck_idx + 1);
742 if (!data->phase2_method)
743 return eap_teap_derive_cmk_basic_pw_auth(data->tls_cs,
744 data->simck_msk,
747 if (!data->phase2_method || !data->phase2_priv) {
748 wpa_printf(MSG_INFO, "EAP-TEAP: Phase 2 method not available");
749 return -1;
752 if (data->phase2_method->isKeyAvailable &&
753 !data->phase2_method->isKeyAvailable(sm, data->phase2_priv)) {
755 "EAP-TEAP: Phase 2 key material not available");
756 return -1;
759 if (data->phase2_method->isKeyAvailable &&
760 data->phase2_method->getKey) {
761 msk = data->phase2_method->getKey(sm, data->phase2_priv,
765 "EAP-TEAP: Could not fetch Phase 2 MSK");
766 return -1;
770 if (data->phase2_method->isKeyAvailable &&
771 data->phase2_method->get_emsk) {
772 emsk = data->phase2_method->get_emsk(sm, data->phase2_priv,
776 res = eap_teap_derive_imck(data->tls_cs,
777 data->simck_msk, data->simck_emsk,
779 data->simck_msk, cmk_msk,
780 data->simck_emsk, cmk_emsk);
784 data->simck_idx++;
786 data->cmk_emsk_available = 1;
797 os_free(data->session_id);
798 data->session_id = os_malloc(max_id_len);
799 if (!data->session_id)
800 return -1;
802 data->session_id[0] = EAP_TYPE_TEAP;
803 res = tls_get_tls_unique(data->ssl.conn, data->session_id + 1,
804 max_id_len - 1);
806 os_free(data->session_id);
807 data->session_id = NULL;
808 wpa_printf(MSG_ERROR, "EAP-TEAP: Failed to derive Session-Id");
809 return -1;
812 data->id_len = 1 + res;
813 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Derived Session-Id",
814 data->session_id, data->id_len);
838 flags = cb->subtype >> 4;
844 if (eap_teap_compound_mac(data->tls_cs, cb,
845 data->server_outer_tlvs,
846 data->peer_outer_tlvs, cmk_msk,
849 res = os_memcmp_const(msk_compound_mac, cb->msk_compound_mac,
851 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Received MSK Compound MAC",
852 cb->msk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
854 "EAP-TEAP: Calculated MSK Compound MAC",
858 "EAP-TEAP: MSK Compound MAC did not match");
865 data->cmk_emsk_available) {
868 if (eap_teap_compound_mac(data->tls_cs, cb,
869 data->server_outer_tlvs,
870 data->peer_outer_tlvs, cmk_emsk,
873 res = os_memcmp_const(emsk_compound_mac, cb->emsk_compound_mac,
875 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Received EMSK Compound MAC",
876 cb->emsk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
878 "EAP-TEAP: Calculated EMSK Compound MAC",
882 "EAP-TEAP: EMSK Compound MAC did not match");
890 !data->cmk_emsk_available) {
892 "EAP-TEAP: Server included only EMSK Compound MAC, but no locally generated inner EAP EMSK to validate this");
906 if (data->phase2_success && eap_teap_derive_msk(data) < 0) {
907 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to generate MSK");
908 ret->methodState = METHOD_DONE;
909 ret->decision = DECISION_FAIL;
910 data->phase2_success = 0;
915 if (data->phase2_success && eap_teap_session_id(data) < 0) {
932 static void eap_teap_parse_pac_tlv(struct eap_teap_pac *entry, int type,
937 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: PAC-Key", pos, len);
940 "EAP-TEAP: Invalid PAC-Key length %lu",
945 os_memcpy(entry->pac_key, pos, len);
948 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Opaque", pos, len);
949 entry->pac_opaque = pos;
950 entry->pac_opaque_len = len;
953 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Info", pos, len);
954 entry->pac_info = pos;
955 entry->pac_info_len = len;
958 wpa_printf(MSG_DEBUG, "EAP-TEAP: Ignored unknown PAC type %d",
965 static int eap_teap_process_pac_tlv(struct eap_teap_pac *entry,
978 type = be_to_host16(hdr->type);
979 len = be_to_host16(hdr->len);
981 left -= sizeof(*hdr);
984 "EAP-TEAP: PAC TLV overrun (type=%d len=%lu left=%lu)",
987 return -1;
990 eap_teap_parse_pac_tlv(entry, type, pos, len, &pac_key_found);
993 left -= len;
996 if (!pac_key_found || !entry->pac_opaque || !entry->pac_info) {
998 "EAP-TEAP: PAC TLV does not include all the required fields");
999 return -1;
1006 static int eap_teap_parse_pac_info(struct eap_teap_pac *entry, int type,
1017 "EAP-TEAP: PAC-Info - Invalid CRED_LIFETIME length - ignored",
1025 * needed. Anyway, the information is available from PAC-Info
1031 "EAP-TEAP: PAC-Info - CRED_LIFETIME %d (%d days)",
1032 lifetime, (lifetime - (u32) now.sec) / 86400);
1035 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - A-ID",
1037 entry->a_id = pos;
1038 entry->a_id_len = len;
1041 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - I-ID",
1043 entry->i_id = pos;
1044 entry->i_id_len = len;
1047 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - A-ID-Info",
1049 entry->a_id_info = pos;
1050 entry->a_id_info_len = len;
1053 /* RFC 7170, Section 4.2.12.6 - PAC-Type TLV */
1056 "EAP-TEAP: Invalid PAC-Type length %lu (expected 2)",
1059 "EAP-TEAP: PAC-Info - PAC-Type",
1061 return -1;
1066 "EAP-TEAP: Unsupported PAC Type %d",
1068 return -1;
1071 wpa_printf(MSG_DEBUG, "EAP-TEAP: PAC-Info - PAC-Type %d",
1073 entry->pac_type = pac_type;
1077 "EAP-TEAP: Ignored unknown PAC-Info type %d", type);
1085 static int eap_teap_process_pac_info(struct eap_teap_pac *entry)
1094 /* PAC-Type defaults to Tunnel PAC (Type 1) */
1095 entry->pac_type = PAC_TYPE_TUNNEL_PAC;
1097 pos = entry->pac_info;
1098 left = entry->pac_info_len;
1101 type = be_to_host16(hdr->type);
1102 len = be_to_host16(hdr->len);
1104 left -= sizeof(*hdr);
1107 "EAP-TEAP: PAC-Info overrun (type=%d len=%lu left=%lu)",
1110 return -1;
1113 if (eap_teap_parse_pac_info(entry, type, pos, len) < 0)
1114 return -1;
1117 left -= len;
1120 if (!entry->a_id || !entry->a_id_info) {
1122 "EAP-TEAP: PAC-Info does not include all the required fields");
1123 return -1;
1136 struct eap_teap_pac entry;
1138 os_memset(&entry, 0, sizeof(entry));
1139 if (eap_teap_process_pac_tlv(&entry, pac, pac_len) ||
1140 eap_teap_process_pac_info(&entry))
1143 eap_teap_add_pac(&data->pac, &data->current_pac, &entry);
1144 eap_teap_pac_list_truncate(data->pac, data->max_pac_list_len);
1145 if (data->use_pac_binary_format)
1146 eap_teap_save_pac_bin(sm, data->pac, config->pac_file);
1148 eap_teap_save_pac(sm, data->pac, config->pac_file);
1151 "EAP-TEAP: Send PAC-Acknowledgement - %s initiated provisioning completed successfully",
1152 data->provisioning ? "peer" : "server");
1171 while (end - pos >= 4) {
1177 if (len > (size_t) (end - pos)) {
1178 wpa_printf(MSG_INFO, "EAP-TEAP: TLV overflow");
1179 return -1;
1182 "EAP-TEAP: Received Phase 2: TLV type %u (%s) length %u%s",
1188 if (res == -2)
1193 "EAP-TEAP: NAK unknown mandatory TLV type %u",
1200 "EAP-TEAP: Ignore unknown optional TLV type %u",
1222 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add Request Action TLV (Process TLV)");
1224 act->tlv_type = host_to_be16(TEAP_TLV_REQUEST_ACTION);
1225 act->length = host_to_be16(2);
1226 act->status = TEAP_STATUS_SUCCESS;
1227 act->action = TEAP_REQUEST_ACTION_PROCESS_TLV;
1229 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV (PAC-Type = Tunnel)");
1231 pac->tlv_type = host_to_be16(TEAP_TLV_PAC);
1232 pac->length = host_to_be16(sizeof(*type));
1235 type->type = host_to_be16(PAC_TYPE_PAC_TYPE);
1236 type->length = host_to_be16(2);
1237 type->pac_type = host_to_be16(PAC_TYPE_TUNNEL_PAC);
1257 /* Parsing failed - no response available */
1262 /* Parsing rejected the message - send out an error response */
1267 /* Server indicated failure - respond similarly per
1271 "EAP-TEAP: Server rejected authentication");
1273 ret->methodState = METHOD_DONE;
1274 ret->decision = DECISION_FAIL;
1279 /* Intermediate-Result TLV indicating success, but no
1280 * Crypto-Binding TLV */
1282 "EAP-TEAP: Intermediate-Result TLV indicating success, but no Crypto-Binding TLV");
1288 if (!data->iresult_verified && !data->result_success_done &&
1290 /* Result TLV indicating success, but no Crypto-Binding TLV */
1292 "EAP-TEAP: Result TLV indicating success, but no Crypto-Binding TLV");
1300 data->inner_method_done) {
1302 "EAP-TEAP: Inner EAP method exchange completed, but no Intermediate-Result TLV included");
1312 "EAP-TEAP: Unexpected Crypto-Binding TLV without Result TLV or Intermediate-Result TLV indicating success");
1327 data->result_success_done = 1;
1329 data->inner_method_done = 0;
1330 data->iresult_verified = 1;
1338 sm->use_machine_cred = config && config->machine_identity &&
1339 config->machine_identity_len;
1341 sm->use_machine_cred = 0;
1346 os_free(data->phase2_types);
1347 data->phase2_types = NULL;
1348 data->num_phase2_types = 0;
1351 &data->phase2_types,
1352 &data->num_phase2_types,
1353 sm->use_machine_cred) < 0) {
1355 "EAP-TEAP: Failed to update Phase 2 EAP types");
1390 if (data->result_success_done && data->session_ticket_used &&
1395 "EAP-TEAP: PAC used - server may decide to skip inner authentication");
1396 ret->methodState = METHOD_MAY_CONT;
1397 ret->decision = DECISION_COND_SUCC;
1398 } else if (data->result_success_done &&
1399 tls_connection_get_own_cert_used(data->ssl.conn) &&
1404 "EAP-TEAP: Client certificate used - server may decide to skip inner authentication");
1405 ret->methodState = METHOD_MAY_CONT;
1406 ret->decision = DECISION_COND_SUCC;
1416 "EAP-TEAP: PAC TLV without Result TLV acknowledging success");
1422 if (!data->current_pac && data->provisioning && !failed && !tlv.pac &&
1424 (!data->anon_provisioning ||
1425 (data->phase2_success && data->phase2_method &&
1426 data->phase2_method->vendor == 0 &&
1427 eap_teap_allowed_anon_prov_cipher_suite(data->tls_cs) &&
1429 data->phase2_method->vendor,
1430 data->phase2_method->method))) &&
1437 wpa_printf(MSG_DEBUG, "EAP-TEAP: Request Tunnel PAC");
1452 ret->methodState = METHOD_DONE;
1453 ret->decision = DECISION_FAIL;
1460 tmp = eap_teap_tlv_result((!failed && data->phase2_success) ?
1467 (tlv.crypto_binding || data->iresult_verified) &&
1468 data->phase2_success) {
1471 "EAP-TEAP: Authentication completed successfully");
1472 ret->methodState = METHOD_MAY_CONT;
1473 data->on_tx_completion = data->provisioning ?
1475 ret->decision = DECISION_UNCOND_SUCC;
1480 "EAP-TEAP: No recognized TLVs - send empty response packet");
1488 wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: Encrypting Phase 2 data", resp);
1489 if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TEAP,
1490 data->teap_version, identifier,
1493 "EAP-TEAP: Failed to encrypt a Phase 2 frame");
1510 "EAP-TEAP: Received %lu bytes encrypted data for Phase 2",
1513 if (data->pending_phase2_req) {
1515 "EAP-TEAP: Pending Phase 2 request - skip decryption and use old data");
1517 eap_peer_tls_reset_input(&data->ssl);
1519 in_decrypted = data->pending_phase2_req;
1520 data->pending_phase2_req = NULL;
1525 /* Received TLS ACK - requesting more fragments */
1526 res = eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TEAP,
1527 data->teap_version,
1529 if (res == 0 && !data->ssl.tls_out &&
1530 data->on_tx_completion) {
1532 "EAP-TEAP: Mark authentication completed at full TX of fragments");
1533 ret->methodState = data->on_tx_completion;
1534 data->on_tx_completion = 0;
1535 ret->decision = DECISION_UNCOND_SUCC;
1540 res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
1545 wpa_hexdump_buf(MSG_MSGDUMP, "EAP-TEAP: Decrypted Phase 2 TLV(s)",
1550 "EAP-TEAP: Too short Phase 2 TLV frame (len=%lu)",
1553 return -1;
1570 data->current_pac = eap_teap_get_pac(data->pac, a_id, a_id_len,
1572 if (data->current_pac) {
1574 "EAP-TEAP: PAC found for this A-ID (PAC-Type %d)",
1575 data->current_pac->pac_type);
1576 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TEAP: A-ID-Info",
1577 data->current_pac->a_id_info,
1578 data->current_pac->a_id_info_len);
1591 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC-Opaque TLS extension");
1592 olen = pac->pac_opaque_len;
1597 ehdr->tlv_type = host_to_be16(PAC_TYPE_PAC_OPAQUE);
1598 ehdr->length = host_to_be16(olen);
1599 os_memcpy(ehdr + 1, pac->pac_opaque, olen);
1602 tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,
1606 "EAP-TEAP: Failed to add PAC-Opaque TLS extension");
1608 return -1;
1619 if (tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,
1622 "EAP-TEAP: Failed to remove PAC-Opaque TLS extension");
1623 return -1;
1639 /* EAP-TEAP version negotiation (RFC 7170, Section 3.2) */
1640 data->received_version = flags & EAP_TLS_VERSION_MASK;
1641 wpa_printf(MSG_DEBUG, "EAP-TEAP: Start (server ver=%u, own ver=%u)",
1642 data->received_version, data->teap_version);
1643 if (data->received_version < 1) {
1646 "EAP-TEAP: Server used unknown TEAP version %u",
1647 data->received_version);
1648 return -1;
1650 if (data->received_version < data->teap_version)
1651 data->teap_version = data->received_version;
1652 wpa_printf(MSG_DEBUG, "EAP-TEAP: Using TEAP version %d",
1653 data->teap_version);
1654 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Start message payload", pos, left);
1656 /* Parse Authority-ID TLV from Outer TLVs, if present */
1663 "EAP-TEAP: Not enough room for the Outer TLV Length field");
1664 return -1;
1669 left -= 4;
1673 "EAP-TEAP: Truncated Outer TLVs field (Outer TLV Length: %u; remaining buffer: %u)",
1675 return -1;
1678 outer_pos = pos + left - outer_tlv_len;
1680 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Start message Outer TLVs",
1682 wpabuf_free(data->server_outer_tlvs);
1683 data->server_outer_tlvs = wpabuf_alloc_copy(outer_pos,
1685 if (!data->server_outer_tlvs)
1686 return -1;
1687 left -= outer_tlv_len;
1690 "EAP-TEAP: Unexpected TLS Data in Start message",
1692 return -1;
1698 if (outer_end - outer_pos < 4) {
1700 "EAP-TEAP: Truncated Outer TLV header");
1701 return -1;
1711 "EAP-TEAP: Outer TLV: Type=%u Length=%u",
1713 if (outer_end - outer_pos < tlv_len) {
1715 "EAP-TEAP: Truncated Outer TLV (Type %u)",
1717 return -1;
1720 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Authority-ID",
1724 "EAP-TEAP: Multiple Authority-ID TLVs in TEAP/Start");
1725 return -1;
1731 "EAP-TEAP: Ignore unknown Outer TLV (Type %u)",
1738 "EAP-TEAP: Unexpected TLS Data in Start message",
1740 return -1;
1745 if (data->resuming && data->current_pac) {
1747 "EAP-TEAP: Trying to resume session - do not add PAC-Opaque to TLS ClientHello");
1749 return -1;
1750 } else if (data->current_pac) {
1752 * PAC found for the A-ID and we are not resuming an old
1753 * session, so add PAC-Opaque extension to ClientHello.
1755 if (eap_teap_use_pac_opaque(sm, data, data->current_pac) < 0)
1756 return -1;
1757 } else if (data->provisioning_allowed) {
1759 "EAP-TEAP: No PAC found - starting provisioning");
1761 return -1;
1762 data->provisioning = 1;
1778 wpabuf_free(data->peer_outer_tlvs);
1779 data->peer_outer_tlvs = wpabuf_alloc(4 + 4);
1780 if (!data->peer_outer_tlvs) {
1785 /* Outer TLVs (stub Vendor-Specific TLV for testing) */
1786 wpabuf_put_be16(data->peer_outer_tlvs, TEAP_TLV_VENDOR_SPECIFIC);
1787 wpabuf_put_be16(data->peer_outer_tlvs, 4);
1788 wpabuf_put_be32(data->peer_outer_tlvs, EAP_VENDOR_HOSTAP);
1789 wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: TESTING - Add stub Outer TLVs",
1790 data->peer_outer_tlvs);
1793 "EAP-TEAP: TEAP/Start response before modification",
1796 wpabuf_len(data->peer_outer_tlvs));
1807 wpabuf_put_be16(resp2, len + 4 + wpabuf_len(data->peer_outer_tlvs));
1814 "EAP-TEAP: Cannot add Outer TLVs for testing");
1822 wpabuf_put_be32(resp2, wpabuf_len(data->peer_outer_tlvs));
1824 wpabuf_put_data(resp2, pos, wpabuf_len(resp) - 6);
1825 wpabuf_put_buf(resp2, data->peer_outer_tlvs); /* Outer TLVs */
1829 "EAP-TEAP: TEAP/Start response after modification",
1849 pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TEAP, ret,
1855 id = req->identifier;
1871 "EAP-TEAP: Outer TLVs present in non-Start message -> ignore message");
1878 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
1879 !data->resuming) {
1883 ret->methodState = METHOD_DONE;
1884 ret->decision = DECISION_FAIL;
1892 if (sm->waiting_ext_cert_check && data->pending_resp) {
1895 if (config->pending_ext_cert_check ==
1898 "EAP-TEAP: External certificate check succeeded - continue handshake");
1899 resp = data->pending_resp;
1900 data->pending_resp = NULL;
1901 sm->waiting_ext_cert_check = 0;
1905 if (config->pending_ext_cert_check ==
1908 "EAP-TEAP: External certificate check failed - force authentication failure");
1909 ret->methodState = METHOD_DONE;
1910 ret->decision = DECISION_FAIL;
1911 sm->waiting_ext_cert_check = 0;
1916 "EAP-TEAP: Continuing to wait external server certificate validation");
1921 res = eap_peer_tls_process_helper(sm, &data->ssl,
1923 data->teap_version, id, &msg,
1927 "EAP-TEAP: TLS processing failed");
1928 ret->methodState = METHOD_DONE;
1929 ret->decision = DECISION_FAIL;
1933 if (sm->waiting_ext_cert_check) {
1935 "EAP-TEAP: Waiting external server certificate validation");
1936 wpabuf_free(data->pending_resp);
1937 data->pending_resp = resp;
1941 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
1945 "EAP-TEAP: TLS done, proceed to Phase 2");
1946 data->tls_cs =
1947 tls_connection_get_cipher_suite(data->ssl.conn);
1949 "EAP-TEAP: TLS cipher suite 0x%04x",
1950 data->tls_cs);
1952 if (data->provisioning &&
1953 (!(data->provisioning_allowed &
1955 tls_get_cipher(sm->ssl_ctx, data->ssl.conn,
1957 os_strstr(cipher, "ADH-") ||
1960 "EAP-TEAP: Using anonymous (unauthenticated) provisioning");
1961 data->anon_provisioning = 1;
1963 data->anon_provisioning = 0;
1965 data->resuming = 0;
1968 "EAP-TEAP: Could not derive keys");
1969 ret->methodState = METHOD_DONE;
1970 ret->decision = DECISION_FAIL;
1980 wpabuf_free(data->pending_phase2_req);
1981 data->pending_phase2_req = resp;
1990 data->teap_version);
1994 if (data->test_outer_tlvs && res == 0 && resp &&
2008 return tls_connection_established(sm->ssl_ctx, data->ssl.conn);
2016 if (data->phase2_priv && data->phase2_method &&
2017 data->phase2_method->deinit_for_reauth)
2018 data->phase2_method->deinit_for_reauth(sm, data->phase2_priv);
2027 if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
2031 if (data->phase2_priv && data->phase2_method &&
2032 data->phase2_method->init_for_reauth)
2033 data->phase2_method->init_for_reauth(sm, data->phase2_priv);
2034 data->phase2_success = 0;
2035 data->inner_method_done = 0;
2036 data->result_success_done = 0;
2037 data->iresult_verified = 0;
2038 data->done_on_tx_completion = 0;
2039 data->resuming = 1;
2040 data->provisioning = 0;
2041 data->anon_provisioning = 0;
2042 data->simck_idx = 0;
2054 len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);
2055 if (data->phase2_method) {
2056 ret = os_snprintf(buf + len, buflen - len,
2057 "EAP-TEAP Phase 2 method=%s\n",
2058 data->phase2_method->name);
2059 if (os_snprintf_error(buflen - len, ret))
2071 return data->success;
2080 if (!data->success)
2083 key = os_memdup(data->key_data, EAP_TEAP_KEY_LEN);
2098 if (!data->success || !data->session_id)
2101 id = os_memdup(data->session_id, data->id_len);
2105 *len = data->id_len;
2116 if (!data->success)
2119 key = os_memdup(data->emsk, EAP_EMSK_LEN);
2136 return -1;
2138 eap->init = eap_teap_init;
2139 eap->deinit = eap_teap_deinit;
2140 eap->process = eap_teap_process;
2141 eap->isKeyAvailable = eap_teap_isKeyAvailable;
2142 eap->getKey = eap_teap_getKey;
2143 eap->getSessionId = eap_teap_get_session_id;
2144 eap->get_status = eap_teap_get_status;
2146 eap->has_reauth_data = eap_teap_has_reauth_data;
2147 eap->deinit_for_reauth = eap_teap_deinit_for_reauth;
2148 eap->init_for_reauth = eap_teap_init_for_reauth;
2150 eap->get_emsk = eap_teap_get_emsk;