]> git.ipfire.org Git - thirdparty/hostap.git/blob - src/eap_peer/eap_teap.c
EAP-TEAP peer: Allow Result TLV without Crypto-Binding TLV
[thirdparty/hostap.git] / src / eap_peer / eap_teap.c
1 /*
2 * EAP peer method: EAP-TEAP (RFC 7170)
3 * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "crypto/tls.h"
13 #include "eap_common/eap_teap_common.h"
14 #include "eap_i.h"
15 #include "eap_tls_common.h"
16 #include "eap_config.h"
17 #include "eap_teap_pac.h"
18
19 #ifdef EAP_TEAP_DYNAMIC
20 #include "eap_teap_pac.c"
21 #endif /* EAP_TEAP_DYNAMIC */
22
23
24 static void eap_teap_deinit(struct eap_sm *sm, void *priv);
25
26
27 struct eap_teap_data {
28 struct eap_ssl_data ssl;
29
30 u8 teap_version; /* Negotiated version */
31 u8 received_version; /* Version number received during negotiation */
32 u16 tls_cs;
33
34 const struct eap_method *phase2_method;
35 void *phase2_priv;
36 int phase2_success;
37 int inner_method_done;
38 int iresult_verified;
39 int result_success_done;
40 int on_tx_completion;
41
42 struct eap_method_type phase2_type;
43 struct eap_method_type *phase2_types;
44 size_t num_phase2_types;
45 int resuming; /* starting a resumed session */
46 #define EAP_TEAP_PROV_UNAUTH 1
47 #define EAP_TEAP_PROV_AUTH 2
48 int provisioning_allowed; /* Allowed PAC provisioning modes */
49 int provisioning; /* doing PAC provisioning (not the normal auth) */
50 int anon_provisioning; /* doing anonymous (unauthenticated)
51 * provisioning */
52 int session_ticket_used;
53 int test_outer_tlvs;
54
55 u8 key_data[EAP_TEAP_KEY_LEN];
56 u8 *session_id;
57 size_t id_len;
58 u8 emsk[EAP_EMSK_LEN];
59 int success;
60
61 struct eap_teap_pac *pac;
62 struct eap_teap_pac *current_pac;
63 size_t max_pac_list_len;
64 int use_pac_binary_format;
65
66 u8 simck_msk[EAP_TEAP_SIMCK_LEN];
67 u8 simck_emsk[EAP_TEAP_SIMCK_LEN];
68 int simck_idx;
69 int cmk_emsk_available;
70
71 struct wpabuf *pending_phase2_req;
72 struct wpabuf *pending_resp;
73 struct wpabuf *server_outer_tlvs;
74 struct wpabuf *peer_outer_tlvs;
75 };
76
77
78 static int eap_teap_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
79 const u8 *client_random,
80 const u8 *server_random,
81 u8 *master_secret)
82 {
83 struct eap_teap_data *data = ctx;
84
85 wpa_printf(MSG_DEBUG, "EAP-TEAP: SessionTicket callback");
86
87 if (!master_secret) {
88 wpa_printf(MSG_DEBUG,
89 "EAP-TEAP: SessionTicket failed - fall back to full TLS handshake");
90 data->session_ticket_used = 0;
91 if (data->provisioning_allowed) {
92 wpa_printf(MSG_DEBUG,
93 "EAP-TEAP: Try to provision a new PAC-Key");
94 data->provisioning = 1;
95 data->current_pac = NULL;
96 }
97 return 0;
98 }
99
100 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: SessionTicket", ticket, len);
101
102 if (!data->current_pac) {
103 wpa_printf(MSG_DEBUG,
104 "EAP-TEAP: No PAC-Key available for using SessionTicket");
105 data->session_ticket_used = 0;
106 return 0;
107 }
108
109 /* EAP-TEAP uses PAC-Key as the TLS master_secret */
110 os_memcpy(master_secret, data->current_pac->pac_key,
111 EAP_TEAP_PAC_KEY_LEN);
112
113 data->session_ticket_used = 1;
114
115 return 1;
116 }
117
118
119 static void eap_teap_parse_phase1(struct eap_teap_data *data,
120 const char *phase1)
121 {
122 const char *pos;
123
124 pos = os_strstr(phase1, "teap_provisioning=");
125 if (pos) {
126 data->provisioning_allowed = atoi(pos + 18);
127 wpa_printf(MSG_DEBUG,
128 "EAP-TEAP: Automatic PAC provisioning mode: %d",
129 data->provisioning_allowed);
130 }
131
132 pos = os_strstr(phase1, "teap_max_pac_list_len=");
133 if (pos) {
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);
139 }
140
141 if (os_strstr(phase1, "teap_pac_format=binary")) {
142 data->use_pac_binary_format = 1;
143 wpa_printf(MSG_DEBUG,
144 "EAP-TEAP: Using binary format for PAC list");
145 }
146
147 #ifdef CONFIG_TESTING_OPTIONS
148 if (os_strstr(phase1, "teap_test_outer_tlvs=1"))
149 data->test_outer_tlvs = 1;
150 #endif /* CONFIG_TESTING_OPTIONS */
151 }
152
153
154 static void * eap_teap_init(struct eap_sm *sm)
155 {
156 struct eap_teap_data *data;
157 struct eap_peer_config *config = eap_get_config(sm);
158
159 if (!config)
160 return NULL;
161
162 data = os_zalloc(sizeof(*data));
163 if (!data)
164 return NULL;
165 data->teap_version = EAP_TEAP_VERSION;
166 data->max_pac_list_len = 10;
167
168 if (config->phase1)
169 eap_teap_parse_phase1(data, config->phase1);
170
171 if ((data->provisioning_allowed & EAP_TEAP_PROV_AUTH) &&
172 !config->ca_cert && !config->ca_path) {
173 /* Prevent PAC provisioning without mutual authentication
174 * (either by validating server certificate or by suitable
175 * inner EAP method). */
176 wpa_printf(MSG_INFO,
177 "EAP-TEAP: Disable authenticated provisioning due to no ca_cert/ca_path");
178 data->provisioning_allowed &= ~EAP_TEAP_PROV_AUTH;
179 }
180
181 if (eap_peer_select_phase2_methods(config, "auth=",
182 &data->phase2_types,
183 &data->num_phase2_types) < 0) {
184 eap_teap_deinit(sm, data);
185 return NULL;
186 }
187
188 data->phase2_type.vendor = EAP_VENDOR_IETF;
189 data->phase2_type.method = EAP_TYPE_NONE;
190
191 config->teap_anon_dh = !!(data->provisioning_allowed &
192 EAP_TEAP_PROV_UNAUTH);
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");
195 eap_teap_deinit(sm, data);
196 return NULL;
197 }
198
199 if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn,
200 eap_teap_session_ticket_cb,
201 data) < 0) {
202 wpa_printf(MSG_INFO,
203 "EAP-TEAP: Failed to set SessionTicket callback");
204 eap_teap_deinit(sm, data);
205 return NULL;
206 }
207
208 if (!config->pac_file) {
209 wpa_printf(MSG_INFO, "EAP-TEAP: No PAC file configured");
210 eap_teap_deinit(sm, data);
211 return NULL;
212 }
213
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");
217 eap_teap_deinit(sm, data);
218 return NULL;
219 }
220
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");
224 eap_teap_deinit(sm, data);
225 return NULL;
226 }
227 eap_teap_pac_list_truncate(data->pac, data->max_pac_list_len);
228
229 return data;
230 }
231
232
233 static void eap_teap_clear(struct eap_teap_data *data)
234 {
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);
249 }
250
251
252 static void eap_teap_deinit(struct eap_sm *sm, void *priv)
253 {
254 struct eap_teap_data *data = priv;
255 struct eap_teap_pac *pac, *prev;
256
257 if (!data)
258 return;
259 if (data->phase2_priv && data->phase2_method)
260 data->phase2_method->deinit(sm, data->phase2_priv);
261 eap_teap_clear(data);
262 os_free(data->phase2_types);
263 eap_peer_tls_ssl_deinit(sm, &data->ssl);
264
265 pac = data->pac;
266 prev = NULL;
267 while (pac) {
268 prev = pac;
269 pac = pac->next;
270 eap_teap_free_pac(prev);
271 }
272
273 os_free(data);
274 }
275
276
277 static int eap_teap_derive_msk(struct eap_teap_data *data)
278 {
279 /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j]
280 * is used in this derivation */
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;
287 return 0;
288 }
289
290
291 static int eap_teap_derive_key_auth(struct eap_sm *sm,
292 struct eap_teap_data *data)
293 {
294 int res;
295
296 /* RFC 7170, Section 5.1 */
297 res = tls_connection_export_key(sm->ssl_ctx, data->ssl.conn,
298 TEAP_TLS_EXPORTER_LABEL_SKS, NULL, 0,
299 data->simck_msk, EAP_TEAP_SIMCK_LEN);
300 if (res)
301 return res;
302 wpa_hexdump_key(MSG_DEBUG,
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;
307 return 0;
308 }
309
310
311 static int eap_teap_init_phase2_method(struct eap_sm *sm,
312 struct eap_teap_data *data)
313 {
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;
321
322 sm->init_phase2 = 1;
323 data->phase2_priv = data->phase2_method->init(sm);
324 sm->init_phase2 = 0;
325
326 return data->phase2_priv == NULL ? -1 : 0;
327 }
328
329
330 static int eap_teap_select_phase2_method(struct eap_teap_data *data, u8 type)
331 {
332 size_t i;
333
334 /* TODO: TNC with anonymous provisioning; need to require both
335 * completed inner EAP authentication (EAP-pwd or EAP-EKE) and TNC */
336
337 if (data->anon_provisioning &&
338 !eap_teap_allowed_anon_prov_phase2_method(type)) {
339 wpa_printf(MSG_INFO,
340 "EAP-TEAP: EAP type %u not allowed during unauthenticated provisioning",
341 type);
342 return -1;
343 }
344
345 #ifdef EAP_TNC
346 if (type == EAP_TYPE_TNC) {
347 data->phase2_type.vendor = EAP_VENDOR_IETF;
348 data->phase2_type.method = EAP_TYPE_TNC;
349 wpa_printf(MSG_DEBUG,
350 "EAP-TEAP: Selected Phase 2 EAP vendor %d method %d for TNC",
351 data->phase2_type.vendor,
352 data->phase2_type.method);
353 return 0;
354 }
355 #endif /* EAP_TNC */
356
357 for (i = 0; i < data->num_phase2_types; i++) {
358 if (data->phase2_types[i].vendor != EAP_VENDOR_IETF ||
359 data->phase2_types[i].method != type)
360 continue;
361
362 data->phase2_type.vendor = data->phase2_types[i].vendor;
363 data->phase2_type.method = data->phase2_types[i].method;
364 wpa_printf(MSG_DEBUG,
365 "EAP-TEAP: Selected Phase 2 EAP vendor %d method %d",
366 data->phase2_type.vendor,
367 data->phase2_type.method);
368 break;
369 }
370
371 if (type != data->phase2_type.method || type == EAP_TYPE_NONE)
372 return -1;
373
374 return 0;
375 }
376
377
378 static int eap_teap_phase2_request(struct eap_sm *sm,
379 struct eap_teap_data *data,
380 struct eap_method_ret *ret,
381 struct eap_hdr *hdr,
382 struct wpabuf **resp)
383 {
384 size_t len = be_to_host16(hdr->length);
385 u8 *pos;
386 struct eap_method_ret iret;
387 struct eap_peer_config *config = eap_get_config(sm);
388 struct wpabuf msg;
389
390 if (len <= sizeof(struct eap_hdr)) {
391 wpa_printf(MSG_INFO,
392 "EAP-TEAP: too short Phase 2 request (len=%lu)",
393 (unsigned long) len);
394 return -1;
395 }
396 pos = (u8 *) (hdr + 1);
397 wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 Request: type=%d", *pos);
398 if (*pos == EAP_TYPE_IDENTITY) {
399 *resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
400 return 0;
401 }
402
403 if (data->phase2_priv && data->phase2_method &&
404 *pos != data->phase2_type.method) {
405 wpa_printf(MSG_DEBUG,
406 "EAP-TEAP: Phase 2 EAP sequence - deinitialize previous method");
407 data->phase2_method->deinit(sm, data->phase2_priv);
408 data->phase2_method = NULL;
409 data->phase2_priv = NULL;
410 data->phase2_type.vendor = EAP_VENDOR_IETF;
411 data->phase2_type.method = EAP_TYPE_NONE;
412 }
413
414 if (data->phase2_type.vendor == EAP_VENDOR_IETF &&
415 data->phase2_type.method == EAP_TYPE_NONE &&
416 eap_teap_select_phase2_method(data, *pos) < 0) {
417 if (eap_peer_tls_phase2_nak(data->phase2_types,
418 data->num_phase2_types,
419 hdr, resp))
420 return -1;
421 return 0;
422 }
423
424 if ((!data->phase2_priv && eap_teap_init_phase2_method(sm, data) < 0) ||
425 !data->phase2_method) {
426 wpa_printf(MSG_INFO,
427 "EAP-TEAP: Failed to initialize Phase 2 EAP method %d",
428 *pos);
429 ret->methodState = METHOD_DONE;
430 ret->decision = DECISION_FAIL;
431 return -1;
432 }
433
434 os_memset(&iret, 0, sizeof(iret));
435 wpabuf_set(&msg, hdr, len);
436 *resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
437 &msg);
438 if (iret.methodState == METHOD_DONE)
439 data->inner_method_done = 1;
440 if (!(*resp) ||
441 (iret.methodState == METHOD_DONE &&
442 iret.decision == DECISION_FAIL)) {
443 ret->methodState = METHOD_DONE;
444 ret->decision = DECISION_FAIL;
445 } else if ((iret.methodState == METHOD_DONE ||
446 iret.methodState == METHOD_MAY_CONT) &&
447 (iret.decision == DECISION_UNCOND_SUCC ||
448 iret.decision == DECISION_COND_SUCC)) {
449 data->phase2_success = 1;
450 }
451
452 if (!(*resp) && config &&
453 (config->pending_req_identity || config->pending_req_password ||
454 config->pending_req_otp || config->pending_req_new_password ||
455 config->pending_req_sim)) {
456 wpabuf_free(data->pending_phase2_req);
457 data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
458 } else if (!(*resp))
459 return -1;
460
461 return 0;
462 }
463
464
465 static struct wpabuf * eap_teap_tlv_nak(int vendor_id, int tlv_type)
466 {
467 struct wpabuf *buf;
468 struct teap_tlv_nak *nak;
469
470 wpa_printf(MSG_DEBUG,
471 "EAP-TEAP: Add NAK TLV (Vendor-Id %u NAK-Type %u)",
472 vendor_id, tlv_type);
473 buf = wpabuf_alloc(sizeof(*nak));
474 if (!buf)
475 return NULL;
476 nak = wpabuf_put(buf, sizeof(*nak));
477 nak->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | TEAP_TLV_NAK);
478 nak->length = host_to_be16(6);
479 nak->vendor_id = host_to_be32(vendor_id);
480 nak->nak_type = host_to_be16(tlv_type);
481 return buf;
482 }
483
484
485 static struct wpabuf * eap_teap_tlv_pac_ack(void)
486 {
487 struct wpabuf *buf;
488 struct teap_tlv_result *res;
489 struct teap_tlv_pac_ack *ack;
490
491 buf = wpabuf_alloc(sizeof(*res) + sizeof(*ack));
492 if (!buf)
493 return NULL;
494
495 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV (ack)");
496 ack = wpabuf_put(buf, sizeof(*ack));
497 ack->tlv_type = host_to_be16(TEAP_TLV_PAC | TEAP_TLV_MANDATORY);
498 ack->length = host_to_be16(sizeof(*ack) - sizeof(struct teap_tlv_hdr));
499 ack->pac_type = host_to_be16(PAC_TYPE_PAC_ACKNOWLEDGEMENT);
500 ack->pac_len = host_to_be16(2);
501 ack->result = host_to_be16(TEAP_STATUS_SUCCESS);
502
503 return buf;
504 }
505
506
507 static struct wpabuf * eap_teap_process_eap_payload_tlv(
508 struct eap_sm *sm, struct eap_teap_data *data,
509 struct eap_method_ret *ret,
510 u8 *eap_payload_tlv, size_t eap_payload_tlv_len)
511 {
512 struct eap_hdr *hdr;
513 struct wpabuf *resp = NULL;
514
515 if (eap_payload_tlv_len < sizeof(*hdr)) {
516 wpa_printf(MSG_DEBUG,
517 "EAP-TEAP: too short EAP Payload TLV (len=%lu)",
518 (unsigned long) eap_payload_tlv_len);
519 return NULL;
520 }
521
522 hdr = (struct eap_hdr *) eap_payload_tlv;
523 if (be_to_host16(hdr->length) > eap_payload_tlv_len) {
524 wpa_printf(MSG_DEBUG,
525 "EAP-TEAP: EAP packet overflow in EAP Payload TLV");
526 return NULL;
527 }
528
529 if (hdr->code != EAP_CODE_REQUEST) {
530 wpa_printf(MSG_INFO,
531 "EAP-TEAP: Unexpected code=%d in Phase 2 EAP header",
532 hdr->code);
533 return NULL;
534 }
535
536 if (eap_teap_phase2_request(sm, data, ret, hdr, &resp)) {
537 wpa_printf(MSG_INFO,
538 "EAP-TEAP: Phase 2 Request processing failed");
539 return NULL;
540 }
541
542 return eap_teap_tlv_eap_payload(resp);
543 }
544
545
546 static struct wpabuf * eap_teap_process_basic_auth_req(
547 struct eap_sm *sm, struct eap_teap_data *data,
548 u8 *basic_auth_req, size_t basic_auth_req_len)
549 {
550 const u8 *identity, *password;
551 size_t identity_len, password_len, plen;
552 struct wpabuf *resp;
553
554 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: Basic-Password-Auth-Req prompt",
555 basic_auth_req, basic_auth_req_len);
556 /* TODO: send over control interface */
557
558 identity = eap_get_config_identity(sm, &identity_len);
559 password = eap_get_config_password(sm, &password_len);
560 if (!identity || !password ||
561 identity_len > 255 || password_len > 255) {
562 wpa_printf(MSG_DEBUG,
563 "EAP-TEAP: No username/password suitable for Basic-Password-Auth");
564 return eap_teap_tlv_nak(0, TEAP_TLV_BASIC_PASSWORD_AUTH_REQ);
565 }
566
567 plen = 1 + identity_len + 1 + password_len;
568 resp = wpabuf_alloc(sizeof(struct teap_tlv_hdr) + plen);
569 if (!resp)
570 return NULL;
571 eap_teap_put_tlv_hdr(resp, TEAP_TLV_BASIC_PASSWORD_AUTH_RESP, plen);
572 wpabuf_put_u8(resp, identity_len);
573 wpabuf_put_data(resp, identity, identity_len);
574 wpabuf_put_u8(resp, password_len);
575 wpabuf_put_data(resp, password, password_len);
576 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Basic-Password-Auth-Resp",
577 resp);
578
579 /* Assume this succeeds so that Result TLV(Success) from the server can
580 * be used to terminate TEAP. */
581 data->phase2_success = 1;
582
583 return resp;
584 }
585
586
587 static int
588 eap_teap_validate_crypto_binding(struct eap_teap_data *data,
589 const struct teap_tlv_crypto_binding *cb)
590 {
591 u8 flags, subtype;
592
593 subtype = cb->subtype & 0x0f;
594 flags = cb->subtype >> 4;
595
596 wpa_printf(MSG_DEBUG,
597 "EAP-TEAP: Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
598 cb->version, cb->received_version, flags, subtype);
599 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
600 cb->nonce, sizeof(cb->nonce));
601 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
602 cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac));
603 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
604 cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
605
606 if (cb->version != EAP_TEAP_VERSION ||
607 cb->received_version != data->received_version ||
608 subtype != TEAP_CRYPTO_BINDING_SUBTYPE_REQUEST ||
609 flags < 1 || flags > 3) {
610 wpa_printf(MSG_INFO,
611 "EAP-TEAP: Invalid Version/Flags/Sub-Type in Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
612 cb->version, cb->received_version, flags, subtype);
613 return -1;
614 }
615
616 if (cb->nonce[EAP_TEAP_NONCE_LEN - 1] & 0x01) {
617 wpa_printf(MSG_INFO,
618 "EAP-TEAP: Invalid Crypto-Binding TLV Nonce in request");
619 return -1;
620 }
621
622 return 0;
623 }
624
625
626 static int eap_teap_write_crypto_binding(
627 struct eap_teap_data *data,
628 struct teap_tlv_crypto_binding *rbind,
629 const struct teap_tlv_crypto_binding *cb,
630 const u8 *cmk_msk, const u8 *cmk_emsk)
631 {
632 u8 subtype, flags;
633
634 rbind->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
635 TEAP_TLV_CRYPTO_BINDING);
636 rbind->length = host_to_be16(sizeof(*rbind) -
637 sizeof(struct teap_tlv_hdr));
638 rbind->version = EAP_TEAP_VERSION;
639 rbind->received_version = data->received_version;
640 /* FIX: RFC 7170 is not clear on which Flags value to use when
641 * Crypto-Binding TLV is used with Basic-Password-Auth */
642 flags = cmk_emsk ? TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC :
643 TEAP_CRYPTO_BINDING_MSK_CMAC;
644 subtype = TEAP_CRYPTO_BINDING_SUBTYPE_RESPONSE;
645 rbind->subtype = (flags << 4) | subtype;
646 os_memcpy(rbind->nonce, cb->nonce, sizeof(cb->nonce));
647 inc_byte_array(rbind->nonce, sizeof(rbind->nonce));
648 os_memset(rbind->emsk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN);
649 os_memset(rbind->msk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN);
650
651 if (eap_teap_compound_mac(data->tls_cs, rbind, data->server_outer_tlvs,
652 data->peer_outer_tlvs, cmk_msk,
653 rbind->msk_compound_mac) < 0)
654 return -1;
655 if (cmk_emsk &&
656 eap_teap_compound_mac(data->tls_cs, rbind, data->server_outer_tlvs,
657 data->peer_outer_tlvs, cmk_emsk,
658 rbind->emsk_compound_mac) < 0)
659 return -1;
660
661 wpa_printf(MSG_DEBUG,
662 "EAP-TEAP: Reply Crypto-Binding TLV: Version %u Received Version %u Flags %u SubType %u",
663 rbind->version, rbind->received_version, flags, subtype);
664 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
665 rbind->nonce, sizeof(rbind->nonce));
666 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
667 rbind->emsk_compound_mac, sizeof(rbind->emsk_compound_mac));
668 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
669 rbind->msk_compound_mac, sizeof(rbind->msk_compound_mac));
670
671 return 0;
672 }
673
674
675 static int eap_teap_get_cmk(struct eap_sm *sm, struct eap_teap_data *data,
676 u8 *cmk_msk, u8 *cmk_emsk)
677 {
678 u8 *msk = NULL, *emsk = NULL;
679 size_t msk_len = 0, emsk_len = 0;
680 int res;
681
682 wpa_printf(MSG_DEBUG,
683 "EAP-TEAP: Determining CMK[%d] for Compound MAC calculation",
684 data->simck_idx + 1);
685
686 if (!data->phase2_method)
687 return eap_teap_derive_cmk_basic_pw_auth(data->tls_cs,
688 data->simck_msk,
689 cmk_msk);
690
691 if (!data->phase2_method || !data->phase2_priv) {
692 wpa_printf(MSG_INFO, "EAP-TEAP: Phase 2 method not available");
693 return -1;
694 }
695
696 if (data->phase2_method->isKeyAvailable &&
697 !data->phase2_method->isKeyAvailable(sm, data->phase2_priv)) {
698 wpa_printf(MSG_INFO,
699 "EAP-TEAP: Phase 2 key material not available");
700 return -1;
701 }
702
703 if (data->phase2_method->isKeyAvailable &&
704 data->phase2_method->getKey) {
705 msk = data->phase2_method->getKey(sm, data->phase2_priv,
706 &msk_len);
707 if (!msk) {
708 wpa_printf(MSG_INFO,
709 "EAP-TEAP: Could not fetch Phase 2 MSK");
710 return -1;
711 }
712 }
713
714 if (data->phase2_method->isKeyAvailable &&
715 data->phase2_method->get_emsk) {
716 emsk = data->phase2_method->get_emsk(sm, data->phase2_priv,
717 &emsk_len);
718 }
719
720 res = eap_teap_derive_imck(data->tls_cs,
721 data->simck_msk, data->simck_emsk,
722 msk, msk_len, emsk, emsk_len,
723 data->simck_msk, cmk_msk,
724 data->simck_emsk, cmk_emsk);
725 bin_clear_free(msk, msk_len);
726 bin_clear_free(emsk, emsk_len);
727 if (res == 0) {
728 data->simck_idx++;
729 if (emsk)
730 data->cmk_emsk_available = 1;
731 }
732 return res;
733 }
734
735
736 static int eap_teap_session_id(struct eap_teap_data *data)
737 {
738 const size_t max_id_len = 100;
739 int res;
740
741 os_free(data->session_id);
742 data->session_id = os_malloc(max_id_len);
743 if (!data->session_id)
744 return -1;
745
746 data->session_id[0] = EAP_TYPE_TEAP;
747 res = tls_get_tls_unique(data->ssl.conn, data->session_id + 1,
748 max_id_len - 1);
749 if (res < 0) {
750 os_free(data->session_id);
751 data->session_id = NULL;
752 wpa_printf(MSG_ERROR, "EAP-TEAP: Failed to derive Session-Id");
753 return -1;
754 }
755
756 data->id_len = 1 + res;
757 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Derived Session-Id",
758 data->session_id, data->id_len);
759 return 0;
760 }
761
762
763 static struct wpabuf * eap_teap_process_crypto_binding(
764 struct eap_sm *sm, struct eap_teap_data *data,
765 struct eap_method_ret *ret,
766 const struct teap_tlv_crypto_binding *cb, size_t bind_len)
767 {
768 struct wpabuf *resp;
769 u8 *pos;
770 u8 cmk_msk[EAP_TEAP_CMK_LEN];
771 u8 cmk_emsk[EAP_TEAP_CMK_LEN];
772 const u8 *cmk_emsk_ptr = NULL;
773 int res;
774 size_t len;
775 u8 flags;
776
777 if (eap_teap_validate_crypto_binding(data, cb) < 0 ||
778 eap_teap_get_cmk(sm, data, cmk_msk, cmk_emsk) < 0)
779 return NULL;
780
781 /* Validate received MSK/EMSK Compound MAC */
782 flags = cb->subtype >> 4;
783
784 if (flags == TEAP_CRYPTO_BINDING_MSK_CMAC ||
785 flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) {
786 u8 msk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN];
787
788 if (eap_teap_compound_mac(data->tls_cs, cb,
789 data->server_outer_tlvs,
790 data->peer_outer_tlvs, cmk_msk,
791 msk_compound_mac) < 0)
792 return NULL;
793 res = os_memcmp_const(msk_compound_mac, cb->msk_compound_mac,
794 EAP_TEAP_COMPOUND_MAC_LEN);
795 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Received MSK Compound MAC",
796 cb->msk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
797 wpa_hexdump(MSG_MSGDUMP,
798 "EAP-TEAP: Calculated MSK Compound MAC",
799 msk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
800 if (res != 0) {
801 wpa_printf(MSG_INFO,
802 "EAP-TEAP: MSK Compound MAC did not match");
803 return NULL;
804 }
805 }
806
807 if ((flags == TEAP_CRYPTO_BINDING_EMSK_CMAC ||
808 flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) &&
809 data->cmk_emsk_available) {
810 u8 emsk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN];
811
812 if (eap_teap_compound_mac(data->tls_cs, cb,
813 data->server_outer_tlvs,
814 data->peer_outer_tlvs, cmk_emsk,
815 emsk_compound_mac) < 0)
816 return NULL;
817 res = os_memcmp_const(emsk_compound_mac, cb->emsk_compound_mac,
818 EAP_TEAP_COMPOUND_MAC_LEN);
819 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Received EMSK Compound MAC",
820 cb->emsk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
821 wpa_hexdump(MSG_MSGDUMP,
822 "EAP-TEAP: Calculated EMSK Compound MAC",
823 emsk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
824 if (res != 0) {
825 wpa_printf(MSG_INFO,
826 "EAP-TEAP: EMSK Compound MAC did not match");
827 return NULL;
828 }
829
830 cmk_emsk_ptr = cmk_emsk;
831 }
832
833 if (flags == TEAP_CRYPTO_BINDING_EMSK_CMAC &&
834 !data->cmk_emsk_available) {
835 wpa_printf(MSG_INFO,
836 "EAP-TEAP: Server included only EMSK Compound MAC, but no locally generated inner EAP EMSK to validate this");
837 return NULL;
838 }
839
840 /*
841 * Compound MAC was valid, so authentication succeeded. Reply with
842 * crypto binding to allow server to complete authentication.
843 */
844
845 len = sizeof(struct teap_tlv_crypto_binding);
846 resp = wpabuf_alloc(len);
847 if (!resp)
848 return NULL;
849
850 if (data->phase2_success && eap_teap_derive_msk(data) < 0) {
851 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to generate MSK");
852 ret->methodState = METHOD_DONE;
853 ret->decision = DECISION_FAIL;
854 data->phase2_success = 0;
855 wpabuf_free(resp);
856 return NULL;
857 }
858
859 if (data->phase2_success && eap_teap_session_id(data) < 0) {
860 wpabuf_free(resp);
861 return NULL;
862 }
863
864 pos = wpabuf_put(resp, sizeof(struct teap_tlv_crypto_binding));
865 if (eap_teap_write_crypto_binding(
866 data, (struct teap_tlv_crypto_binding *) pos,
867 cb, cmk_msk, cmk_emsk_ptr) < 0) {
868 wpabuf_free(resp);
869 return NULL;
870 }
871
872 return resp;
873 }
874
875
876 static void eap_teap_parse_pac_tlv(struct eap_teap_pac *entry, int type,
877 u8 *pos, size_t len, int *pac_key_found)
878 {
879 switch (type & 0x7fff) {
880 case PAC_TYPE_PAC_KEY:
881 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: PAC-Key", pos, len);
882 if (len != EAP_TEAP_PAC_KEY_LEN) {
883 wpa_printf(MSG_DEBUG,
884 "EAP-TEAP: Invalid PAC-Key length %lu",
885 (unsigned long) len);
886 break;
887 }
888 *pac_key_found = 1;
889 os_memcpy(entry->pac_key, pos, len);
890 break;
891 case PAC_TYPE_PAC_OPAQUE:
892 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Opaque", pos, len);
893 entry->pac_opaque = pos;
894 entry->pac_opaque_len = len;
895 break;
896 case PAC_TYPE_PAC_INFO:
897 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Info", pos, len);
898 entry->pac_info = pos;
899 entry->pac_info_len = len;
900 break;
901 default:
902 wpa_printf(MSG_DEBUG, "EAP-TEAP: Ignored unknown PAC type %d",
903 type);
904 break;
905 }
906 }
907
908
909 static int eap_teap_process_pac_tlv(struct eap_teap_pac *entry,
910 u8 *pac, size_t pac_len)
911 {
912 struct pac_attr_hdr *hdr;
913 u8 *pos;
914 size_t left, len;
915 int type, pac_key_found = 0;
916
917 pos = pac;
918 left = pac_len;
919
920 while (left > sizeof(*hdr)) {
921 hdr = (struct pac_attr_hdr *) pos;
922 type = be_to_host16(hdr->type);
923 len = be_to_host16(hdr->len);
924 pos += sizeof(*hdr);
925 left -= sizeof(*hdr);
926 if (len > left) {
927 wpa_printf(MSG_DEBUG,
928 "EAP-TEAP: PAC TLV overrun (type=%d len=%lu left=%lu)",
929 type, (unsigned long) len,
930 (unsigned long) left);
931 return -1;
932 }
933
934 eap_teap_parse_pac_tlv(entry, type, pos, len, &pac_key_found);
935
936 pos += len;
937 left -= len;
938 }
939
940 if (!pac_key_found || !entry->pac_opaque || !entry->pac_info) {
941 wpa_printf(MSG_DEBUG,
942 "EAP-TEAP: PAC TLV does not include all the required fields");
943 return -1;
944 }
945
946 return 0;
947 }
948
949
950 static int eap_teap_parse_pac_info(struct eap_teap_pac *entry, int type,
951 u8 *pos, size_t len)
952 {
953 u16 pac_type;
954 u32 lifetime;
955 struct os_time now;
956
957 switch (type & 0x7fff) {
958 case PAC_TYPE_CRED_LIFETIME:
959 if (len != 4) {
960 wpa_hexdump(MSG_DEBUG,
961 "EAP-TEAP: PAC-Info - Invalid CRED_LIFETIME length - ignored",
962 pos, len);
963 return 0;
964 }
965
966 /*
967 * This is not currently saved separately in PAC files since
968 * the server can automatically initiate PAC update when
969 * needed. Anyway, the information is available from PAC-Info
970 * dump if it is needed for something in the future.
971 */
972 lifetime = WPA_GET_BE32(pos);
973 os_get_time(&now);
974 wpa_printf(MSG_DEBUG,
975 "EAP-TEAP: PAC-Info - CRED_LIFETIME %d (%d days)",
976 lifetime, (lifetime - (u32) now.sec) / 86400);
977 break;
978 case PAC_TYPE_A_ID:
979 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - A-ID",
980 pos, len);
981 entry->a_id = pos;
982 entry->a_id_len = len;
983 break;
984 case PAC_TYPE_I_ID:
985 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - I-ID",
986 pos, len);
987 entry->i_id = pos;
988 entry->i_id_len = len;
989 break;
990 case PAC_TYPE_A_ID_INFO:
991 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - A-ID-Info",
992 pos, len);
993 entry->a_id_info = pos;
994 entry->a_id_info_len = len;
995 break;
996 case PAC_TYPE_PAC_TYPE:
997 /* RFC 7170, Section 4.2.12.6 - PAC-Type TLV */
998 if (len != 2) {
999 wpa_printf(MSG_INFO,
1000 "EAP-TEAP: Invalid PAC-Type length %lu (expected 2)",
1001 (unsigned long) len);
1002 wpa_hexdump_ascii(MSG_DEBUG,
1003 "EAP-TEAP: PAC-Info - PAC-Type",
1004 pos, len);
1005 return -1;
1006 }
1007 pac_type = WPA_GET_BE16(pos);
1008 if (pac_type != PAC_TYPE_TUNNEL_PAC) {
1009 wpa_printf(MSG_INFO,
1010 "EAP-TEAP: Unsupported PAC Type %d",
1011 pac_type);
1012 return -1;
1013 }
1014
1015 wpa_printf(MSG_DEBUG, "EAP-TEAP: PAC-Info - PAC-Type %d",
1016 pac_type);
1017 entry->pac_type = pac_type;
1018 break;
1019 default:
1020 wpa_printf(MSG_DEBUG,
1021 "EAP-TEAP: Ignored unknown PAC-Info type %d", type);
1022 break;
1023 }
1024
1025 return 0;
1026 }
1027
1028
1029 static int eap_teap_process_pac_info(struct eap_teap_pac *entry)
1030 {
1031 struct pac_attr_hdr *hdr;
1032 u8 *pos;
1033 size_t left, len;
1034 int type;
1035
1036 /* RFC 7170, Section 4.2.12.4 */
1037
1038 /* PAC-Type defaults to Tunnel PAC (Type 1) */
1039 entry->pac_type = PAC_TYPE_TUNNEL_PAC;
1040
1041 pos = entry->pac_info;
1042 left = entry->pac_info_len;
1043 while (left > sizeof(*hdr)) {
1044 hdr = (struct pac_attr_hdr *) pos;
1045 type = be_to_host16(hdr->type);
1046 len = be_to_host16(hdr->len);
1047 pos += sizeof(*hdr);
1048 left -= sizeof(*hdr);
1049 if (len > left) {
1050 wpa_printf(MSG_DEBUG,
1051 "EAP-TEAP: PAC-Info overrun (type=%d len=%lu left=%lu)",
1052 type, (unsigned long) len,
1053 (unsigned long) left);
1054 return -1;
1055 }
1056
1057 if (eap_teap_parse_pac_info(entry, type, pos, len) < 0)
1058 return -1;
1059
1060 pos += len;
1061 left -= len;
1062 }
1063
1064 if (!entry->a_id || !entry->a_id_info) {
1065 wpa_printf(MSG_DEBUG,
1066 "EAP-TEAP: PAC-Info does not include all the required fields");
1067 return -1;
1068 }
1069
1070 return 0;
1071 }
1072
1073
1074 static struct wpabuf * eap_teap_process_pac(struct eap_sm *sm,
1075 struct eap_teap_data *data,
1076 struct eap_method_ret *ret,
1077 u8 *pac, size_t pac_len)
1078 {
1079 struct eap_peer_config *config = eap_get_config(sm);
1080 struct eap_teap_pac entry;
1081
1082 os_memset(&entry, 0, sizeof(entry));
1083 if (eap_teap_process_pac_tlv(&entry, pac, pac_len) ||
1084 eap_teap_process_pac_info(&entry))
1085 return NULL;
1086
1087 eap_teap_add_pac(&data->pac, &data->current_pac, &entry);
1088 eap_teap_pac_list_truncate(data->pac, data->max_pac_list_len);
1089 if (data->use_pac_binary_format)
1090 eap_teap_save_pac_bin(sm, data->pac, config->pac_file);
1091 else
1092 eap_teap_save_pac(sm, data->pac, config->pac_file);
1093
1094 wpa_printf(MSG_DEBUG,
1095 "EAP-TEAP: Send PAC-Acknowledgement - %s initiated provisioning completed successfully",
1096 data->provisioning ? "peer" : "server");
1097 return eap_teap_tlv_pac_ack();
1098 }
1099
1100
1101 static int eap_teap_parse_decrypted(struct wpabuf *decrypted,
1102 struct eap_teap_tlv_parse *tlv,
1103 struct wpabuf **resp)
1104 {
1105 u16 tlv_type;
1106 int mandatory, res;
1107 size_t len;
1108 u8 *pos, *end;
1109
1110 os_memset(tlv, 0, sizeof(*tlv));
1111
1112 /* Parse TLVs from the decrypted Phase 2 data */
1113 pos = wpabuf_mhead(decrypted);
1114 end = pos + wpabuf_len(decrypted);
1115 while (end - pos >= 4) {
1116 mandatory = pos[0] & 0x80;
1117 tlv_type = WPA_GET_BE16(pos) & 0x3fff;
1118 pos += 2;
1119 len = WPA_GET_BE16(pos);
1120 pos += 2;
1121 if (len > (size_t) (end - pos)) {
1122 wpa_printf(MSG_INFO, "EAP-TEAP: TLV overflow");
1123 return -1;
1124 }
1125 wpa_printf(MSG_DEBUG,
1126 "EAP-TEAP: Received Phase 2: TLV type %u (%s) length %u%s",
1127 tlv_type, eap_teap_tlv_type_str(tlv_type),
1128 (unsigned int) len,
1129 mandatory ? " (mandatory)" : "");
1130
1131 res = eap_teap_parse_tlv(tlv, tlv_type, pos, len);
1132 if (res == -2)
1133 break;
1134 if (res < 0) {
1135 if (mandatory) {
1136 wpa_printf(MSG_DEBUG,
1137 "EAP-TEAP: NAK unknown mandatory TLV type %u",
1138 tlv_type);
1139 *resp = eap_teap_tlv_nak(0, tlv_type);
1140 break;
1141 }
1142
1143 wpa_printf(MSG_DEBUG,
1144 "EAP-TEAP: Ignore unknown optional TLV type %u",
1145 tlv_type);
1146 }
1147
1148 pos += len;
1149 }
1150
1151 return 0;
1152 }
1153
1154
1155 static struct wpabuf * eap_teap_pac_request(void)
1156 {
1157 struct wpabuf *req;
1158 struct teap_tlv_request_action *act;
1159 struct teap_tlv_hdr *pac;
1160 struct teap_attr_pac_type *type;
1161
1162 req = wpabuf_alloc(sizeof(*act) + sizeof(*pac) + sizeof(*type));
1163 if (!req)
1164 return NULL;
1165
1166 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add Request Action TLV (Process TLV)");
1167 act = wpabuf_put(req, sizeof(*act));
1168 act->tlv_type = host_to_be16(TEAP_TLV_REQUEST_ACTION);
1169 act->length = host_to_be16(2);
1170 act->status = TEAP_STATUS_SUCCESS;
1171 act->action = TEAP_REQUEST_ACTION_PROCESS_TLV;
1172
1173 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV (PAC-Type = Tunnel)");
1174 pac = wpabuf_put(req, sizeof(*pac));
1175 pac->tlv_type = host_to_be16(TEAP_TLV_PAC);
1176 pac->length = host_to_be16(sizeof(*type));
1177
1178 type = wpabuf_put(req, sizeof(*type));
1179 type->type = host_to_be16(PAC_TYPE_PAC_TYPE);
1180 type->length = host_to_be16(2);
1181 type->pac_type = host_to_be16(PAC_TYPE_TUNNEL_PAC);
1182
1183 return req;
1184 }
1185
1186
1187 static int eap_teap_process_decrypted(struct eap_sm *sm,
1188 struct eap_teap_data *data,
1189 struct eap_method_ret *ret,
1190 u8 identifier,
1191 struct wpabuf *decrypted,
1192 struct wpabuf **out_data)
1193 {
1194 struct wpabuf *resp = NULL, *tmp;
1195 struct eap_teap_tlv_parse tlv;
1196 int failed = 0;
1197 enum teap_error_codes error = 0;
1198 int iresult_added = 0;
1199
1200 if (eap_teap_parse_decrypted(decrypted, &tlv, &resp) < 0) {
1201 /* Parsing failed - no response available */
1202 return 0;
1203 }
1204
1205 if (resp) {
1206 /* Parsing rejected the message - send out an error response */
1207 goto send_resp;
1208 }
1209
1210 if (tlv.result == TEAP_STATUS_FAILURE) {
1211 /* Server indicated failure - respond similarly per
1212 * RFC 7170, 3.6.3. This authentication exchange cannot succeed
1213 * and will be terminated with a cleartext EAP Failure. */
1214 wpa_printf(MSG_DEBUG,
1215 "EAP-TEAP: Server rejected authentication");
1216 resp = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0);
1217 ret->methodState = METHOD_DONE;
1218 ret->decision = DECISION_FAIL;
1219 goto send_resp;
1220 }
1221
1222 if (tlv.iresult == TEAP_STATUS_SUCCESS && !tlv.crypto_binding) {
1223 /* Intermediate-Result TLV indicating success, but no
1224 * Crypto-Binding TLV */
1225 wpa_printf(MSG_DEBUG,
1226 "EAP-TEAP: Intermediate-Result TLV indicating success, but no Crypto-Binding TLV");
1227 failed = 1;
1228 error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
1229 goto done;
1230 }
1231
1232 if (!data->iresult_verified && !data->result_success_done &&
1233 tlv.result == TEAP_STATUS_SUCCESS && !tlv.crypto_binding) {
1234 /* Result TLV indicating success, but no Crypto-Binding TLV */
1235 wpa_printf(MSG_DEBUG,
1236 "EAP-TEAP: Result TLV indicating success, but no Crypto-Binding TLV");
1237 failed = 1;
1238 error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
1239 goto done;
1240 }
1241
1242 if (tlv.iresult != TEAP_STATUS_SUCCESS &&
1243 tlv.iresult != TEAP_STATUS_FAILURE &&
1244 data->inner_method_done) {
1245 wpa_printf(MSG_DEBUG,
1246 "EAP-TEAP: Inner EAP method exchange completed, but no Intermediate-Result TLV included");
1247 failed = 1;
1248 error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
1249 goto done;
1250 }
1251
1252 if (tlv.basic_auth_req) {
1253 tmp = eap_teap_process_basic_auth_req(sm, data,
1254 tlv.basic_auth_req,
1255 tlv.basic_auth_req_len);
1256 if (!tmp)
1257 failed = 1;
1258 resp = wpabuf_concat(resp, tmp);
1259 } else if (tlv.eap_payload_tlv) {
1260 tmp = eap_teap_process_eap_payload_tlv(sm, data, ret,
1261 tlv.eap_payload_tlv,
1262 tlv.eap_payload_tlv_len);
1263 if (!tmp)
1264 failed = 1;
1265 resp = wpabuf_concat(resp, tmp);
1266
1267 if (tlv.iresult == TEAP_STATUS_SUCCESS ||
1268 tlv.iresult == TEAP_STATUS_FAILURE) {
1269 tmp = eap_teap_tlv_result(failed ?
1270 TEAP_STATUS_FAILURE :
1271 TEAP_STATUS_SUCCESS, 1);
1272 resp = wpabuf_concat(resp, tmp);
1273 if (tlv.iresult == TEAP_STATUS_FAILURE)
1274 failed = 1;
1275 iresult_added = 1;
1276 }
1277 }
1278
1279 if (tlv.crypto_binding) {
1280 if (tlv.iresult != TEAP_STATUS_SUCCESS &&
1281 tlv.result != TEAP_STATUS_SUCCESS) {
1282 wpa_printf(MSG_DEBUG,
1283 "EAP-TEAP: Unexpected Crypto-Binding TLV without Result TLV or Intermediate-Result TLV indicating success");
1284 failed = 1;
1285 error = TEAP_ERROR_UNEXPECTED_TLVS_EXCHANGED;
1286 goto done;
1287 }
1288
1289 tmp = eap_teap_process_crypto_binding(sm, data, ret,
1290 tlv.crypto_binding,
1291 tlv.crypto_binding_len);
1292 if (!tmp) {
1293 failed = 1;
1294 error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
1295 } else {
1296 resp = wpabuf_concat(resp, tmp);
1297 if (tlv.result == TEAP_STATUS_SUCCESS && !failed)
1298 data->result_success_done = 1;
1299 if (tlv.iresult == TEAP_STATUS_SUCCESS && !failed) {
1300 data->inner_method_done = 0;
1301 data->iresult_verified = 1;
1302 }
1303 }
1304 }
1305
1306 if (data->result_success_done && data->session_ticket_used &&
1307 eap_teap_derive_msk(data) == 0) {
1308 /* Assume the server might accept authentication without going
1309 * through inner authentication. */
1310 wpa_printf(MSG_DEBUG,
1311 "EAP-TEAP: PAC used - server may decide to skip inner authentication");
1312 ret->methodState = METHOD_MAY_CONT;
1313 ret->decision = DECISION_COND_SUCC;
1314 }
1315
1316 if (tlv.pac) {
1317 if (tlv.result == TEAP_STATUS_SUCCESS) {
1318 tmp = eap_teap_process_pac(sm, data, ret,
1319 tlv.pac, tlv.pac_len);
1320 resp = wpabuf_concat(resp, tmp);
1321 } else {
1322 wpa_printf(MSG_DEBUG,
1323 "EAP-TEAP: PAC TLV without Result TLV acknowledging success");
1324 failed = 1;
1325 error = TEAP_ERROR_UNEXPECTED_TLVS_EXCHANGED;
1326 }
1327 }
1328
1329 if (!data->current_pac && data->provisioning && !failed && !tlv.pac &&
1330 tlv.crypto_binding &&
1331 (!data->anon_provisioning ||
1332 (data->phase2_success && data->phase2_method &&
1333 data->phase2_method->vendor == 0 &&
1334 eap_teap_allowed_anon_prov_cipher_suite(data->tls_cs) &&
1335 eap_teap_allowed_anon_prov_phase2_method(
1336 data->phase2_method->method))) &&
1337 (tlv.iresult == TEAP_STATUS_SUCCESS ||
1338 tlv.result == TEAP_STATUS_SUCCESS)) {
1339 /*
1340 * Need to request Tunnel PAC when using authenticated
1341 * provisioning.
1342 */
1343 wpa_printf(MSG_DEBUG, "EAP-TEAP: Request Tunnel PAC");
1344 tmp = eap_teap_pac_request();
1345 resp = wpabuf_concat(resp, tmp);
1346 }
1347
1348 done:
1349 if (failed) {
1350 tmp = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0);
1351 resp = wpabuf_concat(tmp, resp);
1352
1353 if (error != 0) {
1354 tmp = eap_teap_tlv_error(error);
1355 resp = wpabuf_concat(tmp, resp);
1356 }
1357
1358 ret->methodState = METHOD_DONE;
1359 ret->decision = DECISION_FAIL;
1360 } else if (tlv.result == TEAP_STATUS_SUCCESS) {
1361 tmp = eap_teap_tlv_result(TEAP_STATUS_SUCCESS, 0);
1362 resp = wpabuf_concat(tmp, resp);
1363 }
1364 if ((tlv.iresult == TEAP_STATUS_SUCCESS ||
1365 tlv.iresult == TEAP_STATUS_FAILURE) && !iresult_added) {
1366 tmp = eap_teap_tlv_result((!failed && data->phase2_success) ?
1367 TEAP_STATUS_SUCCESS :
1368 TEAP_STATUS_FAILURE, 1);
1369 resp = wpabuf_concat(tmp, resp);
1370 }
1371
1372 if (resp && tlv.result == TEAP_STATUS_SUCCESS && !failed &&
1373 (tlv.crypto_binding || data->iresult_verified) &&
1374 data->phase2_success) {
1375 /* Successfully completed Phase 2 */
1376 wpa_printf(MSG_DEBUG,
1377 "EAP-TEAP: Authentication completed successfully");
1378 ret->methodState = METHOD_MAY_CONT;
1379 data->on_tx_completion = data->provisioning ?
1380 METHOD_MAY_CONT : METHOD_DONE;
1381 ret->decision = DECISION_UNCOND_SUCC;
1382 }
1383
1384 if (!resp) {
1385 wpa_printf(MSG_DEBUG,
1386 "EAP-TEAP: No recognized TLVs - send empty response packet");
1387 resp = wpabuf_alloc(1);
1388 }
1389
1390 send_resp:
1391 if (!resp)
1392 return 0;
1393
1394 wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: Encrypting Phase 2 data", resp);
1395 if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TEAP,
1396 data->teap_version, identifier,
1397 resp, out_data)) {
1398 wpa_printf(MSG_INFO,
1399 "EAP-TEAP: Failed to encrypt a Phase 2 frame");
1400 }
1401 wpabuf_free(resp);
1402
1403 return 0;
1404 }
1405
1406
1407 static int eap_teap_decrypt(struct eap_sm *sm, struct eap_teap_data *data,
1408 struct eap_method_ret *ret, u8 identifier,
1409 const struct wpabuf *in_data,
1410 struct wpabuf **out_data)
1411 {
1412 struct wpabuf *in_decrypted;
1413 int res;
1414
1415 wpa_printf(MSG_DEBUG,
1416 "EAP-TEAP: Received %lu bytes encrypted data for Phase 2",
1417 (unsigned long) wpabuf_len(in_data));
1418
1419 if (data->pending_phase2_req) {
1420 wpa_printf(MSG_DEBUG,
1421 "EAP-TEAP: Pending Phase 2 request - skip decryption and use old data");
1422 /* Clear TLS reassembly state. */
1423 eap_peer_tls_reset_input(&data->ssl);
1424
1425 in_decrypted = data->pending_phase2_req;
1426 data->pending_phase2_req = NULL;
1427 goto continue_req;
1428 }
1429
1430 if (wpabuf_len(in_data) == 0) {
1431 /* Received TLS ACK - requesting more fragments */
1432 res = eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TEAP,
1433 data->teap_version,
1434 identifier, NULL, out_data);
1435 if (res == 0 && !data->ssl.tls_out &&
1436 data->on_tx_completion) {
1437 wpa_printf(MSG_DEBUG,
1438 "EAP-TEAP: Mark authentication completed at full TX of fragments");
1439 ret->methodState = data->on_tx_completion;
1440 data->on_tx_completion = 0;
1441 ret->decision = DECISION_UNCOND_SUCC;
1442 }
1443 return res;
1444 }
1445
1446 res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
1447 if (res)
1448 return res;
1449
1450 continue_req:
1451 wpa_hexdump_buf(MSG_MSGDUMP, "EAP-TEAP: Decrypted Phase 2 TLV(s)",
1452 in_decrypted);
1453
1454 if (wpabuf_len(in_decrypted) < 4) {
1455 wpa_printf(MSG_INFO,
1456 "EAP-TEAP: Too short Phase 2 TLV frame (len=%lu)",
1457 (unsigned long) wpabuf_len(in_decrypted));
1458 wpabuf_free(in_decrypted);
1459 return -1;
1460 }
1461
1462 res = eap_teap_process_decrypted(sm, data, ret, identifier,
1463 in_decrypted, out_data);
1464
1465 wpabuf_free(in_decrypted);
1466
1467 return res;
1468 }
1469
1470
1471 static void eap_teap_select_pac(struct eap_teap_data *data,
1472 const u8 *a_id, size_t a_id_len)
1473 {
1474 if (!a_id)
1475 return;
1476 data->current_pac = eap_teap_get_pac(data->pac, a_id, a_id_len,
1477 PAC_TYPE_TUNNEL_PAC);
1478 if (data->current_pac) {
1479 wpa_printf(MSG_DEBUG,
1480 "EAP-TEAP: PAC found for this A-ID (PAC-Type %d)",
1481 data->current_pac->pac_type);
1482 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TEAP: A-ID-Info",
1483 data->current_pac->a_id_info,
1484 data->current_pac->a_id_info_len);
1485 }
1486 }
1487
1488
1489 static int eap_teap_use_pac_opaque(struct eap_sm *sm,
1490 struct eap_teap_data *data,
1491 struct eap_teap_pac *pac)
1492 {
1493 u8 *tlv;
1494 size_t tlv_len, olen;
1495 struct teap_tlv_hdr *ehdr;
1496
1497 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC-Opaque TLS extension");
1498 olen = pac->pac_opaque_len;
1499 tlv_len = sizeof(*ehdr) + olen;
1500 tlv = os_malloc(tlv_len);
1501 if (tlv) {
1502 ehdr = (struct teap_tlv_hdr *) tlv;
1503 ehdr->tlv_type = host_to_be16(PAC_TYPE_PAC_OPAQUE);
1504 ehdr->length = host_to_be16(olen);
1505 os_memcpy(ehdr + 1, pac->pac_opaque, olen);
1506 }
1507 if (!tlv ||
1508 tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,
1509 TLS_EXT_PAC_OPAQUE,
1510 tlv, tlv_len) < 0) {
1511 wpa_printf(MSG_DEBUG,
1512 "EAP-TEAP: Failed to add PAC-Opaque TLS extension");
1513 os_free(tlv);
1514 return -1;
1515 }
1516 os_free(tlv);
1517
1518 return 0;
1519 }
1520
1521
1522 static int eap_teap_clear_pac_opaque_ext(struct eap_sm *sm,
1523 struct eap_teap_data *data)
1524 {
1525 if (tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,
1526 TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) {
1527 wpa_printf(MSG_DEBUG,
1528 "EAP-TEAP: Failed to remove PAC-Opaque TLS extension");
1529 return -1;
1530 }
1531 return 0;
1532 }
1533
1534
1535 static int eap_teap_process_start(struct eap_sm *sm,
1536 struct eap_teap_data *data, u8 flags,
1537 const u8 *pos, size_t left)
1538 {
1539 const u8 *a_id = NULL;
1540 size_t a_id_len = 0;
1541
1542 /* TODO: Support (mostly theoretical) case of TEAP/Start request being
1543 * fragmented */
1544
1545 /* EAP-TEAP version negotiation (RFC 7170, Section 3.2) */
1546 data->received_version = flags & EAP_TLS_VERSION_MASK;
1547 wpa_printf(MSG_DEBUG, "EAP-TEAP: Start (server ver=%u, own ver=%u)",
1548 data->received_version, data->teap_version);
1549 if (data->received_version < 1) {
1550 /* Version 1 was the first defined version, so reject 0 */
1551 wpa_printf(MSG_INFO,
1552 "EAP-TEAP: Server used unknown TEAP version %u",
1553 data->received_version);
1554 return -1;
1555 }
1556 if (data->received_version < data->teap_version)
1557 data->teap_version = data->received_version;
1558 wpa_printf(MSG_DEBUG, "EAP-TEAP: Using TEAP version %d",
1559 data->teap_version);
1560 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Start message payload", pos, left);
1561
1562 /* Parse Authority-ID TLV from Outer TLVs, if present */
1563 if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) {
1564 const u8 *outer_pos, *outer_end;
1565 u32 outer_tlv_len;
1566
1567 if (left < 4) {
1568 wpa_printf(MSG_INFO,
1569 "EAP-TEAP: Not enough room for the Outer TLV Length field");
1570 return -1;
1571 }
1572
1573 outer_tlv_len = WPA_GET_BE32(pos);
1574 pos += 4;
1575 left -= 4;
1576
1577 if (outer_tlv_len > left) {
1578 wpa_printf(MSG_INFO,
1579 "EAP-TEAP: Truncated Outer TLVs field (Outer TLV Length: %u; remaining buffer: %u)",
1580 outer_tlv_len, (unsigned int) left);
1581 return -1;
1582 }
1583
1584 outer_pos = pos + left - outer_tlv_len;
1585 outer_end = outer_pos + outer_tlv_len;
1586 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Start message Outer TLVs",
1587 outer_pos, outer_tlv_len);
1588 wpabuf_free(data->server_outer_tlvs);
1589 data->server_outer_tlvs = wpabuf_alloc_copy(outer_pos,
1590 outer_tlv_len);
1591 if (!data->server_outer_tlvs)
1592 return -1;
1593 left -= outer_tlv_len;
1594 if (left > 0) {
1595 wpa_hexdump(MSG_INFO,
1596 "EAP-TEAP: Unexpected TLS Data in Start message",
1597 pos, left);
1598 return -1;
1599 }
1600
1601 while (outer_pos < outer_end) {
1602 u16 tlv_type, tlv_len;
1603
1604 if (outer_end - outer_pos < 4) {
1605 wpa_printf(MSG_INFO,
1606 "EAP-TEAP: Truncated Outer TLV header");
1607 return -1;
1608 }
1609 tlv_type = WPA_GET_BE16(outer_pos);
1610 outer_pos += 2;
1611 tlv_len = WPA_GET_BE16(outer_pos);
1612 outer_pos += 2;
1613 /* Outer TLVs are required to be optional, so no need to
1614 * check the M flag */
1615 tlv_type &= TEAP_TLV_TYPE_MASK;
1616 wpa_printf(MSG_DEBUG,
1617 "EAP-TEAP: Outer TLV: Type=%u Length=%u",
1618 tlv_type, tlv_len);
1619 if (outer_end - outer_pos < tlv_len) {
1620 wpa_printf(MSG_INFO,
1621 "EAP-TEAP: Truncated Outer TLV (Type %u)",
1622 tlv_type);
1623 return -1;
1624 }
1625 if (tlv_type == TEAP_TLV_AUTHORITY_ID) {
1626 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Authority-ID",
1627 outer_pos, tlv_len);
1628 if (a_id) {
1629 wpa_printf(MSG_INFO,
1630 "EAP-TEAP: Multiple Authority-ID TLVs in TEAP/Start");
1631 return -1;
1632 }
1633 a_id = outer_pos;
1634 a_id_len = tlv_len;
1635 } else {
1636 wpa_printf(MSG_DEBUG,
1637 "EAP-TEAP: Ignore unknown Outer TLV (Type %u)",
1638 tlv_type);
1639 }
1640 outer_pos += tlv_len;
1641 }
1642 } else if (left > 0) {
1643 wpa_hexdump(MSG_INFO,
1644 "EAP-TEAP: Unexpected TLS Data in Start message",
1645 pos, left);
1646 return -1;
1647 }
1648
1649 eap_teap_select_pac(data, a_id, a_id_len);
1650
1651 if (data->resuming && data->current_pac) {
1652 wpa_printf(MSG_DEBUG,
1653 "EAP-TEAP: Trying to resume session - do not add PAC-Opaque to TLS ClientHello");
1654 if (eap_teap_clear_pac_opaque_ext(sm, data) < 0)
1655 return -1;
1656 } else if (data->current_pac) {
1657 /*
1658 * PAC found for the A-ID and we are not resuming an old
1659 * session, so add PAC-Opaque extension to ClientHello.
1660 */
1661 if (eap_teap_use_pac_opaque(sm, data, data->current_pac) < 0)
1662 return -1;
1663 } else if (data->provisioning_allowed) {
1664 wpa_printf(MSG_DEBUG,
1665 "EAP-TEAP: No PAC found - starting provisioning");
1666 if (eap_teap_clear_pac_opaque_ext(sm, data) < 0)
1667 return -1;
1668 data->provisioning = 1;
1669 }
1670
1671 return 0;
1672 }
1673
1674
1675 #ifdef CONFIG_TESTING_OPTIONS
1676 static struct wpabuf * eap_teap_add_dummy_outer_tlvs(struct eap_teap_data *data,
1677 struct wpabuf *resp)
1678 {
1679 struct wpabuf *resp2;
1680 u16 len;
1681 const u8 *pos;
1682 u8 flags;
1683
1684 wpabuf_free(data->peer_outer_tlvs);
1685 data->peer_outer_tlvs = wpabuf_alloc(4 + 4);
1686 if (!data->peer_outer_tlvs) {
1687 wpabuf_free(resp);
1688 return NULL;
1689 }
1690
1691 /* Outer TLVs (dummy Vendor-Specific TLV for testing) */
1692 wpabuf_put_be16(data->peer_outer_tlvs, TEAP_TLV_VENDOR_SPECIFIC);
1693 wpabuf_put_be16(data->peer_outer_tlvs, 4);
1694 wpabuf_put_be32(data->peer_outer_tlvs, EAP_VENDOR_HOSTAP);
1695 wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: TESTING - Add dummy Outer TLVs",
1696 data->peer_outer_tlvs);
1697
1698 wpa_hexdump_buf(MSG_DEBUG,
1699 "EAP-TEAP: TEAP/Start response before modification",
1700 resp);
1701 resp2 = wpabuf_alloc(wpabuf_len(resp) + 4 +
1702 wpabuf_len(data->peer_outer_tlvs));
1703 if (!resp2) {
1704 wpabuf_free(resp);
1705 return NULL;
1706 }
1707
1708 pos = wpabuf_head(resp);
1709 wpabuf_put_u8(resp2, *pos++); /* Code */
1710 wpabuf_put_u8(resp2, *pos++); /* Identifier */
1711 len = WPA_GET_BE16(pos);
1712 pos += 2;
1713 wpabuf_put_be16(resp2, len + 4 + wpabuf_len(data->peer_outer_tlvs));
1714 wpabuf_put_u8(resp2, *pos++); /* Type */
1715 /* Flags | Ver (with Outer TLV length included flag set to 1) */
1716 flags = *pos++;
1717 if (flags & (EAP_TEAP_FLAGS_OUTER_TLV_LEN |
1718 EAP_TLS_FLAGS_LENGTH_INCLUDED)) {
1719 wpa_printf(MSG_INFO,
1720 "EAP-TEAP: Cannot add Outer TLVs for testing");
1721 wpabuf_free(resp);
1722 wpabuf_free(resp2);
1723 return NULL;
1724 }
1725 flags |= EAP_TEAP_FLAGS_OUTER_TLV_LEN;
1726 wpabuf_put_u8(resp2, flags);
1727 /* Outer TLV Length */
1728 wpabuf_put_be32(resp2, wpabuf_len(data->peer_outer_tlvs));
1729 /* TLS Data */
1730 wpabuf_put_data(resp2, pos, wpabuf_len(resp) - 6);
1731 wpabuf_put_buf(resp2, data->peer_outer_tlvs); /* Outer TLVs */
1732
1733 wpabuf_free(resp);
1734 wpa_hexdump_buf(MSG_DEBUG,
1735 "EAP-TEAP: TEAP/Start response after modification",
1736 resp2);
1737 return resp2;
1738 }
1739 #endif /* CONFIG_TESTING_OPTIONS */
1740
1741
1742 static struct wpabuf * eap_teap_process(struct eap_sm *sm, void *priv,
1743 struct eap_method_ret *ret,
1744 const struct wpabuf *reqData)
1745 {
1746 const struct eap_hdr *req;
1747 size_t left;
1748 int res;
1749 u8 flags, id;
1750 struct wpabuf *resp;
1751 const u8 *pos;
1752 struct eap_teap_data *data = priv;
1753 struct wpabuf msg;
1754
1755 pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TEAP, ret,
1756 reqData, &left, &flags);
1757 if (!pos)
1758 return NULL;
1759
1760 req = wpabuf_head(reqData);
1761 id = req->identifier;
1762
1763 if (flags & EAP_TLS_FLAGS_START) {
1764 if (eap_teap_process_start(sm, data, flags, pos, left) < 0)
1765 return NULL;
1766
1767 /* Outer TLVs are not used in further packet processing and
1768 * there cannot be TLS Data in this TEAP/Start message, so
1769 * enforce that by ignoring whatever data might remain in the
1770 * buffer. */
1771 left = 0;
1772 } else if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) {
1773 /* TODO: RFC 7170, Section 4.3.1 indicates that the unexpected
1774 * Outer TLVs MUST be ignored instead of ignoring the full
1775 * message. */
1776 wpa_printf(MSG_INFO,
1777 "EAP-TEAP: Outer TLVs present in non-Start message -> ignore message");
1778 return NULL;
1779 }
1780
1781 wpabuf_set(&msg, pos, left);
1782
1783 resp = NULL;
1784 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
1785 !data->resuming) {
1786 /* Process tunneled (encrypted) phase 2 data. */
1787 res = eap_teap_decrypt(sm, data, ret, id, &msg, &resp);
1788 if (res < 0) {
1789 ret->methodState = METHOD_DONE;
1790 ret->decision = DECISION_FAIL;
1791 /*
1792 * Ack possible Alert that may have caused failure in
1793 * decryption.
1794 */
1795 res = 1;
1796 }
1797 } else {
1798 if (sm->waiting_ext_cert_check && data->pending_resp) {
1799 struct eap_peer_config *config = eap_get_config(sm);
1800
1801 if (config->pending_ext_cert_check ==
1802 EXT_CERT_CHECK_GOOD) {
1803 wpa_printf(MSG_DEBUG,
1804 "EAP-TEAP: External certificate check succeeded - continue handshake");
1805 resp = data->pending_resp;
1806 data->pending_resp = NULL;
1807 sm->waiting_ext_cert_check = 0;
1808 return resp;
1809 }
1810
1811 if (config->pending_ext_cert_check ==
1812 EXT_CERT_CHECK_BAD) {
1813 wpa_printf(MSG_DEBUG,
1814 "EAP-TEAP: External certificate check failed - force authentication failure");
1815 ret->methodState = METHOD_DONE;
1816 ret->decision = DECISION_FAIL;
1817 sm->waiting_ext_cert_check = 0;
1818 return NULL;
1819 }
1820
1821 wpa_printf(MSG_DEBUG,
1822 "EAP-TEAP: Continuing to wait external server certificate validation");
1823 return NULL;
1824 }
1825
1826 /* Continue processing TLS handshake (phase 1). */
1827 res = eap_peer_tls_process_helper(sm, &data->ssl,
1828 EAP_TYPE_TEAP,
1829 data->teap_version, id, &msg,
1830 &resp);
1831 if (res < 0) {
1832 wpa_printf(MSG_DEBUG,
1833 "EAP-TEAP: TLS processing failed");
1834 ret->methodState = METHOD_DONE;
1835 ret->decision = DECISION_FAIL;
1836 return resp;
1837 }
1838
1839 if (sm->waiting_ext_cert_check) {
1840 wpa_printf(MSG_DEBUG,
1841 "EAP-TEAP: Waiting external server certificate validation");
1842 wpabuf_free(data->pending_resp);
1843 data->pending_resp = resp;
1844 return NULL;
1845 }
1846
1847 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
1848 char cipher[80];
1849
1850 wpa_printf(MSG_DEBUG,
1851 "EAP-TEAP: TLS done, proceed to Phase 2");
1852 data->tls_cs =
1853 tls_connection_get_cipher_suite(data->ssl.conn);
1854 wpa_printf(MSG_DEBUG,
1855 "EAP-TEAP: TLS cipher suite 0x%04x",
1856 data->tls_cs);
1857
1858 if (data->provisioning &&
1859 (!(data->provisioning_allowed &
1860 EAP_TEAP_PROV_AUTH) ||
1861 tls_get_cipher(sm->ssl_ctx, data->ssl.conn,
1862 cipher, sizeof(cipher)) < 0 ||
1863 os_strstr(cipher, "ADH-") ||
1864 os_strstr(cipher, "anon"))) {
1865 wpa_printf(MSG_DEBUG,
1866 "EAP-TEAP: Using anonymous (unauthenticated) provisioning");
1867 data->anon_provisioning = 1;
1868 } else {
1869 data->anon_provisioning = 0;
1870 }
1871 data->resuming = 0;
1872 if (eap_teap_derive_key_auth(sm, data) < 0) {
1873 wpa_printf(MSG_DEBUG,
1874 "EAP-TEAP: Could not derive keys");
1875 ret->methodState = METHOD_DONE;
1876 ret->decision = DECISION_FAIL;
1877 wpabuf_free(resp);
1878 return NULL;
1879 }
1880 }
1881
1882 if (res == 2) {
1883 /*
1884 * Application data included in the handshake message.
1885 */
1886 wpabuf_free(data->pending_phase2_req);
1887 data->pending_phase2_req = resp;
1888 resp = NULL;
1889 res = eap_teap_decrypt(sm, data, ret, id, &msg, &resp);
1890 }
1891 }
1892
1893 if (res == 1) {
1894 wpabuf_free(resp);
1895 return eap_peer_tls_build_ack(id, EAP_TYPE_TEAP,
1896 data->teap_version);
1897 }
1898
1899 #ifdef CONFIG_TESTING_OPTIONS
1900 if (data->test_outer_tlvs && res == 0 && resp &&
1901 (flags & EAP_TLS_FLAGS_START) && wpabuf_len(resp) >= 6)
1902 resp = eap_teap_add_dummy_outer_tlvs(data, resp);
1903 #endif /* CONFIG_TESTING_OPTIONS */
1904
1905 return resp;
1906 }
1907
1908
1909 #if 0 /* TODO */
1910 static Boolean eap_teap_has_reauth_data(struct eap_sm *sm, void *priv)
1911 {
1912 struct eap_teap_data *data = priv;
1913
1914 return tls_connection_established(sm->ssl_ctx, data->ssl.conn);
1915 }
1916
1917
1918 static void eap_teap_deinit_for_reauth(struct eap_sm *sm, void *priv)
1919 {
1920 struct eap_teap_data *data = priv;
1921
1922 if (data->phase2_priv && data->phase2_method &&
1923 data->phase2_method->deinit_for_reauth)
1924 data->phase2_method->deinit_for_reauth(sm, data->phase2_priv);
1925 eap_teap_clear(data);
1926 }
1927
1928
1929 static void * eap_teap_init_for_reauth(struct eap_sm *sm, void *priv)
1930 {
1931 struct eap_teap_data *data = priv;
1932
1933 if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
1934 eap_teap_deinit(sm, data);
1935 return NULL;
1936 }
1937 if (data->phase2_priv && data->phase2_method &&
1938 data->phase2_method->init_for_reauth)
1939 data->phase2_method->init_for_reauth(sm, data->phase2_priv);
1940 data->phase2_success = 0;
1941 data->inner_method_done = 0;
1942 data->result_success_done = 0;
1943 data->iresult_verified = 0;
1944 data->done_on_tx_completion = 0;
1945 data->resuming = 1;
1946 data->provisioning = 0;
1947 data->anon_provisioning = 0;
1948 data->simck_idx = 0;
1949 return priv;
1950 }
1951 #endif
1952
1953
1954 static int eap_teap_get_status(struct eap_sm *sm, void *priv, char *buf,
1955 size_t buflen, int verbose)
1956 {
1957 struct eap_teap_data *data = priv;
1958 int len, ret;
1959
1960 len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);
1961 if (data->phase2_method) {
1962 ret = os_snprintf(buf + len, buflen - len,
1963 "EAP-TEAP Phase 2 method=%s\n",
1964 data->phase2_method->name);
1965 if (os_snprintf_error(buflen - len, ret))
1966 return len;
1967 len += ret;
1968 }
1969 return len;
1970 }
1971
1972
1973 static Boolean eap_teap_isKeyAvailable(struct eap_sm *sm, void *priv)
1974 {
1975 struct eap_teap_data *data = priv;
1976
1977 return data->success;
1978 }
1979
1980
1981 static u8 * eap_teap_getKey(struct eap_sm *sm, void *priv, size_t *len)
1982 {
1983 struct eap_teap_data *data = priv;
1984 u8 *key;
1985
1986 if (!data->success)
1987 return NULL;
1988
1989 key = os_memdup(data->key_data, EAP_TEAP_KEY_LEN);
1990 if (!key)
1991 return NULL;
1992
1993 *len = EAP_TEAP_KEY_LEN;
1994
1995 return key;
1996 }
1997
1998
1999 static u8 * eap_teap_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
2000 {
2001 struct eap_teap_data *data = priv;
2002 u8 *id;
2003
2004 if (!data->success || !data->session_id)
2005 return NULL;
2006
2007 id = os_memdup(data->session_id, data->id_len);
2008 if (!id)
2009 return NULL;
2010
2011 *len = data->id_len;
2012
2013 return id;
2014 }
2015
2016
2017 static u8 * eap_teap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
2018 {
2019 struct eap_teap_data *data = priv;
2020 u8 *key;
2021
2022 if (!data->success)
2023 return NULL;
2024
2025 key = os_memdup(data->emsk, EAP_EMSK_LEN);
2026 if (!key)
2027 return NULL;
2028
2029 *len = EAP_EMSK_LEN;
2030
2031 return key;
2032 }
2033
2034
2035 int eap_peer_teap_register(void)
2036 {
2037 struct eap_method *eap;
2038
2039 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
2040 EAP_VENDOR_IETF, EAP_TYPE_TEAP, "TEAP");
2041 if (!eap)
2042 return -1;
2043
2044 eap->init = eap_teap_init;
2045 eap->deinit = eap_teap_deinit;
2046 eap->process = eap_teap_process;
2047 eap->isKeyAvailable = eap_teap_isKeyAvailable;
2048 eap->getKey = eap_teap_getKey;
2049 eap->getSessionId = eap_teap_get_session_id;
2050 eap->get_status = eap_teap_get_status;
2051 #if 0 /* TODO */
2052 eap->has_reauth_data = eap_teap_has_reauth_data;
2053 eap->deinit_for_reauth = eap_teap_deinit_for_reauth;
2054 eap->init_for_reauth = eap_teap_init_for_reauth;
2055 #endif
2056 eap->get_emsk = eap_teap_get_emsk;
2057
2058 return eap_peer_method_register(eap);
2059 }