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
,