2 * hostapd / EAP-TTLS (draft-ietf-pppext-eap-ttls-05.txt)
3 * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
18 #include <netinet/in.h>
23 #include "eap_tls_common.h"
30 #define EAP_TTLS_VERSION 0
33 static void eap_ttls_reset(struct eap_sm *sm, void *priv);
36 struct eap_ttls_data {
37 struct eap_ssl_data ssl;
39 START, PHASE1, PHASE2_START, PHASE2_METHOD,
40 PHASE2_MSCHAPV2_RESP, SUCCESS, FAILURE
44 const struct eap_method *phase2_method;
47 u8 mschapv2_auth_response[20];
52 static const char * eap_ttls_state_txt(int state)
60 return "PHASE2_START";
62 return "PHASE2_METHOD";
63 case PHASE2_MSCHAPV2_RESP:
64 return "PHASE2_MSCHAPV2_RESP";
75 static void eap_ttls_state(struct eap_ttls_data *data, int state)
77 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s",
78 eap_ttls_state_txt(data->state),
79 eap_ttls_state_txt(state));
84 static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
85 int mandatory, size_t len)
87 struct ttls_avp_vendor *avp;
91 avp = (struct ttls_avp_vendor *) avphdr;
92 flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
94 flags |= AVP_FLAGS_VENDOR;
95 hdrlen = sizeof(*avp);
96 avp->vendor_id = host_to_be32(vendor_id);
98 hdrlen = sizeof(struct ttls_avp);
101 avp->avp_code = host_to_be32(avp_code);
102 avp->avp_length = host_to_be32((flags << 24) | (hdrlen + len));
104 return avphdr + hdrlen;
108 static int eap_ttls_avp_encapsulate(u8 **resp, size_t *resp_len, u32 avp_code,
113 avp = malloc(sizeof(struct ttls_avp) + *resp_len + 4);
120 pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, *resp_len);
121 memcpy(pos, *resp, *resp_len);
126 *resp_len = pos - avp;
131 struct eap_ttls_avp {
132 /* Note: eap is allocated memory; caller is responsible for freeing
133 * it. All the other pointers are pointing to the packet data, i.e.,
134 * they must not be freed separately. */
138 size_t user_name_len;
140 size_t user_password_len;
142 size_t chap_challenge_len;
144 size_t chap_password_len;
145 u8 *mschap_challenge;
146 size_t mschap_challenge_len;
148 size_t mschap_response_len;
149 u8 *mschap2_response;
150 size_t mschap2_response_len;
154 static int eap_ttls_avp_parse(u8 *buf, size_t len, struct eap_ttls_avp *parse)
156 struct ttls_avp *avp;
162 memset(parse, 0, sizeof(*parse));
165 u32 avp_code, avp_length, vendor_id = 0;
168 avp = (struct ttls_avp *) pos;
169 avp_code = be_to_host32(avp->avp_code);
170 avp_length = be_to_host32(avp->avp_length);
171 avp_flags = (avp_length >> 24) & 0xff;
172 avp_length &= 0xffffff;
173 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
174 "length=%d", (int) avp_code, avp_flags,
176 if (avp_length > left) {
177 wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
178 "(len=%d, left=%d) - dropped",
179 (int) avp_length, left);
182 dpos = (u8 *) (avp + 1);
183 dlen = avp_length - sizeof(*avp);
184 if (avp_flags & AVP_FLAGS_VENDOR) {
186 wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP "
190 vendor_id = be_to_host32(* (u32 *) dpos);
191 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
197 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
199 if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
200 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
201 if (parse->eap == NULL) {
202 parse->eap = malloc(dlen);
203 if (parse->eap == NULL) {
204 wpa_printf(MSG_WARNING, "EAP-TTLS: "
205 "failed to allocate memory "
206 "for Phase 2 EAP data");
209 memcpy(parse->eap, dpos, dlen);
210 parse->eap_len = dlen;
212 u8 *neweap = realloc(parse->eap,
213 parse->eap_len + dlen);
214 if (neweap == NULL) {
215 wpa_printf(MSG_WARNING, "EAP-TTLS: "
216 "failed to allocate memory "
217 "for Phase 2 EAP data");
222 memcpy(neweap + parse->eap_len, dpos, dlen);
224 parse->eap_len += dlen;
226 } else if (vendor_id == 0 &&
227 avp_code == RADIUS_ATTR_USER_NAME) {
228 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name",
230 parse->user_name = dpos;
231 parse->user_name_len = dlen;
232 } else if (vendor_id == 0 &&
233 avp_code == RADIUS_ATTR_USER_PASSWORD) {
235 size_t password_len = dlen;
236 while (password_len > 0 &&
237 password[password_len - 1] == '\0') {
240 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: "
241 "User-Password (PAP)",
242 password, password_len);
243 parse->user_password = password;
244 parse->user_password_len = password_len;
245 } else if (vendor_id == 0 &&
246 avp_code == RADIUS_ATTR_CHAP_CHALLENGE) {
247 wpa_hexdump(MSG_DEBUG,
248 "EAP-TTLS: CHAP-Challenge (CHAP)",
250 parse->chap_challenge = dpos;
251 parse->chap_challenge_len = dlen;
252 } else if (vendor_id == 0 &&
253 avp_code == RADIUS_ATTR_CHAP_PASSWORD) {
254 wpa_hexdump(MSG_DEBUG,
255 "EAP-TTLS: CHAP-Password (CHAP)",
257 parse->chap_password = dpos;
258 parse->chap_password_len = dlen;
259 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
260 avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) {
261 wpa_hexdump(MSG_DEBUG,
262 "EAP-TTLS: MS-CHAP-Challenge",
264 parse->mschap_challenge = dpos;
265 parse->mschap_challenge_len = dlen;
266 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
267 avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) {
268 wpa_hexdump(MSG_DEBUG,
269 "EAP-TTLS: MS-CHAP-Response (MSCHAP)",
271 parse->mschap_response = dpos;
272 parse->mschap_response_len = dlen;
273 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
274 avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) {
275 wpa_hexdump(MSG_DEBUG,
276 "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)",
278 parse->mschap2_response = dpos;
279 parse->mschap2_response_len = dlen;
280 } else if (avp_flags & AVP_FLAGS_MANDATORY) {
281 wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported "
282 "mandatory AVP code %d vendor_id %d - "
283 "dropped", (int) avp_code, (int) vendor_id);
286 wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported "
287 "AVP code %d vendor_id %d",
288 (int) avp_code, (int) vendor_id);
291 pad = (4 - (avp_length & 3)) & 3;
292 pos += avp_length + pad;
293 left -= avp_length + pad;
300 static void * eap_ttls_init(struct eap_sm *sm)
302 struct eap_ttls_data *data;
304 data = malloc(sizeof(*data));
307 memset(data, 0, sizeof(*data));
308 data->ttls_version = EAP_TTLS_VERSION;
311 if (eap_tls_ssl_init(sm, &data->ssl, 0)) {
312 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
313 eap_ttls_reset(sm, data);
321 static void eap_ttls_reset(struct eap_sm *sm, void *priv)
323 struct eap_ttls_data *data = priv;
326 if (data->phase2_priv && data->phase2_method)
327 data->phase2_method->reset(sm, data->phase2_priv);
328 eap_tls_ssl_deinit(sm, &data->ssl);
333 static u8 * eap_ttls_build_start(struct eap_sm *sm, struct eap_ttls_data *data,
334 int id, size_t *reqDataLen)
339 *reqDataLen = sizeof(*req) + 2;
340 req = malloc(*reqDataLen);
342 wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for"
344 eap_ttls_state(data, FAILURE);
348 req->code = EAP_CODE_REQUEST;
349 req->identifier = id;
350 req->length = htons(*reqDataLen);
351 pos = (u8 *) (req + 1);
352 *pos++ = EAP_TYPE_TTLS;
353 *pos = EAP_TLS_FLAGS_START | data->ttls_version;
355 eap_ttls_state(data, PHASE1);
361 static u8 * eap_ttls_build_req(struct eap_sm *sm, struct eap_ttls_data *data,
362 int id, size_t *reqDataLen)
367 res = eap_tls_buildReq_helper(sm, &data->ssl, EAP_TYPE_TTLS,
368 data->ttls_version, id, &req,
371 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
372 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, starting "
374 eap_ttls_state(data, PHASE2_START);
378 return eap_tls_build_ack(reqDataLen, id, EAP_TYPE_TTLS,
384 static u8 * eap_ttls_encrypt(struct eap_sm *sm, struct eap_ttls_data *data,
385 int id, u8 *plain, size_t plain_len,
392 /* TODO: add support for fragmentation, if needed. This will need to
393 * add TLS Message Length field, if the frame is fragmented. */
394 req = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
398 req->code = EAP_CODE_REQUEST;
399 req->identifier = id;
401 pos = (u8 *) (req + 1);
402 *pos++ = EAP_TYPE_TTLS;
403 *pos++ = data->ttls_version;
405 res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
407 pos, data->ssl.tls_out_limit);
409 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt Phase 2 "
415 *out_len = sizeof(struct eap_hdr) + 2 + res;
416 req->length = host_to_be16(*out_len);
421 static u8 * eap_ttls_build_phase2_eap_req(struct eap_sm *sm,
422 struct eap_ttls_data *data,
423 int id, size_t *reqDataLen)
429 req = data->phase2_method->buildReq(sm, data->phase2_priv, id,
434 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encapsulate Phase 2 data",
437 if (eap_ttls_avp_encapsulate(&req, &req_len, RADIUS_ATTR_EAP_MESSAGE,
439 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "
444 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated Phase "
445 "2 data", req, req_len);
447 encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
454 static u8 * eap_ttls_build_phase2_mschapv2(struct eap_sm *sm,
455 struct eap_ttls_data *data,
456 int id, size_t *reqDataLen)
458 u8 *req, *encr_req, *pos, *end;
462 pos = req = malloc(100);
467 if (data->mschapv2_resp_ok) {
468 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS,
469 RADIUS_VENDOR_ID_MICROSOFT, 1, 43);
470 *pos++ = data->mschapv2_ident;
471 pos += snprintf((char *) pos, end - pos, "S=");
472 for (i = 0; i < sizeof(data->mschapv2_auth_response); i++) {
473 pos += snprintf((char *) pos, end - pos, "%02X",
474 data->mschapv2_auth_response[i]);
477 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR,
478 RADIUS_VENDOR_ID_MICROSOFT, 1, 6);
479 memcpy(pos, "Failed", 6);
485 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 "
486 "data", req, req_len);
488 encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
495 static u8 * eap_ttls_buildReq(struct eap_sm *sm, void *priv, int id,
498 struct eap_ttls_data *data = priv;
500 switch (data->state) {
502 return eap_ttls_build_start(sm, data, id, reqDataLen);
504 return eap_ttls_build_req(sm, data, id, reqDataLen);
506 return eap_ttls_build_phase2_eap_req(sm, data, id, reqDataLen);
507 case PHASE2_MSCHAPV2_RESP:
508 return eap_ttls_build_phase2_mschapv2(sm, data, id,
511 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
512 __func__, data->state);
518 static Boolean eap_ttls_check(struct eap_sm *sm, void *priv,
519 u8 *respData, size_t respDataLen)
521 struct eap_hdr *resp;
525 resp = (struct eap_hdr *) respData;
526 pos = (u8 *) (resp + 1);
527 if (respDataLen < sizeof(*resp) + 2 || *pos != EAP_TYPE_TTLS ||
528 (len = ntohs(resp->length)) > respDataLen) {
529 wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame");
537 static void eap_ttls_process_phase2_pap(struct eap_sm *sm,
538 struct eap_ttls_data *data,
539 const u8 *user_password,
540 size_t user_password_len)
542 /* TODO: add support for verifying that the user entry accepts
544 if (!sm->user || !sm->user->password) {
545 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No user password "
547 eap_ttls_state(data, FAILURE);
551 if (sm->user->password_len != user_password_len ||
552 memcmp(sm->user->password, user_password, user_password_len) != 0)
554 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");
555 eap_ttls_state(data, FAILURE);
559 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password");
560 eap_ttls_state(data, SUCCESS);
564 static void eap_ttls_process_phase2_chap(struct eap_sm *sm,
565 struct eap_ttls_data *data,
567 size_t challenge_len,
571 u8 *chal, hash[MD5_MAC_LEN];
575 if (challenge == NULL || password == NULL ||
576 challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN ||
577 password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) {
578 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes "
579 "(challenge len %lu password len %lu)",
580 (unsigned long) challenge_len,
581 (unsigned long) password_len);
582 eap_ttls_state(data, FAILURE);
586 /* TODO: add support for verifying that the user entry accepts
588 if (!sm->user || !sm->user->password) {
589 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No user password "
591 eap_ttls_state(data, FAILURE);
595 chal = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
596 EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
598 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate "
599 "challenge from TLS data");
600 eap_ttls_state(data, FAILURE);
604 if (memcmp(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) != 0 ||
605 password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) {
606 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch");
608 eap_ttls_state(data, FAILURE);
613 /* MD5(Ident + Password + Challenge) */
616 addr[1] = sm->user->password;
617 len[1] = sm->user->password_len;
619 len[2] = challenge_len;
620 md5_vector(3, addr, len, hash);
622 if (memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) {
623 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
624 eap_ttls_state(data, SUCCESS);
626 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password");
627 eap_ttls_state(data, FAILURE);
632 static void eap_ttls_process_phase2_mschap(struct eap_sm *sm,
633 struct eap_ttls_data *data,
634 u8 *challenge, size_t challenge_len,
635 u8 *response, size_t response_len)
637 u8 *chal, nt_response[24];
639 if (challenge == NULL || response == NULL ||
640 challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN ||
641 response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) {
642 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP "
643 "attributes (challenge len %lu response len %lu)",
644 (unsigned long) challenge_len,
645 (unsigned long) response_len);
646 eap_ttls_state(data, FAILURE);
650 /* TODO: add support for verifying that the user entry accepts
651 * EAP-TTLS/MSCHAP. */
652 if (!sm->user || !sm->user->password) {
653 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password "
655 eap_ttls_state(data, FAILURE);
659 chal = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
660 EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
662 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate "
663 "challenge from TLS data");
664 eap_ttls_state(data, FAILURE);
668 if (memcmp(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) != 0 ||
669 response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {
670 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch");
672 eap_ttls_state(data, FAILURE);
677 nt_challenge_response(challenge, sm->user->password,
678 sm->user->password_len, nt_response);
680 if (memcmp(nt_response, response + 2 + 24, 24) == 0) {
681 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
682 eap_ttls_state(data, SUCCESS);
684 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response");
685 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received",
686 response + 2 + 24, 24);
687 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected",
689 eap_ttls_state(data, FAILURE);
694 static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
695 struct eap_ttls_data *data,
697 size_t challenge_len,
698 u8 *response, size_t response_len)
700 u8 *chal, *username, nt_response[24], *pos, *rx_resp, *peer_challenge,
705 if (challenge == NULL || response == NULL ||
706 challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN ||
707 response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) {
708 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 "
709 "attributes (challenge len %lu response len %lu)",
710 (unsigned long) challenge_len,
711 (unsigned long) response_len);
712 eap_ttls_state(data, FAILURE);
716 /* TODO: add support for verifying that the user entry accepts
717 * EAP-TTLS/MSCHAPV2. */
718 if (!sm->user || !sm->user->password) {
719 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password "
721 eap_ttls_state(data, FAILURE);
725 /* MSCHAPv2 does not include optional domain name in the
726 * challenge-response calculation, so remove domain prefix
728 username = sm->identity;
729 username_len = sm->identity_len;
731 for (i = 0; i < username_len; i++) {
732 if (username[i] == '\\') {
733 username_len -= i + 1;
739 chal = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
740 EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
742 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate "
743 "challenge from TLS data");
744 eap_ttls_state(data, FAILURE);
748 if (memcmp(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) != 0 ||
749 response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) {
750 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch");
752 eap_ttls_state(data, FAILURE);
757 auth_challenge = challenge;
758 peer_challenge = response + 2;
760 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User",
761 username, username_len);
762 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge",
763 auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
764 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge",
765 peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
767 generate_nt_response(auth_challenge, peer_challenge,
768 username, username_len,
769 sm->user->password, sm->user->password_len,
772 rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
773 if (memcmp(nt_response, rx_resp, 24) == 0) {
774 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
776 data->mschapv2_resp_ok = 1;
778 generate_authenticator_response(sm->user->password,
779 sm->user->password_len,
782 username, username_len,
784 data->mschapv2_auth_response);
787 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid "
789 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received",
791 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected",
793 data->mschapv2_resp_ok = 0;
795 eap_ttls_state(data, PHASE2_MSCHAPV2_RESP);
796 data->mschapv2_ident = response[0];
800 static int eap_ttls_phase2_eap_init(struct eap_sm *sm,
801 struct eap_ttls_data *data, u8 eap_type)
803 if (data->phase2_priv && data->phase2_method) {
804 data->phase2_method->reset(sm, data->phase2_priv);
805 data->phase2_method = NULL;
806 data->phase2_priv = NULL;
808 data->phase2_method = eap_sm_get_eap_methods(eap_type);
809 if (!data->phase2_method)
813 data->phase2_priv = data->phase2_method->init(sm);
819 static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm,
820 struct eap_ttls_data *data,
821 u8 *in_data, size_t in_len)
823 u8 next_type = EAP_TYPE_NONE;
828 if (data->phase2_priv == NULL) {
829 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not "
830 "initialized?!", __func__);
834 hdr = (struct eap_hdr *) in_data;
835 pos = (u8 *) (hdr + 1);
836 left = in_len - sizeof(*hdr);
838 if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
839 wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; "
840 "allowed types", pos + 1, left - 1);
841 eap_sm_process_nak(sm, pos + 1, left - 1);
842 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
843 sm->user->methods[sm->user_eap_method_index] !=
846 sm->user->methods[sm->user_eap_method_index++];
847 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d",
849 eap_ttls_phase2_eap_init(sm, data, next_type);
851 eap_ttls_state(data, FAILURE);
856 if (data->phase2_method->check(sm, data->phase2_priv, in_data,
858 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to "
859 "ignore the packet");
863 data->phase2_method->process(sm, data->phase2_priv, in_data, in_len);
865 if (!data->phase2_method->isDone(sm, data->phase2_priv))
868 if (!data->phase2_method->isSuccess(sm, data->phase2_priv)) {
869 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed");
870 eap_ttls_state(data, FAILURE);
874 switch (data->state) {
876 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
877 wpa_hexdump_ascii(MSG_DEBUG, "EAP_TTLS: Phase2 "
878 "Identity not found in the user "
880 sm->identity, sm->identity_len);
881 eap_ttls_state(data, FAILURE);
885 eap_ttls_state(data, PHASE2_METHOD);
886 next_type = sm->user->methods[0];
887 sm->user_eap_method_index = 1;
888 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type);
891 eap_ttls_state(data, SUCCESS);
896 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
897 __func__, data->state);
901 eap_ttls_phase2_eap_init(sm, data, next_type);
905 static void eap_ttls_process_phase2_eap(struct eap_sm *sm,
906 struct eap_ttls_data *data,
907 const u8 *eap, size_t eap_len)
912 if (data->state == PHASE2_START) {
913 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2");
914 if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_IDENTITY) < 0)
916 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: failed to "
917 "initialize EAP-Identity");
922 if (eap_len < sizeof(*hdr)) {
923 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: too short Phase 2 EAP "
924 "packet (len=%lu)", (unsigned long) eap_len);
928 hdr = (struct eap_hdr *) eap;
929 len = be_to_host16(hdr->length);
930 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d "
931 "identifier=%d length=%lu", hdr->code, hdr->identifier,
932 (unsigned long) len);
934 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Length mismatch in Phase 2"
935 " EAP frame (hdr len=%lu, data len in AVP=%lu)",
936 (unsigned long) len, (unsigned long) eap_len);
941 case EAP_CODE_RESPONSE:
942 eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr,
946 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in "
947 "Phase 2 EAP header", hdr->code);
953 static void eap_ttls_process_phase2(struct eap_sm *sm,
954 struct eap_ttls_data *data,
955 struct eap_hdr *resp,
956 u8 *in_data, size_t in_len)
959 int buf_len, len_decrypted, res;
960 struct eap_ttls_avp parse;
962 wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
963 " Phase 2", (unsigned long) in_len);
965 res = eap_tls_data_reassemble(sm, &data->ssl, &in_data, &in_len);
966 if (res < 0 || res == 1)
970 if (data->ssl.tls_in_total > buf_len)
971 buf_len = data->ssl.tls_in_total;
972 in_decrypted = malloc(buf_len);
973 if (in_decrypted == NULL) {
974 free(data->ssl.tls_in);
975 data->ssl.tls_in = NULL;
976 data->ssl.tls_in_len = 0;
977 wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate memory "
982 len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
984 in_decrypted, buf_len);
985 free(data->ssl.tls_in);
986 data->ssl.tls_in = NULL;
987 data->ssl.tls_in_len = 0;
988 if (len_decrypted < 0) {
989 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "
992 eap_ttls_state(data, FAILURE);
996 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP",
997 in_decrypted, len_decrypted);
999 if (eap_ttls_avp_parse(in_decrypted, len_decrypted, &parse) < 0) {
1000 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs");
1002 eap_ttls_state(data, FAILURE);
1006 if (parse.user_name) {
1008 sm->identity = malloc(parse.user_name_len);
1010 memcpy(sm->identity, parse.user_name,
1011 parse.user_name_len);
1012 sm->identity_len = parse.user_name_len;
1014 if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1)
1016 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not "
1017 "found in the user database");
1018 eap_ttls_state(data, FAILURE);
1024 eap_ttls_process_phase2_eap(sm, data, parse.eap,
1026 } else if (parse.user_password) {
1027 eap_ttls_process_phase2_pap(sm, data, parse.user_password,
1028 parse.user_password_len);
1029 } else if (parse.chap_password) {
1030 eap_ttls_process_phase2_chap(sm, data,
1031 parse.chap_challenge,
1032 parse.chap_challenge_len,
1033 parse.chap_password,
1034 parse.chap_password_len);
1035 } else if (parse.mschap_response) {
1036 eap_ttls_process_phase2_mschap(sm, data,
1037 parse.mschap_challenge,
1038 parse.mschap_challenge_len,
1039 parse.mschap_response,
1040 parse.mschap_response_len);
1041 } else if (parse.mschap2_response) {
1042 eap_ttls_process_phase2_mschapv2(sm, data,
1043 parse.mschap_challenge,
1044 parse.mschap_challenge_len,
1045 parse.mschap2_response,
1046 parse.mschap2_response_len);
1055 static void eap_ttls_process(struct eap_sm *sm, void *priv,
1056 u8 *respData, size_t respDataLen)
1058 struct eap_ttls_data *data = priv;
1059 struct eap_hdr *resp;
1062 unsigned int tls_msg_len;
1065 resp = (struct eap_hdr *) respData;
1066 pos = (u8 *) (resp + 1);
1069 left = htons(resp->length) - sizeof(struct eap_hdr) - 2;
1070 wpa_printf(MSG_DEBUG, "EAP-TTLS: Received packet(len=%lu) - "
1071 "Flags 0x%02x", (unsigned long) respDataLen, flags);
1072 peer_version = flags & EAP_PEAP_VERSION_MASK;
1073 if (peer_version < data->ttls_version) {
1074 wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; "
1076 peer_version, data->ttls_version, peer_version);
1077 data->ttls_version = peer_version;
1080 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
1082 wpa_printf(MSG_INFO, "EAP-TTLS: Short frame with TLS "
1084 eap_ttls_state(data, FAILURE);
1087 tls_msg_len = (pos[0] << 24) | (pos[1] << 16) | (pos[2] << 8) |
1089 wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS Message Length: %d",
1091 if (data->ssl.tls_in_left == 0) {
1092 data->ssl.tls_in_total = tls_msg_len;
1093 data->ssl.tls_in_left = tls_msg_len;
1094 free(data->ssl.tls_in);
1095 data->ssl.tls_in = NULL;
1096 data->ssl.tls_in_len = 0;
1102 switch (data->state) {
1104 if (eap_tls_process_helper(sm, &data->ssl, pos, left) < 0) {
1105 wpa_printf(MSG_INFO, "EAP-TTLS: TLS processing "
1107 eap_ttls_state(data, FAILURE);
1112 eap_ttls_process_phase2(sm, data, resp, pos, left);
1114 case PHASE2_MSCHAPV2_RESP:
1115 if (data->mschapv2_resp_ok && left == 0) {
1116 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
1117 "acknowledged response");
1118 eap_ttls_state(data, SUCCESS);
1119 } else if (!data->mschapv2_resp_ok) {
1120 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
1121 "acknowledged error");
1122 eap_ttls_state(data, FAILURE);
1124 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected "
1125 "frame from peer (payload len %d, expected "
1126 "empty frame)", left);
1127 eap_ttls_state(data, FAILURE);
1131 wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s",
1132 data->state, __func__);
1136 if (tls_connection_get_write_alerts(sm->ssl_ctx, data->ssl.conn) > 1) {
1137 wpa_printf(MSG_INFO, "EAP-TTLS: Locally detected fatal error "
1138 "in TLS processing");
1139 eap_ttls_state(data, FAILURE);
1144 static Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv)
1146 struct eap_ttls_data *data = priv;
1147 return data->state == SUCCESS || data->state == FAILURE;
1151 static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
1153 struct eap_ttls_data *data = priv;
1156 if (data->state != SUCCESS)
1159 eapKeyData = eap_tls_derive_key(sm, &data->ssl,
1160 "ttls keying material",
1163 *len = EAP_TLS_KEY_LEN;
1164 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Derived key",
1165 eapKeyData, EAP_TLS_KEY_LEN);
1167 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
1174 static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv)
1176 struct eap_ttls_data *data = priv;
1177 return data->state == SUCCESS;
1181 const struct eap_method eap_method_ttls =
1183 .method = EAP_TYPE_TTLS,
1185 .init = eap_ttls_init,
1186 .reset = eap_ttls_reset,
1187 .buildReq = eap_ttls_buildReq,
1188 .check = eap_ttls_check,
1189 .process = eap_ttls_process,
1190 .isDone = eap_ttls_isDone,
1191 .getKey = eap_ttls_getKey,
1192 .isSuccess = eap_ttls_isSuccess,