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"
29 #define EAP_TTLS_VERSION 0
32 static void eap_ttls_reset(struct eap_sm *sm, void *priv);
35 struct eap_ttls_data {
36 struct eap_ssl_data ssl;
38 START, PHASE1, PHASE2_START, PHASE2_METHOD,
39 PHASE2_MSCHAPV2_RESP, SUCCESS, FAILURE
43 const struct eap_method *phase2_method;
46 u8 mschapv2_auth_response[20];
51 static const char * eap_ttls_state_txt(int state)
59 return "PHASE2_START";
61 return "PHASE2_METHOD";
62 case PHASE2_MSCHAPV2_RESP:
63 return "PHASE2_MSCHAPV2_RESP";
74 static void eap_ttls_state(struct eap_ttls_data *data, int state)
76 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s",
77 eap_ttls_state_txt(data->state),
78 eap_ttls_state_txt(state));
83 static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
84 int mandatory, size_t len)
86 struct ttls_avp_vendor *avp;
90 avp = (struct ttls_avp_vendor *) avphdr;
91 flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
93 flags |= AVP_FLAGS_VENDOR;
94 hdrlen = sizeof(*avp);
95 avp->vendor_id = host_to_be32(vendor_id);
97 hdrlen = sizeof(struct ttls_avp);
100 avp->avp_code = host_to_be32(avp_code);
101 avp->avp_length = host_to_be32((flags << 24) | (hdrlen + len));
103 return avphdr + hdrlen;
107 static int eap_ttls_avp_encapsulate(u8 **resp, size_t *resp_len, u32 avp_code,
112 avp = malloc(sizeof(struct ttls_avp) + *resp_len + 4);
119 pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, *resp_len);
120 memcpy(pos, *resp, *resp_len);
125 *resp_len = pos - avp;
130 struct eap_ttls_avp {
131 /* Note: eap is allocated memory; caller is responsible for freeing
132 * it. All the other pointers are pointing to the packet data, i.e.,
133 * they must not be freed separately. */
137 size_t user_name_len;
139 size_t user_password_len;
141 size_t chap_challenge_len;
143 size_t chap_password_len;
144 u8 *mschap_challenge;
145 size_t mschap_challenge_len;
147 size_t mschap_response_len;
148 u8 *mschap2_response;
149 size_t mschap2_response_len;
153 static int eap_ttls_avp_parse(u8 *buf, size_t len, struct eap_ttls_avp *parse)
155 struct ttls_avp *avp;
161 memset(parse, 0, sizeof(*parse));
164 u32 avp_code, avp_length, vendor_id = 0;
167 avp = (struct ttls_avp *) pos;
168 avp_code = be_to_host32(avp->avp_code);
169 avp_length = be_to_host32(avp->avp_length);
170 avp_flags = (avp_length >> 24) & 0xff;
171 avp_length &= 0xffffff;
172 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
173 "length=%d", (int) avp_code, avp_flags,
175 if (avp_length > left) {
176 wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
177 "(len=%d, left=%d) - dropped",
178 (int) avp_length, left);
181 dpos = (u8 *) (avp + 1);
182 dlen = avp_length - sizeof(*avp);
183 if (avp_flags & AVP_FLAGS_VENDOR) {
185 wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP "
189 vendor_id = be_to_host32(* (u32 *) dpos);
190 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
196 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
198 if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
199 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
200 if (parse->eap == NULL) {
201 parse->eap = malloc(dlen);
202 if (parse->eap == NULL) {
203 wpa_printf(MSG_WARNING, "EAP-TTLS: "
204 "failed to allocate memory "
205 "for Phase 2 EAP data");
208 memcpy(parse->eap, dpos, dlen);
209 parse->eap_len = dlen;
211 u8 *neweap = realloc(parse->eap,
212 parse->eap_len + dlen);
213 if (neweap == NULL) {
214 wpa_printf(MSG_WARNING, "EAP-TTLS: "
215 "failed to allocate memory "
216 "for Phase 2 EAP data");
221 memcpy(neweap + parse->eap_len, dpos, dlen);
223 parse->eap_len += dlen;
225 } else if (vendor_id == 0 &&
226 avp_code == RADIUS_ATTR_USER_NAME) {
227 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name",
229 parse->user_name = dpos;
230 parse->user_name_len = dlen;
231 } else if (vendor_id == 0 &&
232 avp_code == RADIUS_ATTR_USER_PASSWORD) {
234 size_t password_len = dlen;
235 while (password_len > 0 &&
236 password[password_len - 1] == '\0') {
239 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: "
240 "User-Password (PAP)",
241 password, password_len);
242 parse->user_password = password;
243 parse->user_password_len = password_len;
244 } else if (vendor_id == 0 &&
245 avp_code == RADIUS_ATTR_CHAP_CHALLENGE) {
246 wpa_hexdump(MSG_DEBUG,
247 "EAP-TTLS: CHAP-Challenge (CHAP)",
249 parse->chap_challenge = dpos;
250 parse->chap_challenge_len = dlen;
251 } else if (vendor_id == 0 &&
252 avp_code == RADIUS_ATTR_CHAP_PASSWORD) {
253 wpa_hexdump(MSG_DEBUG,
254 "EAP-TTLS: CHAP-Password (CHAP)",
256 parse->chap_password = dpos;
257 parse->chap_password_len = dlen;
258 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
259 avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) {
260 wpa_hexdump(MSG_DEBUG,
261 "EAP-TTLS: MS-CHAP-Challenge",
263 parse->mschap_challenge = dpos;
264 parse->mschap_challenge_len = dlen;
265 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
266 avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) {
267 wpa_hexdump(MSG_DEBUG,
268 "EAP-TTLS: MS-CHAP-Response (MSCHAP)",
270 parse->mschap_response = dpos;
271 parse->mschap_response_len = dlen;
272 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
273 avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) {
274 wpa_hexdump(MSG_DEBUG,
275 "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)",
277 parse->mschap2_response = dpos;
278 parse->mschap2_response_len = dlen;
279 } else if (avp_flags & AVP_FLAGS_MANDATORY) {
280 wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported "
281 "mandatory AVP code %d vendor_id %d - "
282 "dropped", (int) avp_code, (int) vendor_id);
285 wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported "
286 "AVP code %d vendor_id %d",
287 (int) avp_code, (int) vendor_id);
290 pad = (4 - (avp_length & 3)) & 3;
291 pos += avp_length + pad;
292 left -= avp_length + pad;
299 static void * eap_ttls_init(struct eap_sm *sm)
301 struct eap_ttls_data *data;
303 data = malloc(sizeof(*data));
306 memset(data, 0, sizeof(*data));
307 data->ttls_version = EAP_TTLS_VERSION;
310 if (eap_tls_ssl_init(sm, &data->ssl, 0)) {
311 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
312 eap_ttls_reset(sm, data);
320 static void eap_ttls_reset(struct eap_sm *sm, void *priv)
322 struct eap_ttls_data *data = priv;
325 if (data->phase2_priv && data->phase2_method)
326 data->phase2_method->reset(sm, data->phase2_priv);
327 eap_tls_ssl_deinit(sm, &data->ssl);
332 static u8 * eap_ttls_build_start(struct eap_sm *sm, struct eap_ttls_data *data,
333 int id, size_t *reqDataLen)
338 *reqDataLen = sizeof(*req) + 2;
339 req = malloc(*reqDataLen);
341 wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for"
343 eap_ttls_state(data, FAILURE);
347 req->code = EAP_CODE_REQUEST;
348 req->identifier = id;
349 req->length = htons(*reqDataLen);
350 pos = (u8 *) (req + 1);
351 *pos++ = EAP_TYPE_TTLS;
352 *pos = EAP_TLS_FLAGS_START | data->ttls_version;
354 eap_ttls_state(data, PHASE1);
360 static u8 * eap_ttls_build_req(struct eap_sm *sm, struct eap_ttls_data *data,
361 int id, size_t *reqDataLen)
366 res = eap_tls_buildReq_helper(sm, &data->ssl, EAP_TYPE_TTLS,
367 data->ttls_version, id, &req,
370 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
371 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, starting "
373 eap_ttls_state(data, PHASE2_START);
377 return eap_tls_build_ack(reqDataLen, id, EAP_TYPE_TTLS,
383 static u8 * eap_ttls_encrypt(struct eap_sm *sm, struct eap_ttls_data *data,
384 int id, u8 *plain, size_t plain_len,
391 /* TODO: add support for fragmentation, if needed. This will need to
392 * add TLS Message Length field, if the frame is fragmented. */
393 req = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
397 req->code = EAP_CODE_REQUEST;
398 req->identifier = id;
400 pos = (u8 *) (req + 1);
401 *pos++ = EAP_TYPE_TTLS;
402 *pos++ = data->ttls_version;
404 res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
406 pos, data->ssl.tls_out_limit);
408 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt Phase 2 "
414 *out_len = sizeof(struct eap_hdr) + 2 + res;
415 req->length = host_to_be16(*out_len);
420 static u8 * eap_ttls_build_phase2_eap_req(struct eap_sm *sm,
421 struct eap_ttls_data *data,
422 int id, size_t *reqDataLen)
428 req = data->phase2_method->buildReq(sm, data->phase2_priv, id,
433 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encapsulate Phase 2 data",
436 if (eap_ttls_avp_encapsulate(&req, &req_len, RADIUS_ATTR_EAP_MESSAGE,
438 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "
443 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated Phase "
444 "2 data", req, req_len);
446 encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
453 static u8 * eap_ttls_build_phase2_mschapv2(struct eap_sm *sm,
454 struct eap_ttls_data *data,
455 int id, size_t *reqDataLen)
457 u8 *req, *encr_req, *pos, *end;
461 pos = req = malloc(100);
466 if (data->mschapv2_resp_ok) {
467 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS,
468 RADIUS_VENDOR_ID_MICROSOFT, 1, 43);
469 *pos++ = data->mschapv2_ident;
470 pos += snprintf((char *) pos, end - pos, "S=");
471 for (i = 0; i < sizeof(data->mschapv2_auth_response); i++) {
472 pos += snprintf((char *) pos, end - pos, "%02X",
473 data->mschapv2_auth_response[i]);
476 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR,
477 RADIUS_VENDOR_ID_MICROSOFT, 1, 6);
478 memcpy(pos, "Failed", 6);
484 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 "
485 "data", req, req_len);
487 encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
494 static u8 * eap_ttls_buildReq(struct eap_sm *sm, void *priv, int id,
497 struct eap_ttls_data *data = priv;
499 switch (data->state) {
501 return eap_ttls_build_start(sm, data, id, reqDataLen);
503 return eap_ttls_build_req(sm, data, id, reqDataLen);
505 return eap_ttls_build_phase2_eap_req(sm, data, id, reqDataLen);
506 case PHASE2_MSCHAPV2_RESP:
507 return eap_ttls_build_phase2_mschapv2(sm, data, id,
510 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
511 __func__, data->state);
517 static Boolean eap_ttls_check(struct eap_sm *sm, void *priv,
518 u8 *respData, size_t respDataLen)
520 struct eap_hdr *resp;
524 resp = (struct eap_hdr *) respData;
525 pos = (u8 *) (resp + 1);
526 if (respDataLen < sizeof(*resp) + 2 || *pos != EAP_TYPE_TTLS ||
527 (len = ntohs(resp->length)) > respDataLen) {
528 wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame");
536 static void eap_ttls_process_phase2_pap(struct eap_sm *sm,
537 struct eap_ttls_data *data,
538 const u8 *user_password,
539 size_t user_password_len)
541 /* TODO: add support for verifying that the user entry accepts
543 if (!sm->user || !sm->user->password) {
544 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No user password "
546 eap_ttls_state(data, FAILURE);
550 if (sm->user->password_len != user_password_len ||
551 memcmp(sm->user->password, user_password, user_password_len) != 0)
553 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");
554 eap_ttls_state(data, FAILURE);
558 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password");
559 eap_ttls_state(data, SUCCESS);
563 static void eap_ttls_process_phase2_chap(struct eap_sm *sm,
564 struct eap_ttls_data *data,
566 size_t challenge_len,
571 u8 *chal, hash[MD5_MAC_LEN];
573 if (challenge == NULL || password == NULL ||
574 challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN ||
575 password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) {
576 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes "
577 "(challenge len %lu password len %lu)",
578 (unsigned long) challenge_len,
579 (unsigned long) password_len);
580 eap_ttls_state(data, FAILURE);
584 /* TODO: add support for verifying that the user entry accepts
586 if (!sm->user || !sm->user->password) {
587 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No user password "
589 eap_ttls_state(data, FAILURE);
593 chal = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
594 EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
596 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate "
597 "challenge from TLS data");
598 eap_ttls_state(data, FAILURE);
602 if (memcmp(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) != 0 ||
603 password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) {
604 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch");
606 eap_ttls_state(data, FAILURE);
611 /* MD5(Ident + Password + Challenge) */
613 MD5Update(&context, password, 1);
614 MD5Update(&context, sm->user->password, sm->user->password_len);
615 MD5Update(&context, challenge, challenge_len);
616 MD5Final(hash, &context);
618 if (memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) {
619 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
620 eap_ttls_state(data, SUCCESS);
622 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password");
623 eap_ttls_state(data, FAILURE);
628 static void eap_ttls_process_phase2_mschap(struct eap_sm *sm,
629 struct eap_ttls_data *data,
630 u8 *challenge, size_t challenge_len,
631 u8 *response, size_t response_len)
633 u8 *chal, nt_response[24];
635 if (challenge == NULL || response == NULL ||
636 challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN ||
637 response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) {
638 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP "
639 "attributes (challenge len %lu response len %lu)",
640 (unsigned long) challenge_len,
641 (unsigned long) response_len);
642 eap_ttls_state(data, FAILURE);
646 /* TODO: add support for verifying that the user entry accepts
647 * EAP-TTLS/MSCHAP. */
648 if (!sm->user || !sm->user->password) {
649 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password "
651 eap_ttls_state(data, FAILURE);
655 chal = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
656 EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
658 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate "
659 "challenge from TLS data");
660 eap_ttls_state(data, FAILURE);
664 if (memcmp(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) != 0 ||
665 response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {
666 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch");
668 eap_ttls_state(data, FAILURE);
673 nt_challenge_response(challenge, sm->user->password,
674 sm->user->password_len, nt_response);
676 if (memcmp(nt_response, response + 2 + 24, 24) == 0) {
677 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
678 eap_ttls_state(data, SUCCESS);
680 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response");
681 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received",
682 response + 2 + 24, 24);
683 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected",
685 eap_ttls_state(data, FAILURE);
690 static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
691 struct eap_ttls_data *data,
693 size_t challenge_len,
694 u8 *response, size_t response_len)
696 u8 *chal, *username, nt_response[24], *pos, *rx_resp, *peer_challenge,
701 if (challenge == NULL || response == NULL ||
702 challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN ||
703 response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) {
704 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 "
705 "attributes (challenge len %lu response len %lu)",
706 (unsigned long) challenge_len,
707 (unsigned long) response_len);
708 eap_ttls_state(data, FAILURE);
712 /* TODO: add support for verifying that the user entry accepts
713 * EAP-TTLS/MSCHAPV2. */
714 if (!sm->user || !sm->user->password) {
715 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password "
717 eap_ttls_state(data, FAILURE);
721 /* MSCHAPv2 does not include optional domain name in the
722 * challenge-response calculation, so remove domain prefix
724 username = sm->identity;
725 username_len = sm->identity_len;
727 for (i = 0; i < username_len; i++) {
728 if (username[i] == '\\') {
729 username_len -= i + 1;
735 chal = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
736 EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
738 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate "
739 "challenge from TLS data");
740 eap_ttls_state(data, FAILURE);
744 if (memcmp(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) != 0 ||
745 response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) {
746 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch");
748 eap_ttls_state(data, FAILURE);
753 auth_challenge = challenge;
754 peer_challenge = response + 2;
756 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User",
757 username, username_len);
758 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge",
759 auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
760 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge",
761 peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
763 generate_nt_response(auth_challenge, peer_challenge,
764 username, username_len,
765 sm->user->password, sm->user->password_len,
768 rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
769 if (memcmp(nt_response, rx_resp, 24) == 0) {
770 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
772 data->mschapv2_resp_ok = 1;
774 generate_authenticator_response(sm->user->password,
775 sm->user->password_len,
778 username, username_len,
780 data->mschapv2_auth_response);
783 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid "
785 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received",
787 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected",
789 data->mschapv2_resp_ok = 0;
791 eap_ttls_state(data, PHASE2_MSCHAPV2_RESP);
792 data->mschapv2_ident = response[0];
796 static int eap_ttls_phase2_eap_init(struct eap_sm *sm,
797 struct eap_ttls_data *data, u8 eap_type)
799 if (data->phase2_priv && data->phase2_method) {
800 data->phase2_method->reset(sm, data->phase2_priv);
801 data->phase2_method = NULL;
802 data->phase2_priv = NULL;
804 data->phase2_method = eap_sm_get_eap_methods(eap_type);
805 if (!data->phase2_method)
809 data->phase2_priv = data->phase2_method->init(sm);
815 static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm,
816 struct eap_ttls_data *data,
817 u8 *in_data, size_t in_len)
819 u8 next_type = EAP_TYPE_NONE;
824 if (data->phase2_priv == NULL) {
825 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not "
826 "initialized?!", __func__);
830 hdr = (struct eap_hdr *) in_data;
831 pos = (u8 *) (hdr + 1);
832 left = in_len - sizeof(*hdr);
834 if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
835 wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; "
836 "allowed types", pos + 1, left - 1);
837 eap_sm_process_nak(sm, pos + 1, left - 1);
838 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
839 sm->user->methods[sm->user_eap_method_index] !=
842 sm->user->methods[sm->user_eap_method_index++];
843 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d",
845 eap_ttls_phase2_eap_init(sm, data, next_type);
847 eap_ttls_state(data, FAILURE);
852 if (data->phase2_method->check(sm, data->phase2_priv, in_data,
854 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to "
855 "ignore the packet");
859 data->phase2_method->process(sm, data->phase2_priv, in_data, in_len);
861 if (!data->phase2_method->isDone(sm, data->phase2_priv))
864 if (!data->phase2_method->isSuccess(sm, data->phase2_priv)) {
865 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed");
866 eap_ttls_state(data, FAILURE);
870 switch (data->state) {
872 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
873 wpa_hexdump_ascii(MSG_DEBUG, "EAP_TTLS: Phase2 "
874 "Identity not found in the user "
876 sm->identity, sm->identity_len);
877 eap_ttls_state(data, FAILURE);
881 eap_ttls_state(data, PHASE2_METHOD);
882 next_type = sm->user->methods[0];
883 sm->user_eap_method_index = 1;
884 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type);
887 eap_ttls_state(data, SUCCESS);
892 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
893 __func__, data->state);
897 eap_ttls_phase2_eap_init(sm, data, next_type);
901 static void eap_ttls_process_phase2_eap(struct eap_sm *sm,
902 struct eap_ttls_data *data,
903 const u8 *eap, size_t eap_len)
908 if (data->state == PHASE2_START) {
909 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2");
910 if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_IDENTITY) < 0)
912 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: failed to "
913 "initialize EAP-Identity");
918 if (eap_len < sizeof(*hdr)) {
919 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: too short Phase 2 EAP "
920 "packet (len=%lu)", (unsigned long) eap_len);
924 hdr = (struct eap_hdr *) eap;
925 len = be_to_host16(hdr->length);
926 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d "
927 "identifier=%d length=%lu", hdr->code, hdr->identifier,
928 (unsigned long) len);
930 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Length mismatch in Phase 2"
931 " EAP frame (hdr len=%lu, data len in AVP=%lu)",
932 (unsigned long) len, (unsigned long) eap_len);
937 case EAP_CODE_RESPONSE:
938 eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr,
942 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in "
943 "Phase 2 EAP header", hdr->code);
949 static void eap_ttls_process_phase2(struct eap_sm *sm,
950 struct eap_ttls_data *data,
951 struct eap_hdr *resp,
952 u8 *in_data, size_t in_len)
955 int buf_len, len_decrypted, res;
956 struct eap_ttls_avp parse;
958 wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
959 " Phase 2", (unsigned long) in_len);
961 res = eap_tls_data_reassemble(sm, &data->ssl, &in_data, &in_len);
962 if (res < 0 || res == 1)
966 if (data->ssl.tls_in_total > buf_len)
967 buf_len = data->ssl.tls_in_total;
968 in_decrypted = malloc(buf_len);
969 if (in_decrypted == NULL) {
970 free(data->ssl.tls_in);
971 data->ssl.tls_in = NULL;
972 data->ssl.tls_in_len = 0;
973 wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate memory "
978 len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
980 in_decrypted, buf_len);
981 free(data->ssl.tls_in);
982 data->ssl.tls_in = NULL;
983 data->ssl.tls_in_len = 0;
984 if (len_decrypted < 0) {
985 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "
988 eap_ttls_state(data, FAILURE);
992 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP",
993 in_decrypted, len_decrypted);
995 if (eap_ttls_avp_parse(in_decrypted, len_decrypted, &parse) < 0) {
996 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs");
998 eap_ttls_state(data, FAILURE);
1002 if (parse.user_name) {
1004 sm->identity = malloc(parse.user_name_len);
1006 memcpy(sm->identity, parse.user_name,
1007 parse.user_name_len);
1008 sm->identity_len = parse.user_name_len;
1010 if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1)
1012 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not "
1013 "found in the user database");
1014 eap_ttls_state(data, FAILURE);
1020 eap_ttls_process_phase2_eap(sm, data, parse.eap,
1022 } else if (parse.user_password) {
1023 eap_ttls_process_phase2_pap(sm, data, parse.user_password,
1024 parse.user_password_len);
1025 } else if (parse.chap_password) {
1026 eap_ttls_process_phase2_chap(sm, data,
1027 parse.chap_challenge,
1028 parse.chap_challenge_len,
1029 parse.chap_password,
1030 parse.chap_password_len);
1031 } else if (parse.mschap_response) {
1032 eap_ttls_process_phase2_mschap(sm, data,
1033 parse.mschap_challenge,
1034 parse.mschap_challenge_len,
1035 parse.mschap_response,
1036 parse.mschap_response_len);
1037 } else if (parse.mschap2_response) {
1038 eap_ttls_process_phase2_mschapv2(sm, data,
1039 parse.mschap_challenge,
1040 parse.mschap_challenge_len,
1041 parse.mschap2_response,
1042 parse.mschap2_response_len);
1051 static void eap_ttls_process(struct eap_sm *sm, void *priv,
1052 u8 *respData, size_t respDataLen)
1054 struct eap_ttls_data *data = priv;
1055 struct eap_hdr *resp;
1058 unsigned int tls_msg_len;
1061 resp = (struct eap_hdr *) respData;
1062 pos = (u8 *) (resp + 1);
1065 left = htons(resp->length) - sizeof(struct eap_hdr) - 2;
1066 wpa_printf(MSG_DEBUG, "EAP-TTLS: Received packet(len=%lu) - "
1067 "Flags 0x%02x", (unsigned long) respDataLen, flags);
1068 peer_version = flags & EAP_PEAP_VERSION_MASK;
1069 if (peer_version < data->ttls_version) {
1070 wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; "
1072 peer_version, data->ttls_version, peer_version);
1073 data->ttls_version = peer_version;
1076 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
1078 wpa_printf(MSG_INFO, "EAP-TTLS: Short frame with TLS "
1080 eap_ttls_state(data, FAILURE);
1083 tls_msg_len = (pos[0] << 24) | (pos[1] << 16) | (pos[2] << 8) |
1085 wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS Message Length: %d",
1087 if (data->ssl.tls_in_left == 0) {
1088 data->ssl.tls_in_total = tls_msg_len;
1089 data->ssl.tls_in_left = tls_msg_len;
1090 free(data->ssl.tls_in);
1091 data->ssl.tls_in = NULL;
1092 data->ssl.tls_in_len = 0;
1098 switch (data->state) {
1100 if (eap_tls_process_helper(sm, &data->ssl, pos, left) < 0) {
1101 wpa_printf(MSG_INFO, "EAP-TTLS: TLS processing "
1103 eap_ttls_state(data, FAILURE);
1108 eap_ttls_process_phase2(sm, data, resp, pos, left);
1110 case PHASE2_MSCHAPV2_RESP:
1111 if (data->mschapv2_resp_ok && left == 0) {
1112 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
1113 "acknowledged response");
1114 eap_ttls_state(data, SUCCESS);
1115 } else if (!data->mschapv2_resp_ok) {
1116 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
1117 "acknowledged error");
1118 eap_ttls_state(data, FAILURE);
1120 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected "
1121 "frame from peer (payload len %d, expected "
1122 "empty frame)", left);
1123 eap_ttls_state(data, FAILURE);
1127 wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s",
1128 data->state, __func__);
1134 static Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv)
1136 struct eap_ttls_data *data = priv;
1137 return data->state == SUCCESS || data->state == FAILURE;
1141 static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
1143 struct eap_ttls_data *data = priv;
1146 if (data->state != SUCCESS)
1149 eapKeyData = eap_tls_derive_key(sm, &data->ssl,
1150 "ttls keying material",
1153 *len = EAP_TLS_KEY_LEN;
1154 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Derived key",
1155 eapKeyData, EAP_TLS_KEY_LEN);
1157 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
1164 static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv)
1166 struct eap_ttls_data *data = priv;
1167 return data->state == SUCCESS;
1171 const struct eap_method eap_method_ttls =
1173 .method = EAP_TYPE_TTLS,
1175 .init = eap_ttls_init,
1176 .reset = eap_ttls_reset,
1177 .buildReq = eap_ttls_buildReq,
1178 .check = eap_ttls_check,
1179 .process = eap_ttls_process,
1180 .isDone = eap_ttls_isDone,
1181 .getKey = eap_ttls_getKey,
1182 .isSuccess = eap_ttls_isSuccess,