eap_server_ttls.c revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / EAP-TTLS (RFC 5281) 31f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify 68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation. 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license. 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details. 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/ms_funcs.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha1.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/tls.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap_i.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap_tls_common.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_common/chap.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_common/eap_ttls.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define EAP_TTLS_VERSION 0 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_reset(struct eap_sm *sm, void *priv); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_ttls_data { 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ssl_data ssl; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt START, PHASE1, PHASE2_START, PHASE2_METHOD, 371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt PHASE2_MSCHAPV2_RESP, SUCCESS, FAILURE 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } state; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ttls_version; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_method *phase2_method; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *phase2_priv; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int mschapv2_resp_ok; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 mschapv2_auth_response[20]; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 mschapv2_ident; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *pending_phase2_eap_resp; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tnc_started; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * eap_ttls_state_txt(int state) 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (state) { 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case START: 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "START"; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE1: 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PHASE1"; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE2_START: 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PHASE2_START"; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE2_METHOD: 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PHASE2_METHOD"; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE2_MSCHAPV2_RESP: 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "PHASE2_MSCHAPV2_RESP"; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SUCCESS: 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "SUCCESS"; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case FAILURE: 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "FAILURE"; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return "Unknown?!"; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_state(struct eap_ttls_data *data, int state) 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s", 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state_txt(data->state), 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state_txt(state)); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = state; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id, 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int mandatory, size_t len) 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ttls_avp_vendor *avp; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 flags; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t hdrlen; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp = (struct ttls_avp_vendor *) avphdr; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = mandatory ? AVP_FLAGS_MANDATORY : 0; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor_id) { 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= AVP_FLAGS_VENDOR; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdrlen = sizeof(*avp); 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp->vendor_id = host_to_be32(vendor_id); 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdrlen = sizeof(struct ttls_avp); 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp->avp_code = host_to_be32(avp_code); 1011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt avp->avp_length = host_to_be32(((u32) flags << 24) | 1021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ((u32) (hdrlen + len))); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return avphdr + hdrlen; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_ttls_avp_encapsulate(struct wpabuf *resp, 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 avp_code, int mandatory) 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *avp; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(resp) + 4); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (avp == NULL) { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_ttls_avp_hdr(wpabuf_mhead(avp), avp_code, 0, mandatory, 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(resp)); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, wpabuf_head(resp), wpabuf_len(resp)); 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpabuf_len(resp); 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AVP_PAD((const u8 *) wpabuf_head(avp), pos); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(avp, pos - (u8 *) wpabuf_head(avp)); 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return avp; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_ttls_avp { 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Note: eap is allocated memory; caller is responsible for freeing 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it. All the other pointers are pointing to the packet data, i.e., 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * they must not be freed separately. */ 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *eap; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t eap_len; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *user_name; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t user_name_len; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *user_password; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t user_password_len; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *chap_challenge; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t chap_challenge_len; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *chap_password; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t chap_password_len; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *mschap_challenge; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t mschap_challenge_len; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *mschap_response; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t mschap_response_len; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *mschap2_response; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t mschap2_response_len; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_ttls_avp_parse(struct wpabuf *buf, struct eap_ttls_avp *parse) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ttls_avp *avp; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int left; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = wpabuf_mhead(buf); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = wpabuf_len(buf); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(parse, 0, sizeof(*parse)); 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (left > 0) { 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 avp_code, avp_length, vendor_id = 0; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 avp_flags, *dpos; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t pad, dlen; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp = (struct ttls_avp *) pos; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp_code = be_to_host32(avp->avp_code); 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp_length = be_to_host32(avp->avp_length); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp_flags = (avp_length >> 24) & 0xff; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp_length &= 0xffffff; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x " 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length=%d", (int) avp_code, avp_flags, 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) avp_length); 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((int) avp_length > left) { 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow " 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%d, left=%d) - dropped", 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) avp_length, left); 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (avp_length < sizeof(*avp)) { 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length " 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d", avp_length); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dpos = (u8 *) (avp + 1); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = avp_length - sizeof(*avp); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (avp_flags & AVP_FLAGS_VENDOR) { 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dlen < 4) { 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP " 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "underflow"); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vendor_id = be_to_host32(* (be32 *) dpos); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d", 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) vendor_id); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dpos += 4; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen -= 4; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) { 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message"); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (parse->eap == NULL) { 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->eap = os_malloc(dlen); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (parse->eap == NULL) { 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP-TTLS: " 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed to allocate memory " 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for Phase 2 EAP data"); 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(parse->eap, dpos, dlen); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->eap_len = dlen; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *neweap = os_realloc(parse->eap, 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->eap_len + dlen); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (neweap == NULL) { 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP-TTLS: " 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed to allocate memory " 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for Phase 2 EAP data"); 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(neweap + parse->eap_len, dpos, dlen); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->eap = neweap; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->eap_len += dlen; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (vendor_id == 0 && 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp_code == RADIUS_ATTR_USER_NAME) { 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name", 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dpos, dlen); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->user_name = dpos; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->user_name_len = dlen; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (vendor_id == 0 && 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp_code == RADIUS_ATTR_USER_PASSWORD) { 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *password = dpos; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t password_len = dlen; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (password_len > 0 && 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt password[password_len - 1] == '\0') { 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt password_len--; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: " 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "User-Password (PAP)", 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt password, password_len); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->user_password = password; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->user_password_len = password_len; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (vendor_id == 0 && 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp_code == RADIUS_ATTR_CHAP_CHALLENGE) { 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-TTLS: CHAP-Challenge (CHAP)", 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dpos, dlen); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->chap_challenge = dpos; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->chap_challenge_len = dlen; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (vendor_id == 0 && 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp_code == RADIUS_ATTR_CHAP_PASSWORD) { 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-TTLS: CHAP-Password (CHAP)", 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dpos, dlen); 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->chap_password = dpos; 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->chap_password_len = dlen; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT && 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) { 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-TTLS: MS-CHAP-Challenge", 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dpos, dlen); 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->mschap_challenge = dpos; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->mschap_challenge_len = dlen; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT && 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) { 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-TTLS: MS-CHAP-Response (MSCHAP)", 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dpos, dlen); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->mschap_response = dpos; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->mschap_response_len = dlen; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT && 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) { 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)", 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dpos, dlen); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->mschap2_response = dpos; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->mschap2_response_len = dlen; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (avp_flags & AVP_FLAGS_MANDATORY) { 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported " 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "mandatory AVP code %d vendor_id %d - " 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dropped", (int) avp_code, (int) vendor_id); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported " 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AVP code %d vendor_id %d", 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) avp_code, (int) vendor_id); 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pad = (4 - (avp_length & 3)) & 3; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += avp_length + pad; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= avp_length + pad; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(parse->eap); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse->eap = NULL; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * eap_ttls_implicit_challenge(struct eap_sm *sm, 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data, size_t len) 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return eap_server_tls_derive_key(sm, &data->ssl, "ttls challenge", 3121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt len); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void * eap_ttls_init(struct eap_sm *sm) 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = os_zalloc(sizeof(*data)); 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ttls_version = EAP_TTLS_VERSION; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = START; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_server_tls_ssl_init(sm, &data->ssl, 0)) { 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL."); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_reset(sm, data); 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_reset(struct eap_sm *sm, void *priv) 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data = priv; 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->phase2_priv && data->phase2_method) 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->phase2_method->reset(sm, data->phase2_priv); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_tls_ssl_deinit(sm, &data->ssl); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->pending_phase2_eap_resp); 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_ttls_build_start(struct eap_sm *sm, 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data, u8 id) 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1, 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_CODE_REQUEST, id); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) { 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for" 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " request"); 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->ttls_version); 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, PHASE1); 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_ttls_build_phase2_eap_req( 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *sm, struct eap_ttls_data *data, u8 id) 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf, *encr_req; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = data->phase2_method->buildReq(sm, data->phase2_priv, id); 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf_key(MSG_DEBUG, 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-TTLS/EAP: Encapsulate Phase 2 data", buf); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = eap_ttls_avp_encapsulate(buf, RADIUS_ATTR_EAP_MESSAGE, 1); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate " 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "packet"); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated " 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Phase 2 data", buf); 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr_req = eap_server_tls_encrypt(sm, &data->ssl, buf); 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return encr_req; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_ttls_build_phase2_mschapv2( 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *sm, struct eap_ttls_data *data) 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *encr_req, msgbuf; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *req, *pos, *end; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = req = os_malloc(100); 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = req + 100; 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->mschapv2_resp_ok) { 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS, 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_VENDOR_ID_MICROSOFT, 1, 43); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = data->mschapv2_ident; 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf((char *) pos, end - pos, "S="); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret >= 0 && ret < end - pos) 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpa_snprintf_hex_uppercase( 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) pos, end - pos, data->mschapv2_auth_response, 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(data->mschapv2_auth_response)); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR, 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_VENDOR_ID_MICROSOFT, 1, 6); 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, "Failed", 6); 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 6; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AVP_PAD(req, pos); 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_set(&msgbuf, req, pos - req); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 " 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data", &msgbuf); 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf); 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(req); 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return encr_req; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_ttls_buildReq(struct eap_sm *sm, void *priv, u8 id) 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data = priv; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->ssl.state == FRAG_ACK) { 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_server_tls_build_ack(id, EAP_TYPE_TTLS, 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ttls_version); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->ssl.state == WAIT_FRAG_ACK) { 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS, 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ttls_version, id); 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data->state) { 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case START: 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_ttls_build_start(sm, data, id); 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE1: 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, " 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "starting Phase2"); 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, PHASE2_START); 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE2_METHOD: 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->ssl.tls_out); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ssl.tls_out_pos = 0; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ssl.tls_out = eap_ttls_build_phase2_eap_req(sm, data, 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE2_MSCHAPV2_RESP: 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->ssl.tls_out); 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ssl.tls_out_pos = 0; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ssl.tls_out = eap_ttls_build_phase2_mschapv2(sm, data); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d", 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, data->state); 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS, 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ttls_version, id); 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_ttls_check(struct eap_sm *sm, void *priv, 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *respData) 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TTLS, respData, &len); 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL || len < 1) { 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame"); 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TRUE; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FALSE; 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_process_phase2_pap(struct eap_sm *sm, 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data, 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *user_password, 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t user_password_len) 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->user || !sm->user->password || sm->user->password_hash || 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->user->ttls_auth & EAP_TTLS_AUTH_PAP)) { 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No plaintext user " 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "password configured"); 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user->password_len != user_password_len || 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sm->user->password, user_password, user_password_len) != 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password"); 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password"); 5261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_ttls_state(data, SUCCESS); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_process_phase2_chap(struct eap_sm *sm, 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data, 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *challenge, 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t challenge_len, 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *password, 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t password_len) 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *chal, hash[CHAP_MD5_LEN]; 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (challenge == NULL || password == NULL || 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN || 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) { 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes " 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(challenge len %lu password len %lu)", 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) challenge_len, 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) password_len); 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->user || !sm->user->password || sm->user->password_hash || 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->user->ttls_auth & EAP_TTLS_AUTH_CHAP)) { 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No plaintext user " 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "password configured"); 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chal = eap_ttls_implicit_challenge(sm, data, 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_TTLS_CHAP_CHALLENGE_LEN + 1); 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (chal == NULL) { 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate " 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "challenge from TLS data"); 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) != 0 || 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) { 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch"); 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(chal); 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(chal); 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* MD5(Ident + Password + Challenge) */ 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chap_md5(password[0], sm->user->password, sm->user->password_len, 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt challenge, challenge_len, hash); 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) { 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password"); 5821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_ttls_state(data, SUCCESS); 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password"); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_process_phase2_mschap(struct eap_sm *sm, 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data, 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *challenge, size_t challenge_len, 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *response, size_t response_len) 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *chal, nt_response[24]; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (challenge == NULL || response == NULL || 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN || 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) { 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP " 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attributes (challenge len %lu response len %lu)", 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) challenge_len, 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) response_len); 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->user || !sm->user->password || 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAP)) { 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password " 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "configured"); 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chal = eap_ttls_implicit_challenge(sm, data, 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1); 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (chal == NULL) { 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate " 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "challenge from TLS data"); 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) != 0 || 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) { 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch"); 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(chal); 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(chal); 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user->password_hash) 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt challenge_response(challenge, sm->user->password, nt_response); 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nt_challenge_response(challenge, sm->user->password, 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->password_len, nt_response); 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(nt_response, response + 2 + 24, 24) == 0) { 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response"); 6421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_ttls_state(data, SUCCESS); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response"); 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received", 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt response + 2 + 24, 24); 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected", 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nt_response, 24); 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm, 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data, 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *challenge, 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t challenge_len, 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *response, size_t response_len) 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *chal, *username, nt_response[24], *rx_resp, *peer_challenge, 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *auth_challenge; 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t username_len, i; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (challenge == NULL || response == NULL || 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN || 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) { 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 " 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attributes (challenge len %lu response len %lu)", 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) challenge_len, 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) response_len); 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->user || !sm->user->password || 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAPV2)) { 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password " 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "configured"); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* MSCHAPv2 does not include optional domain name in the 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * challenge-response calculation, so remove domain prefix 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (if present). */ 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt username = sm->identity; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt username_len = sm->identity_len; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < username_len; i++) { 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (username[i] == '\\') { 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt username_len -= i + 1; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt username += i + 1; 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chal = eap_ttls_implicit_challenge( 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1); 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (chal == NULL) { 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate " 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "challenge from TLS data"); 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) != 0 || 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) { 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch"); 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(chal); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(chal); 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_challenge = challenge; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer_challenge = response + 2; 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User", 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt username, username_len); 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge", 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN); 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge", 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN); 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user->password_hash) { 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generate_nt_response_pwhash(auth_challenge, peer_challenge, 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt username, username_len, 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->password, 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nt_response); 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generate_nt_response(auth_challenge, peer_challenge, 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt username, username_len, 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->password, 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->password_len, 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nt_response); 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8; 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(nt_response, rx_resp, 24) == 0) { 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct " 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "NT-Response"); 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->mschapv2_resp_ok = 1; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user->password_hash) { 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generate_authenticator_response_pwhash( 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->password, 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer_challenge, auth_challenge, 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt username, username_len, nt_response, 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->mschapv2_auth_response); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt generate_authenticator_response( 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->password, sm->user->password_len, 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer_challenge, auth_challenge, 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt username, username_len, nt_response, 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->mschapv2_auth_response); 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid " 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "NT-Response"); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received", 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rx_resp, 24); 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected", 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nt_response, 24); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->mschapv2_resp_ok = 0; 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, PHASE2_MSCHAPV2_RESP); 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->mschapv2_ident = response[0]; 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_ttls_phase2_eap_init(struct eap_sm *sm, 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data, 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType eap_type) 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->phase2_priv && data->phase2_method) { 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->phase2_method->reset(sm, data->phase2_priv); 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->phase2_method = NULL; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->phase2_priv = NULL; 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF, 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_type); 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!data->phase2_method) 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->init_phase2 = 1; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->phase2_priv = data->phase2_method->init(sm); 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->init_phase2 = 0; 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data->phase2_priv == NULL ? -1 : 0; 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_process_phase2_eap_response(struct eap_sm *sm, 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data, 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *in_data, size_t in_len) 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 next_type = EAP_TYPE_NONE; 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_hdr *hdr; 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf buf; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_method *m = data->phase2_method; 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *priv = data->phase2_priv; 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL) { 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not " 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "initialized?!", __func__); 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct eap_hdr *) in_data; 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (u8 *) (hdr + 1); 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) { 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = in_len - sizeof(*hdr); 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; " 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "allowed types", pos + 1, left - 1); 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_process_nak(sm, pos + 1, left - 1); 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->methods[sm->user_eap_method_index].method != 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_TYPE_NONE) { 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next_type = sm->user->methods[ 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user_eap_method_index++].method; 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next_type); 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_ttls_phase2_eap_init(sm, data, next_type)) { 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to " 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "initialize EAP type %d", 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next_type); 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_set(&buf, in_data, in_len); 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m->check(sm, priv, &buf)) { 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to " 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignore the packet"); 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m->process(sm, priv, &buf); 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->method_pending == METHOD_PENDING_WAIT) { 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method is in " 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pending wait state - save decrypted response"); 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->pending_phase2_eap_resp); 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pending_phase2_eap_resp = wpabuf_dup(&buf); 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!m->isDone(sm, priv)) 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!m->isSuccess(sm, priv)) { 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed"); 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data->state) { 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE2_START: 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP_TTLS: Phase2 " 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Identity not found in the user " 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "database", 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity, sm->identity_len); 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, PHASE2_METHOD); 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next_type = sm->user->methods[0].method; 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user_eap_method_index = 1; 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type); 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_ttls_phase2_eap_init(sm, data, next_type)) { 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize " 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP type %d", next_type); 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE2_METHOD: 8851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_ttls_state(data, SUCCESS); 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case FAILURE: 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d", 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, data->state); 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_process_phase2_eap(struct eap_sm *sm, 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data, 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *eap, size_t eap_len) 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_hdr *hdr; 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state == PHASE2_START) { 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2"); 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_IDENTITY) < 0) 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: failed to " 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "initialize EAP-Identity"); 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_len < sizeof(*hdr)) { 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: too short Phase 2 EAP " 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "packet (len=%lu)", (unsigned long) eap_len); 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct eap_hdr *) eap; 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = be_to_host16(hdr->length); 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d " 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "identifier=%d length=%lu", hdr->code, hdr->identifier, 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > eap_len) { 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Length mismatch in Phase 2" 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " EAP frame (hdr len=%lu, data len in AVP=%lu)", 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, (unsigned long) eap_len); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->code) { 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_RESPONSE: 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr, 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len); 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in " 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Phase 2 EAP header", hdr->code); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_process_phase2(struct eap_sm *sm, 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data, 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *in_buf) 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *in_decrypted; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_avp parse; 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for" 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " Phase 2", (unsigned long) wpabuf_len(in_buf)); 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->pending_phase2_eap_resp) { 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 EAP response " 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "- skip decryption and use old data"); 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_process_phase2_eap( 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm, data, wpabuf_head(data->pending_phase2_eap_resp), 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(data->pending_phase2_eap_resp)); 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->pending_phase2_eap_resp); 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pending_phase2_eap_resp = NULL; 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn, 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_buf); 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (in_decrypted == NULL) { 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 " 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data"); 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP", 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_decrypted); 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_ttls_avp_parse(in_decrypted, &parse) < 0) { 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs"); 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(in_decrypted); 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (parse.user_name) { 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->identity); 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity = os_malloc(parse.user_name_len); 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->identity) { 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->identity, parse.user_name, 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.user_name_len); 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity_len = parse.user_name_len; 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1) 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt != 0) { 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not " 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "found in the user database"); 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto done; 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_TNC 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tnc_started && parse.eap == NULL) { 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: TNC started but no EAP " 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "response from peer"); 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto done; 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_TNC */ 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (parse.eap) { 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_process_phase2_eap(sm, data, parse.eap, 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.eap_len); 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (parse.user_password) { 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_process_phase2_pap(sm, data, parse.user_password, 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.user_password_len); 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (parse.chap_password) { 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_process_phase2_chap(sm, data, 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.chap_challenge, 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.chap_challenge_len, 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.chap_password, 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.chap_password_len); 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (parse.mschap_response) { 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_process_phase2_mschap(sm, data, 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.mschap_challenge, 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.mschap_challenge_len, 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.mschap_response, 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.mschap_response_len); 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (parse.mschap2_response) { 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_process_phase2_mschapv2(sm, data, 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.mschap_challenge, 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.mschap_challenge_len, 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.mschap2_response, 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt parse.mschap2_response_len); 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdone: 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(in_decrypted); 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(parse.eap); 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_start_tnc(struct eap_sm *sm, struct eap_ttls_data *data) 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_TNC 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->tnc || data->state != SUCCESS || data->tnc_started) 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: Initialize TNC"); 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_TNC)) { 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize TNC"); 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tnc_started = 1; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, PHASE2_METHOD); 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_TNC */ 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_ttls_process_version(struct eap_sm *sm, void *priv, 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int peer_version) 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data = priv; 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (peer_version < data->ttls_version) { 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; " 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "use version %d", 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt peer_version, data->ttls_version, peer_version); 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ttls_version = peer_version; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_process_msg(struct eap_sm *sm, void *priv, 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *respData) 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data = priv; 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data->state) { 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE1: 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_server_tls_phase1(sm, &data->ssl) < 0) 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE2_START: 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE2_METHOD: 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_process_phase2(sm, data, data->ssl.tls_in); 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_start_tnc(sm, data); 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case PHASE2_MSCHAPV2_RESP: 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->mschapv2_resp_ok && wpabuf_len(data->ssl.tls_in) == 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer " 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "acknowledged response"); 10971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eap_ttls_state(data, SUCCESS); 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (!data->mschapv2_resp_ok) { 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer " 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "acknowledged error"); 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected " 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame from peer (payload len %lu, " 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "expected empty frame)", 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(data->ssl.tls_in)); 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_start_tnc(sm, data); 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s", 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state, __func__); 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_ttls_process(struct eap_sm *sm, void *priv, 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *respData) 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data = priv; 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_server_tls_process(sm, &data->ssl, respData, data, 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_TYPE_TTLS, eap_ttls_process_version, 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_process_msg) < 0) 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_ttls_state(data, FAILURE); 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv) 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data = priv; 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data->state == SUCCESS || data->state == FAILURE; 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len) 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data = priv; 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *eapKeyData; 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state != SUCCESS) 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, 11471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "ttls keying material", 11481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt EAP_TLS_KEY_LEN); 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapKeyData) { 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = EAP_TLS_KEY_LEN; 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key", 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapKeyData, EAP_TLS_KEY_LEN); 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key"); 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eapKeyData; 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv) 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ttls_data *data = priv; 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data->state == SUCCESS; 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_server_ttls_register(void) 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *eap; 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS"); 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->init = eap_ttls_init; 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->reset = eap_ttls_reset; 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->buildReq = eap_ttls_buildReq; 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->check = eap_ttls_check; 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->process = eap_ttls_process; 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->isDone = eap_ttls_isDone; 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->getKey = eap_ttls_getKey; 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->isSuccess = eap_ttls_isSuccess; 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = eap_server_method_register(eap); 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_method_free(eap); 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1192