eap_server_ttls.c revision 281806
1204076Spjd/* 2204076Spjd * hostapd / EAP-TTLS (RFC 5281) 3218041Spjd * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> 4204076Spjd * 5204076Spjd * This software may be distributed under the terms of the BSD license. 6204076Spjd * See README for more details. 7204076Spjd */ 8204076Spjd 9204076Spjd#include "includes.h" 10204076Spjd 11204076Spjd#include "common.h" 12204076Spjd#include "crypto/ms_funcs.h" 13204076Spjd#include "crypto/sha1.h" 14204076Spjd#include "crypto/tls.h" 15204076Spjd#include "eap_server/eap_i.h" 16204076Spjd#include "eap_server/eap_tls_common.h" 17204076Spjd#include "eap_common/chap.h" 18204076Spjd#include "eap_common/eap_ttls.h" 19204076Spjd 20204076Spjd 21204076Spjd#define EAP_TTLS_VERSION 0 22204076Spjd 23204076Spjd 24204076Spjdstatic void eap_ttls_reset(struct eap_sm *sm, void *priv); 25204076Spjd 26204076Spjd 27204076Spjdstruct eap_ttls_data { 28204076Spjd struct eap_ssl_data ssl; 29204076Spjd enum { 30204076Spjd START, PHASE1, PHASE2_START, PHASE2_METHOD, 31204076Spjd PHASE2_MSCHAPV2_RESP, SUCCESS, FAILURE 32204076Spjd } state; 33204076Spjd 34204076Spjd int ttls_version; 35204076Spjd const struct eap_method *phase2_method; 36204076Spjd void *phase2_priv; 37204076Spjd int mschapv2_resp_ok; 38204076Spjd u8 mschapv2_auth_response[20]; 39204076Spjd u8 mschapv2_ident; 40204076Spjd struct wpabuf *pending_phase2_eap_resp; 41204076Spjd int tnc_started; 42204076Spjd}; 43204076Spjd 44204076Spjd 45204076Spjdstatic const char * eap_ttls_state_txt(int state) 46204076Spjd{ 47204076Spjd switch (state) { 48204076Spjd case START: 49204076Spjd return "START"; 50204076Spjd case PHASE1: 51204076Spjd return "PHASE1"; 52204076Spjd case PHASE2_START: 53204076Spjd return "PHASE2_START"; 54204076Spjd case PHASE2_METHOD: 55212038Spjd return "PHASE2_METHOD"; 56204076Spjd case PHASE2_MSCHAPV2_RESP: 57204076Spjd return "PHASE2_MSCHAPV2_RESP"; 58204076Spjd case SUCCESS: 59211977Spjd return "SUCCESS"; 60204076Spjd case FAILURE: 61204076Spjd return "FAILURE"; 62204076Spjd default: 63210886Spjd return "Unknown?!"; 64204076Spjd } 65204076Spjd} 66204076Spjd 67204076Spjd 68204076Spjdstatic void eap_ttls_state(struct eap_ttls_data *data, int state) 69204076Spjd{ 70204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s", 71211977Spjd eap_ttls_state_txt(data->state), 72213430Spjd eap_ttls_state_txt(state)); 73211977Spjd data->state = state; 74204076Spjd} 75204076Spjd 76204076Spjd 77204076Spjdstatic u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id, 78204076Spjd int mandatory, size_t len) 79204076Spjd{ 80204076Spjd struct ttls_avp_vendor *avp; 81204076Spjd u8 flags; 82204076Spjd size_t hdrlen; 83204076Spjd 84204076Spjd avp = (struct ttls_avp_vendor *) avphdr; 85204076Spjd flags = mandatory ? AVP_FLAGS_MANDATORY : 0; 86204076Spjd if (vendor_id) { 87204076Spjd flags |= AVP_FLAGS_VENDOR; 88204076Spjd hdrlen = sizeof(*avp); 89204076Spjd avp->vendor_id = host_to_be32(vendor_id); 90204076Spjd } else { 91204076Spjd hdrlen = sizeof(struct ttls_avp); 92204076Spjd } 93204076Spjd 94204076Spjd avp->avp_code = host_to_be32(avp_code); 95204076Spjd avp->avp_length = host_to_be32(((u32) flags << 24) | 96218041Spjd ((u32) (hdrlen + len))); 97218041Spjd 98218041Spjd return avphdr + hdrlen; 99218041Spjd} 100218041Spjd 101218041Spjd 102218041Spjdstatic struct wpabuf * eap_ttls_avp_encapsulate(struct wpabuf *resp, 103218041Spjd u32 avp_code, int mandatory) 104218041Spjd{ 105218041Spjd struct wpabuf *avp; 106218041Spjd u8 *pos; 107218041Spjd 108218041Spjd avp = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(resp) + 4); 109218041Spjd if (avp == NULL) { 110218041Spjd wpabuf_free(resp); 111218041Spjd return NULL; 112218041Spjd } 113218041Spjd 114218041Spjd pos = eap_ttls_avp_hdr(wpabuf_mhead(avp), avp_code, 0, mandatory, 115218041Spjd wpabuf_len(resp)); 116218041Spjd os_memcpy(pos, wpabuf_head(resp), wpabuf_len(resp)); 117218041Spjd pos += wpabuf_len(resp); 118218041Spjd AVP_PAD((const u8 *) wpabuf_head(avp), pos); 119218041Spjd wpabuf_free(resp); 120218041Spjd wpabuf_put(avp, pos - (u8 *) wpabuf_head(avp)); 121218041Spjd return avp; 122204076Spjd} 123207372Spjd 124207372Spjd 125207372Spjdstruct eap_ttls_avp { 126207372Spjd /* Note: eap is allocated memory; caller is responsible for freeing 127207372Spjd * it. All the other pointers are pointing to the packet data, i.e., 128207372Spjd * they must not be freed separately. */ 129207372Spjd u8 *eap; 130207372Spjd size_t eap_len; 131207372Spjd u8 *user_name; 132207372Spjd size_t user_name_len; 133207372Spjd u8 *user_password; 134207372Spjd size_t user_password_len; 135207372Spjd u8 *chap_challenge; 136207372Spjd size_t chap_challenge_len; 137207372Spjd u8 *chap_password; 138207372Spjd size_t chap_password_len; 139204076Spjd u8 *mschap_challenge; 140204076Spjd size_t mschap_challenge_len; 141204076Spjd u8 *mschap_response; 142204076Spjd size_t mschap_response_len; 143204076Spjd u8 *mschap2_response; 144204076Spjd size_t mschap2_response_len; 145204076Spjd}; 146204076Spjd 147204076Spjd 148204076Spjdstatic int eap_ttls_avp_parse(struct wpabuf *buf, struct eap_ttls_avp *parse) 149204076Spjd{ 150204076Spjd struct ttls_avp *avp; 151204076Spjd u8 *pos; 152204076Spjd int left; 153204076Spjd 154211977Spjd pos = wpabuf_mhead(buf); 155211977Spjd left = wpabuf_len(buf); 156204076Spjd os_memset(parse, 0, sizeof(*parse)); 157211977Spjd 158204076Spjd while (left > 0) { 159204076Spjd u32 avp_code, avp_length, vendor_id = 0; 160204076Spjd u8 avp_flags, *dpos; 161204076Spjd size_t pad, dlen; 162207372Spjd avp = (struct ttls_avp *) pos; 163213006Spjd avp_code = be_to_host32(avp->avp_code); 164204076Spjd avp_length = be_to_host32(avp->avp_length); 165207372Spjd avp_flags = (avp_length >> 24) & 0xff; 166207372Spjd avp_length &= 0xffffff; 167207372Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x " 168207372Spjd "length=%d", (int) avp_code, avp_flags, 169207372Spjd (int) avp_length); 170207372Spjd if ((int) avp_length > left) { 171207372Spjd wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow " 172207348Spjd "(len=%d, left=%d) - dropped", 173207348Spjd (int) avp_length, left); 174207348Spjd goto fail; 175207348Spjd } 176207348Spjd if (avp_length < sizeof(*avp)) { 177207348Spjd wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length " 178207348Spjd "%d", avp_length); 179207348Spjd goto fail; 180204076Spjd } 181204076Spjd dpos = (u8 *) (avp + 1); 182204076Spjd dlen = avp_length - sizeof(*avp); 183204076Spjd if (avp_flags & AVP_FLAGS_VENDOR) { 184204076Spjd if (dlen < 4) { 185210886Spjd wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP " 186210886Spjd "underflow"); 187210886Spjd goto fail; 188210886Spjd } 189210886Spjd vendor_id = be_to_host32(* (be32 *) dpos); 190210886Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d", 191210886Spjd (int) vendor_id); 192210886Spjd dpos += 4; 193210886Spjd dlen -= 4; 194210886Spjd } 195210886Spjd 196210886Spjd wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen); 197210886Spjd 198210886Spjd if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) { 199210886Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message"); 200210886Spjd if (parse->eap == NULL) { 201210886Spjd parse->eap = os_malloc(dlen); 202210886Spjd if (parse->eap == NULL) { 203210886Spjd wpa_printf(MSG_WARNING, "EAP-TTLS: " 204211886Spjd "failed to allocate memory " 205211886Spjd "for Phase 2 EAP data"); 206210886Spjd goto fail; 207210886Spjd } 208210886Spjd os_memcpy(parse->eap, dpos, dlen); 209210886Spjd parse->eap_len = dlen; 210210886Spjd } else { 211210886Spjd u8 *neweap = os_realloc(parse->eap, 212210886Spjd parse->eap_len + dlen); 213210886Spjd if (neweap == NULL) { 214210886Spjd wpa_printf(MSG_WARNING, "EAP-TTLS: " 215210886Spjd "failed to allocate memory " 216210886Spjd "for Phase 2 EAP data"); 217210886Spjd goto fail; 218210886Spjd } 219210886Spjd os_memcpy(neweap + parse->eap_len, dpos, dlen); 220210886Spjd parse->eap = neweap; 221210886Spjd parse->eap_len += dlen; 222210886Spjd } 223210886Spjd } else if (vendor_id == 0 && 224210886Spjd avp_code == RADIUS_ATTR_USER_NAME) { 225210886Spjd wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name", 226210886Spjd dpos, dlen); 227210886Spjd parse->user_name = dpos; 228211886Spjd parse->user_name_len = dlen; 229211886Spjd } else if (vendor_id == 0 && 230210886Spjd avp_code == RADIUS_ATTR_USER_PASSWORD) { 231210886Spjd u8 *password = dpos; 232210886Spjd size_t password_len = dlen; 233204076Spjd while (password_len > 0 && 234217784Spjd password[password_len - 1] == '\0') { 235217784Spjd password_len--; 236217784Spjd } 237217784Spjd wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: " 238217784Spjd "User-Password (PAP)", 239217784Spjd password, password_len); 240217784Spjd parse->user_password = password; 241217784Spjd parse->user_password_len = password_len; 242217784Spjd } else if (vendor_id == 0 && 243217784Spjd avp_code == RADIUS_ATTR_CHAP_CHALLENGE) { 244217784Spjd wpa_hexdump(MSG_DEBUG, 245217784Spjd "EAP-TTLS: CHAP-Challenge (CHAP)", 246217784Spjd dpos, dlen); 247217784Spjd parse->chap_challenge = dpos; 248217784Spjd parse->chap_challenge_len = dlen; 249217784Spjd } else if (vendor_id == 0 && 250217784Spjd avp_code == RADIUS_ATTR_CHAP_PASSWORD) { 251217784Spjd wpa_hexdump(MSG_DEBUG, 252217784Spjd "EAP-TTLS: CHAP-Password (CHAP)", 253217784Spjd dpos, dlen); 254217784Spjd parse->chap_password = dpos; 255217784Spjd parse->chap_password_len = dlen; 256217784Spjd } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT && 257217784Spjd avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) { 258217784Spjd wpa_hexdump(MSG_DEBUG, 259217784Spjd "EAP-TTLS: MS-CHAP-Challenge", 260217784Spjd dpos, dlen); 261217784Spjd parse->mschap_challenge = dpos; 262217784Spjd parse->mschap_challenge_len = dlen; 263217784Spjd } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT && 264217784Spjd avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) { 265217784Spjd wpa_hexdump(MSG_DEBUG, 266217784Spjd "EAP-TTLS: MS-CHAP-Response (MSCHAP)", 267217784Spjd dpos, dlen); 268217784Spjd parse->mschap_response = dpos; 269217784Spjd parse->mschap_response_len = dlen; 270217784Spjd } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT && 271217784Spjd avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) { 272217784Spjd wpa_hexdump(MSG_DEBUG, 273204076Spjd "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)", 274204076Spjd dpos, dlen); 275210886Spjd parse->mschap2_response = dpos; 276210886Spjd parse->mschap2_response_len = dlen; 277210886Spjd } else if (avp_flags & AVP_FLAGS_MANDATORY) { 278204076Spjd wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported " 279210886Spjd "mandatory AVP code %d vendor_id %d - " 280210886Spjd "dropped", (int) avp_code, (int) vendor_id); 281210886Spjd goto fail; 282210886Spjd } else { 283210886Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported " 284210886Spjd "AVP code %d vendor_id %d", 285210886Spjd (int) avp_code, (int) vendor_id); 286210886Spjd } 287210886Spjd 288210886Spjd pad = (4 - (avp_length & 3)) & 3; 289210886Spjd pos += avp_length + pad; 290210886Spjd left -= avp_length + pad; 291210886Spjd } 292210886Spjd 293210886Spjd return 0; 294210886Spjd 295210886Spjdfail: 296210886Spjd os_free(parse->eap); 297210886Spjd parse->eap = NULL; 298210886Spjd return -1; 299210886Spjd} 300210886Spjd 301210886Spjd 302210886Spjdstatic u8 * eap_ttls_implicit_challenge(struct eap_sm *sm, 303210886Spjd struct eap_ttls_data *data, size_t len) 304210886Spjd{ 305210886Spjd return eap_server_tls_derive_key(sm, &data->ssl, "ttls challenge", 306210886Spjd len); 307210886Spjd} 308210886Spjd 309210886Spjd 310210886Spjdstatic void * eap_ttls_init(struct eap_sm *sm) 311210886Spjd{ 312210886Spjd struct eap_ttls_data *data; 313210886Spjd 314210886Spjd data = os_zalloc(sizeof(*data)); 315210886Spjd if (data == NULL) 316210886Spjd return NULL; 317210886Spjd data->ttls_version = EAP_TTLS_VERSION; 318210886Spjd data->state = START; 319210886Spjd 320210886Spjd if (eap_server_tls_ssl_init(sm, &data->ssl, 0)) { 321210886Spjd wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL."); 322210886Spjd eap_ttls_reset(sm, data); 323210886Spjd return NULL; 324210886Spjd } 325210886Spjd 326210886Spjd return data; 327210886Spjd} 328210886Spjd 329210886Spjd 330210886Spjdstatic void eap_ttls_reset(struct eap_sm *sm, void *priv) 331210886Spjd{ 332210886Spjd struct eap_ttls_data *data = priv; 333210886Spjd if (data == NULL) 334210886Spjd return; 335210886Spjd if (data->phase2_priv && data->phase2_method) 336210886Spjd data->phase2_method->reset(sm, data->phase2_priv); 337210886Spjd eap_server_tls_ssl_deinit(sm, &data->ssl); 338210886Spjd wpabuf_free(data->pending_phase2_eap_resp); 339210886Spjd bin_clear_free(data, sizeof(*data)); 340210886Spjd} 341210886Spjd 342210886Spjd 343210886Spjdstatic struct wpabuf * eap_ttls_build_start(struct eap_sm *sm, 344210886Spjd struct eap_ttls_data *data, u8 id) 345210886Spjd{ 346210886Spjd struct wpabuf *req; 347210886Spjd 348210886Spjd req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1, 349210886Spjd EAP_CODE_REQUEST, id); 350210886Spjd if (req == NULL) { 351210886Spjd wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for" 352210886Spjd " request"); 353210886Spjd eap_ttls_state(data, FAILURE); 354210886Spjd return NULL; 355210886Spjd } 356210886Spjd 357210886Spjd wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->ttls_version); 358210886Spjd 359210886Spjd eap_ttls_state(data, PHASE1); 360210886Spjd 361210886Spjd return req; 362210886Spjd} 363210886Spjd 364210886Spjd 365210886Spjdstatic struct wpabuf * eap_ttls_build_phase2_eap_req( 366210886Spjd struct eap_sm *sm, struct eap_ttls_data *data, u8 id) 367210886Spjd{ 368210886Spjd struct wpabuf *buf, *encr_req; 369210886Spjd 370210886Spjd 371210886Spjd buf = data->phase2_method->buildReq(sm, data->phase2_priv, id); 372210886Spjd if (buf == NULL) 373210886Spjd return NULL; 374217729Spjd 375217729Spjd wpa_hexdump_buf_key(MSG_DEBUG, 376217729Spjd "EAP-TTLS/EAP: Encapsulate Phase 2 data", buf); 377210886Spjd 378210886Spjd buf = eap_ttls_avp_encapsulate(buf, RADIUS_ATTR_EAP_MESSAGE, 1); 379210886Spjd if (buf == NULL) { 380210886Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate " 381210886Spjd "packet"); 382210886Spjd return NULL; 383210886Spjd } 384210886Spjd 385210886Spjd wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated " 386210886Spjd "Phase 2 data", buf); 387210886Spjd 388210886Spjd encr_req = eap_server_tls_encrypt(sm, &data->ssl, buf); 389210886Spjd wpabuf_free(buf); 390210886Spjd 391210886Spjd return encr_req; 392210886Spjd} 393210886Spjd 394210886Spjd 395210886Spjdstatic struct wpabuf * eap_ttls_build_phase2_mschapv2( 396210886Spjd struct eap_sm *sm, struct eap_ttls_data *data) 397210886Spjd{ 398210886Spjd struct wpabuf *encr_req, msgbuf; 399210886Spjd u8 *req, *pos, *end; 400210886Spjd int ret; 401210886Spjd 402210886Spjd pos = req = os_malloc(100); 403210886Spjd if (req == NULL) 404217729Spjd return NULL; 405217729Spjd end = req + 100; 406217784Spjd 407217784Spjd if (data->mschapv2_resp_ok) { 408210886Spjd pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS, 409210886Spjd RADIUS_VENDOR_ID_MICROSOFT, 1, 43); 410210886Spjd *pos++ = data->mschapv2_ident; 411210886Spjd ret = os_snprintf((char *) pos, end - pos, "S="); 412210886Spjd if (!os_snprintf_error(end - pos, ret)) 413210886Spjd pos += ret; 414210886Spjd pos += wpa_snprintf_hex_uppercase( 415210886Spjd (char *) pos, end - pos, data->mschapv2_auth_response, 416210886Spjd sizeof(data->mschapv2_auth_response)); 417210886Spjd } else { 418210886Spjd pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR, 419210886Spjd RADIUS_VENDOR_ID_MICROSOFT, 1, 6); 420210886Spjd os_memcpy(pos, "Failed", 6); 421210886Spjd pos += 6; 422210886Spjd AVP_PAD(req, pos); 423204076Spjd } 424204076Spjd 425204076Spjd wpabuf_set(&msgbuf, req, pos - req); 426211899Spjd wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 " 427211899Spjd "data", &msgbuf); 428211899Spjd 429211899Spjd encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf); 430211899Spjd os_free(req); 431211899Spjd 432211899Spjd return encr_req; 433211899Spjd} 434211899Spjd 435211899Spjd 436211899Spjdstatic struct wpabuf * eap_ttls_buildReq(struct eap_sm *sm, void *priv, u8 id) 437211899Spjd{ 438211899Spjd struct eap_ttls_data *data = priv; 439211899Spjd 440211899Spjd if (data->ssl.state == FRAG_ACK) { 441211899Spjd return eap_server_tls_build_ack(id, EAP_TYPE_TTLS, 442211899Spjd data->ttls_version); 443211899Spjd } 444211899Spjd 445204076Spjd if (data->ssl.state == WAIT_FRAG_ACK) { 446204076Spjd return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS, 447204076Spjd data->ttls_version, id); 448204076Spjd } 449204076Spjd 450204076Spjd switch (data->state) { 451204076Spjd case START: 452204076Spjd return eap_ttls_build_start(sm, data, id); 453204076Spjd case PHASE1: 454204076Spjd if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { 455204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, " 456204076Spjd "starting Phase2"); 457204076Spjd eap_ttls_state(data, PHASE2_START); 458204076Spjd } 459204076Spjd break; 460204076Spjd case PHASE2_METHOD: 461204076Spjd wpabuf_free(data->ssl.tls_out); 462204076Spjd data->ssl.tls_out_pos = 0; 463204076Spjd data->ssl.tls_out = eap_ttls_build_phase2_eap_req(sm, data, 464204076Spjd id); 465204076Spjd break; 466204076Spjd case PHASE2_MSCHAPV2_RESP: 467209185Spjd wpabuf_free(data->ssl.tls_out); 468204076Spjd data->ssl.tls_out_pos = 0; 469207371Spjd data->ssl.tls_out = eap_ttls_build_phase2_mschapv2(sm, data); 470207371Spjd break; 471207371Spjd default: 472207371Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d", 473204076Spjd __func__, data->state); 474204076Spjd return NULL; 475204076Spjd } 476204076Spjd 477204076Spjd return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS, 478204076Spjd data->ttls_version, id); 479204076Spjd} 480204076Spjd 481204076Spjd 482204076Spjdstatic Boolean eap_ttls_check(struct eap_sm *sm, void *priv, 483204076Spjd struct wpabuf *respData) 484204076Spjd{ 485204076Spjd const u8 *pos; 486204076Spjd size_t len; 487204076Spjd 488204076Spjd pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TTLS, respData, &len); 489204076Spjd if (pos == NULL || len < 1) { 490204076Spjd wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame"); 491204076Spjd return TRUE; 492204076Spjd } 493204076Spjd 494204076Spjd return FALSE; 495204076Spjd} 496204076Spjd 497204076Spjd 498204076Spjdstatic void eap_ttls_process_phase2_pap(struct eap_sm *sm, 499204076Spjd struct eap_ttls_data *data, 500204076Spjd const u8 *user_password, 501204076Spjd size_t user_password_len) 502204076Spjd{ 503204076Spjd if (!sm->user || !sm->user->password || sm->user->password_hash || 504204076Spjd !(sm->user->ttls_auth & EAP_TTLS_AUTH_PAP)) { 505204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No plaintext user " 506204076Spjd "password configured"); 507204076Spjd eap_ttls_state(data, FAILURE); 508204076Spjd return; 509204076Spjd } 510204076Spjd 511204076Spjd if (sm->user->password_len != user_password_len || 512204076Spjd os_memcmp_const(sm->user->password, user_password, 513204076Spjd user_password_len) != 0) { 514204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password"); 515204076Spjd eap_ttls_state(data, FAILURE); 516204076Spjd return; 517204076Spjd } 518204076Spjd 519204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password"); 520204076Spjd eap_ttls_state(data, SUCCESS); 521204076Spjd} 522204076Spjd 523204076Spjd 524204076Spjdstatic void eap_ttls_process_phase2_chap(struct eap_sm *sm, 525204076Spjd struct eap_ttls_data *data, 526204076Spjd const u8 *challenge, 527204076Spjd size_t challenge_len, 528204076Spjd const u8 *password, 529204076Spjd size_t password_len) 530204076Spjd{ 531204076Spjd u8 *chal, hash[CHAP_MD5_LEN]; 532204076Spjd 533204076Spjd if (challenge == NULL || password == NULL || 534204076Spjd challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN || 535204076Spjd password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) { 536204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes " 537204076Spjd "(challenge len %lu password len %lu)", 538204076Spjd (unsigned long) challenge_len, 539204076Spjd (unsigned long) password_len); 540204076Spjd eap_ttls_state(data, FAILURE); 541204076Spjd return; 542204076Spjd } 543204076Spjd 544204076Spjd if (!sm->user || !sm->user->password || sm->user->password_hash || 545204076Spjd !(sm->user->ttls_auth & EAP_TTLS_AUTH_CHAP)) { 546204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No plaintext user " 547204076Spjd "password configured"); 548204076Spjd eap_ttls_state(data, FAILURE); 549204076Spjd return; 550204076Spjd } 551204076Spjd 552204076Spjd chal = eap_ttls_implicit_challenge(sm, data, 553209185Spjd EAP_TTLS_CHAP_CHALLENGE_LEN + 1); 554204076Spjd if (chal == NULL) { 555204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate " 556204076Spjd "challenge from TLS data"); 557204076Spjd eap_ttls_state(data, FAILURE); 558204076Spjd return; 559204076Spjd } 560204076Spjd 561204076Spjd if (os_memcmp_const(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) 562204076Spjd != 0 || 563204076Spjd password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) { 564204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch"); 565204076Spjd os_free(chal); 566204076Spjd eap_ttls_state(data, FAILURE); 567204076Spjd return; 568204076Spjd } 569204076Spjd os_free(chal); 570204076Spjd 571204076Spjd /* MD5(Ident + Password + Challenge) */ 572204076Spjd chap_md5(password[0], sm->user->password, sm->user->password_len, 573204076Spjd challenge, challenge_len, hash); 574204076Spjd 575204076Spjd if (os_memcmp_const(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 576204076Spjd 0) { 577204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password"); 578204076Spjd eap_ttls_state(data, SUCCESS); 579204076Spjd } else { 580204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password"); 581204076Spjd eap_ttls_state(data, FAILURE); 582207372Spjd } 583204076Spjd} 584204076Spjd 585204076Spjd 586204076Spjdstatic void eap_ttls_process_phase2_mschap(struct eap_sm *sm, 587207372Spjd struct eap_ttls_data *data, 588204076Spjd u8 *challenge, size_t challenge_len, 589213006Spjd u8 *response, size_t response_len) 590204076Spjd{ 591204076Spjd u8 *chal, nt_response[24]; 592204076Spjd 593213981Spjd if (challenge == NULL || response == NULL || 594213981Spjd challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN || 595204076Spjd response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) { 596204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP " 597204076Spjd "attributes (challenge len %lu response len %lu)", 598204076Spjd (unsigned long) challenge_len, 599204076Spjd (unsigned long) response_len); 600204076Spjd eap_ttls_state(data, FAILURE); 601204076Spjd return; 602204076Spjd } 603204076Spjd 604204076Spjd if (!sm->user || !sm->user->password || 605204076Spjd !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAP)) { 606204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password " 607204076Spjd "configured"); 608204076Spjd eap_ttls_state(data, FAILURE); 609204076Spjd return; 610204076Spjd } 611204076Spjd 612204076Spjd chal = eap_ttls_implicit_challenge(sm, data, 613204076Spjd EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1); 614204076Spjd if (chal == NULL) { 615204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate " 616204076Spjd "challenge from TLS data"); 617204076Spjd eap_ttls_state(data, FAILURE); 618204076Spjd return; 619204076Spjd } 620204076Spjd 621204076Spjd if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) 622204076Spjd != 0 || 623204076Spjd response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) { 624204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch"); 625204076Spjd os_free(chal); 626204076Spjd eap_ttls_state(data, FAILURE); 627204076Spjd return; 628204076Spjd } 629204076Spjd os_free(chal); 630204076Spjd 631204076Spjd if (sm->user->password_hash) 632204076Spjd challenge_response(challenge, sm->user->password, nt_response); 633204076Spjd else 634204076Spjd nt_challenge_response(challenge, sm->user->password, 635204076Spjd sm->user->password_len, nt_response); 636204076Spjd 637204076Spjd if (os_memcmp_const(nt_response, response + 2 + 24, 24) == 0) { 638204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response"); 639204076Spjd eap_ttls_state(data, SUCCESS); 640204076Spjd } else { 641204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response"); 642204076Spjd wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received", 643204076Spjd response + 2 + 24, 24); 644204076Spjd wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected", 645204076Spjd nt_response, 24); 646204076Spjd eap_ttls_state(data, FAILURE); 647204076Spjd } 648204076Spjd} 649204076Spjd 650204076Spjd 651204076Spjdstatic void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm, 652204076Spjd struct eap_ttls_data *data, 653204076Spjd u8 *challenge, 654204076Spjd size_t challenge_len, 655204076Spjd u8 *response, size_t response_len) 656204076Spjd{ 657204076Spjd u8 *chal, *username, nt_response[24], *rx_resp, *peer_challenge, 658204076Spjd *auth_challenge; 659204076Spjd size_t username_len, i; 660204076Spjd 661204076Spjd if (challenge == NULL || response == NULL || 662204076Spjd challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN || 663204076Spjd response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) { 664204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 " 665204076Spjd "attributes (challenge len %lu response len %lu)", 666204076Spjd (unsigned long) challenge_len, 667212038Spjd (unsigned long) response_len); 668213009Spjd eap_ttls_state(data, FAILURE); 669213009Spjd return; 670213009Spjd } 671213009Spjd 672212037Spjd if (!sm->user || !sm->user->password || 673204076Spjd !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAPV2)) { 674213009Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password " 675213009Spjd "configured"); 676213009Spjd eap_ttls_state(data, FAILURE); 677213009Spjd return; 678211977Spjd } 679213009Spjd 680213009Spjd if (sm->identity == NULL) { 681213009Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user identity " 682213009Spjd "known"); 683213009Spjd eap_ttls_state(data, FAILURE); 684213009Spjd return; 685216477Spjd } 686216477Spjd 687216477Spjd /* MSCHAPv2 does not include optional domain name in the 688204076Spjd * challenge-response calculation, so remove domain prefix 689213009Spjd * (if present). */ 690213009Spjd username = sm->identity; 691213009Spjd username_len = sm->identity_len; 692213009Spjd for (i = 0; i < username_len; i++) { 693213009Spjd if (username[i] == '\\') { 694213009Spjd username_len -= i + 1; 695217967Spjd username += i + 1; 696213009Spjd break; 697213009Spjd } 698213009Spjd } 699213009Spjd 700213009Spjd chal = eap_ttls_implicit_challenge( 701213009Spjd sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1); 702213009Spjd if (chal == NULL) { 703213009Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate " 704213009Spjd "challenge from TLS data"); 705213009Spjd eap_ttls_state(data, FAILURE); 706213009Spjd return; 707211899Spjd } 708204076Spjd 709209177Spjd if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) 710204076Spjd != 0 || 711212038Spjd response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) { 712213008Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch"); 713212038Spjd os_free(chal); 714212038Spjd eap_ttls_state(data, FAILURE); 715213008Spjd return; 716212038Spjd } 717212038Spjd os_free(chal); 718212038Spjd 719212038Spjd auth_challenge = challenge; 720212038Spjd peer_challenge = response + 2; 721212038Spjd 722213008Spjd wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User", 723212038Spjd username, username_len); 724212038Spjd wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge", 725212038Spjd auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN); 726204076Spjd wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge", 727213008Spjd peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN); 728213009Spjd 729211977Spjd if (sm->user->password_hash) { 730213429Spjd generate_nt_response_pwhash(auth_challenge, peer_challenge, 731211977Spjd username, username_len, 732204076Spjd sm->user->password, 733204076Spjd nt_response); 734204076Spjd } else { 735204076Spjd generate_nt_response(auth_challenge, peer_challenge, 736204076Spjd username, username_len, 737204076Spjd sm->user->password, 738212038Spjd sm->user->password_len, 739204076Spjd nt_response); 740212038Spjd } 741204076Spjd 742212038Spjd rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8; 743212038Spjd if (os_memcmp_const(nt_response, rx_resp, 24) == 0) { 744212038Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct " 745212038Spjd "NT-Response"); 746212038Spjd data->mschapv2_resp_ok = 1; 747212038Spjd 748212038Spjd if (sm->user->password_hash) { 749212038Spjd generate_authenticator_response_pwhash( 750212038Spjd sm->user->password, 751212038Spjd peer_challenge, auth_challenge, 752212038Spjd username, username_len, nt_response, 753204076Spjd data->mschapv2_auth_response); 754204076Spjd } else { 755204076Spjd generate_authenticator_response( 756213428Spjd sm->user->password, sm->user->password_len, 757213428Spjd peer_challenge, auth_challenge, 758213428Spjd username, username_len, nt_response, 759213428Spjd data->mschapv2_auth_response); 760213428Spjd } 761213428Spjd } else { 762204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid " 763204076Spjd "NT-Response"); 764204076Spjd wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received", 765204076Spjd rx_resp, 24); 766204076Spjd wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected", 767204076Spjd nt_response, 24); 768204076Spjd data->mschapv2_resp_ok = 0; 769213009Spjd } 770204076Spjd eap_ttls_state(data, PHASE2_MSCHAPV2_RESP); 771204076Spjd data->mschapv2_ident = response[0]; 772204076Spjd} 773204076Spjd 774204076Spjd 775204076Spjdstatic int eap_ttls_phase2_eap_init(struct eap_sm *sm, 776204076Spjd struct eap_ttls_data *data, 777204076Spjd EapType eap_type) 778204076Spjd{ 779204076Spjd if (data->phase2_priv && data->phase2_method) { 780204076Spjd data->phase2_method->reset(sm, data->phase2_priv); 781204076Spjd data->phase2_method = NULL; 782204076Spjd data->phase2_priv = NULL; 783204076Spjd } 784204076Spjd data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF, 785204076Spjd eap_type); 786204076Spjd if (!data->phase2_method) 787204076Spjd return -1; 788204076Spjd 789204076Spjd sm->init_phase2 = 1; 790204076Spjd data->phase2_priv = data->phase2_method->init(sm); 791204076Spjd sm->init_phase2 = 0; 792204076Spjd return data->phase2_priv == NULL ? -1 : 0; 793204076Spjd} 794204076Spjd 795204076Spjd 796204076Spjdstatic void eap_ttls_process_phase2_eap_response(struct eap_sm *sm, 797204076Spjd struct eap_ttls_data *data, 798204076Spjd u8 *in_data, size_t in_len) 799204076Spjd{ 800204076Spjd u8 next_type = EAP_TYPE_NONE; 801204076Spjd struct eap_hdr *hdr; 802217965Spjd u8 *pos; 803204076Spjd size_t left; 804204076Spjd struct wpabuf buf; 805214273Spjd const struct eap_method *m = data->phase2_method; 806214273Spjd void *priv = data->phase2_priv; 807204076Spjd 808204076Spjd if (priv == NULL) { 809204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not " 810204076Spjd "initialized?!", __func__); 811204076Spjd return; 812204076Spjd } 813204076Spjd 814204076Spjd hdr = (struct eap_hdr *) in_data; 815210879Spjd pos = (u8 *) (hdr + 1); 816204076Spjd 817204076Spjd if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) { 818210883Spjd left = in_len - sizeof(*hdr); 819204076Spjd wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; " 820204076Spjd "allowed types", pos + 1, left - 1); 821213428Spjd eap_sm_process_nak(sm, pos + 1, left - 1); 822217307Spjd if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && 823217307Spjd sm->user->methods[sm->user_eap_method_index].method != 824217307Spjd EAP_TYPE_NONE) { 825217307Spjd next_type = sm->user->methods[ 826217307Spjd sm->user_eap_method_index++].method; 827217307Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", 828217307Spjd next_type); 829213428Spjd if (eap_ttls_phase2_eap_init(sm, data, next_type)) { 830213428Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to " 831213428Spjd "initialize EAP type %d", 832213428Spjd next_type); 833217307Spjd eap_ttls_state(data, FAILURE); 834213009Spjd return; 835213009Spjd } 836213009Spjd } else { 837213009Spjd eap_ttls_state(data, FAILURE); 838213009Spjd } 839213009Spjd return; 840204076Spjd } 841204076Spjd 842204076Spjd wpabuf_set(&buf, in_data, in_len); 843204076Spjd 844204076Spjd if (m->check(sm, priv, &buf)) { 845204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to " 846204076Spjd "ignore the packet"); 847204076Spjd return; 848204076Spjd } 849204076Spjd 850204076Spjd m->process(sm, priv, &buf); 851204076Spjd 852204076Spjd if (sm->method_pending == METHOD_PENDING_WAIT) { 853204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method is in " 854204076Spjd "pending wait state - save decrypted response"); 855204076Spjd wpabuf_free(data->pending_phase2_eap_resp); 856204076Spjd data->pending_phase2_eap_resp = wpabuf_dup(&buf); 857204076Spjd } 858204076Spjd 859204076Spjd if (!m->isDone(sm, priv)) 860204076Spjd return; 861204076Spjd 862204076Spjd if (!m->isSuccess(sm, priv)) { 863204076Spjd wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed"); 864204076Spjd eap_ttls_state(data, FAILURE); 865204076Spjd return; 866204076Spjd } 867204076Spjd 868204076Spjd switch (data->state) { 869204076Spjd case PHASE2_START: 870211977Spjd if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { 871211977Spjd wpa_hexdump_ascii(MSG_DEBUG, "EAP_TTLS: Phase2 " 872204076Spjd "Identity not found in the user " 873204076Spjd "database", 874204076Spjd sm->identity, sm->identity_len); 875204076Spjd eap_ttls_state(data, FAILURE); 876 break; 877 } 878 879 eap_ttls_state(data, PHASE2_METHOD); 880 next_type = sm->user->methods[0].method; 881 sm->user_eap_method_index = 1; 882 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type); 883 if (eap_ttls_phase2_eap_init(sm, data, next_type)) { 884 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize " 885 "EAP type %d", next_type); 886 eap_ttls_state(data, FAILURE); 887 } 888 break; 889 case PHASE2_METHOD: 890 eap_ttls_state(data, SUCCESS); 891 break; 892 case FAILURE: 893 break; 894 default: 895 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d", 896 __func__, data->state); 897 break; 898 } 899} 900 901 902static void eap_ttls_process_phase2_eap(struct eap_sm *sm, 903 struct eap_ttls_data *data, 904 const u8 *eap, size_t eap_len) 905{ 906 struct eap_hdr *hdr; 907 size_t len; 908 909 if (data->state == PHASE2_START) { 910 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2"); 911 if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_IDENTITY) < 0) 912 { 913 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: failed to " 914 "initialize EAP-Identity"); 915 return; 916 } 917 } 918 919 if (eap_len < sizeof(*hdr)) { 920 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: too short Phase 2 EAP " 921 "packet (len=%lu)", (unsigned long) eap_len); 922 return; 923 } 924 925 hdr = (struct eap_hdr *) eap; 926 len = be_to_host16(hdr->length); 927 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d " 928 "identifier=%d length=%lu", hdr->code, hdr->identifier, 929 (unsigned long) len); 930 if (len > eap_len) { 931 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Length mismatch in Phase 2" 932 " EAP frame (hdr len=%lu, data len in AVP=%lu)", 933 (unsigned long) len, (unsigned long) eap_len); 934 return; 935 } 936 937 switch (hdr->code) { 938 case EAP_CODE_RESPONSE: 939 eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr, 940 len); 941 break; 942 default: 943 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in " 944 "Phase 2 EAP header", hdr->code); 945 break; 946 } 947} 948 949 950static void eap_ttls_process_phase2(struct eap_sm *sm, 951 struct eap_ttls_data *data, 952 struct wpabuf *in_buf) 953{ 954 struct wpabuf *in_decrypted; 955 struct eap_ttls_avp parse; 956 957 wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for" 958 " Phase 2", (unsigned long) wpabuf_len(in_buf)); 959 960 if (data->pending_phase2_eap_resp) { 961 wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 EAP response " 962 "- skip decryption and use old data"); 963 eap_ttls_process_phase2_eap( 964 sm, data, wpabuf_head(data->pending_phase2_eap_resp), 965 wpabuf_len(data->pending_phase2_eap_resp)); 966 wpabuf_free(data->pending_phase2_eap_resp); 967 data->pending_phase2_eap_resp = NULL; 968 return; 969 } 970 971 in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn, 972 in_buf); 973 if (in_decrypted == NULL) { 974 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 " 975 "data"); 976 eap_ttls_state(data, FAILURE); 977 return; 978 } 979 980 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP", 981 in_decrypted); 982 983 if (eap_ttls_avp_parse(in_decrypted, &parse) < 0) { 984 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs"); 985 wpabuf_free(in_decrypted); 986 eap_ttls_state(data, FAILURE); 987 return; 988 } 989 990 if (parse.user_name) { 991 char *nbuf; 992 nbuf = os_malloc(parse.user_name_len * 4 + 1); 993 if (nbuf) { 994 printf_encode(nbuf, parse.user_name_len * 4 + 1, 995 parse.user_name, 996 parse.user_name_len); 997 eap_log_msg(sm, "TTLS-User-Name '%s'", nbuf); 998 os_free(nbuf); 999 } 1000 1001 os_free(sm->identity); 1002 sm->identity = os_malloc(parse.user_name_len); 1003 if (sm->identity == NULL) { 1004 eap_ttls_state(data, FAILURE); 1005 goto done; 1006 } 1007 os_memcpy(sm->identity, parse.user_name, parse.user_name_len); 1008 sm->identity_len = parse.user_name_len; 1009 if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1) 1010 != 0) { 1011 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not " 1012 "found in the user database"); 1013 eap_ttls_state(data, FAILURE); 1014 goto done; 1015 } 1016 } 1017 1018#ifdef EAP_SERVER_TNC 1019 if (data->tnc_started && parse.eap == NULL) { 1020 wpa_printf(MSG_DEBUG, "EAP-TTLS: TNC started but no EAP " 1021 "response from peer"); 1022 eap_ttls_state(data, FAILURE); 1023 goto done; 1024 } 1025#endif /* EAP_SERVER_TNC */ 1026 1027 if (parse.eap) { 1028 eap_ttls_process_phase2_eap(sm, data, parse.eap, 1029 parse.eap_len); 1030 } else if (parse.user_password) { 1031 eap_ttls_process_phase2_pap(sm, data, parse.user_password, 1032 parse.user_password_len); 1033 } else if (parse.chap_password) { 1034 eap_ttls_process_phase2_chap(sm, data, 1035 parse.chap_challenge, 1036 parse.chap_challenge_len, 1037 parse.chap_password, 1038 parse.chap_password_len); 1039 } else if (parse.mschap_response) { 1040 eap_ttls_process_phase2_mschap(sm, data, 1041 parse.mschap_challenge, 1042 parse.mschap_challenge_len, 1043 parse.mschap_response, 1044 parse.mschap_response_len); 1045 } else if (parse.mschap2_response) { 1046 eap_ttls_process_phase2_mschapv2(sm, data, 1047 parse.mschap_challenge, 1048 parse.mschap_challenge_len, 1049 parse.mschap2_response, 1050 parse.mschap2_response_len); 1051 } 1052 1053done: 1054 wpabuf_free(in_decrypted); 1055 os_free(parse.eap); 1056} 1057 1058 1059static void eap_ttls_start_tnc(struct eap_sm *sm, struct eap_ttls_data *data) 1060{ 1061#ifdef EAP_SERVER_TNC 1062 if (!sm->tnc || data->state != SUCCESS || data->tnc_started) 1063 return; 1064 1065 wpa_printf(MSG_DEBUG, "EAP-TTLS: Initialize TNC"); 1066 if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_TNC)) { 1067 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize TNC"); 1068 eap_ttls_state(data, FAILURE); 1069 return; 1070 } 1071 1072 data->tnc_started = 1; 1073 eap_ttls_state(data, PHASE2_METHOD); 1074#endif /* EAP_SERVER_TNC */ 1075} 1076 1077 1078static int eap_ttls_process_version(struct eap_sm *sm, void *priv, 1079 int peer_version) 1080{ 1081 struct eap_ttls_data *data = priv; 1082 if (peer_version < data->ttls_version) { 1083 wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; " 1084 "use version %d", 1085 peer_version, data->ttls_version, peer_version); 1086 data->ttls_version = peer_version; 1087 } 1088 1089 return 0; 1090} 1091 1092 1093static void eap_ttls_process_msg(struct eap_sm *sm, void *priv, 1094 const struct wpabuf *respData) 1095{ 1096 struct eap_ttls_data *data = priv; 1097 1098 switch (data->state) { 1099 case PHASE1: 1100 if (eap_server_tls_phase1(sm, &data->ssl) < 0) 1101 eap_ttls_state(data, FAILURE); 1102 break; 1103 case PHASE2_START: 1104 case PHASE2_METHOD: 1105 eap_ttls_process_phase2(sm, data, data->ssl.tls_in); 1106 eap_ttls_start_tnc(sm, data); 1107 break; 1108 case PHASE2_MSCHAPV2_RESP: 1109 if (data->mschapv2_resp_ok && wpabuf_len(data->ssl.tls_in) == 1110 0) { 1111 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer " 1112 "acknowledged response"); 1113 eap_ttls_state(data, SUCCESS); 1114 } else if (!data->mschapv2_resp_ok) { 1115 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer " 1116 "acknowledged error"); 1117 eap_ttls_state(data, FAILURE); 1118 } else { 1119 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected " 1120 "frame from peer (payload len %lu, " 1121 "expected empty frame)", 1122 (unsigned long) 1123 wpabuf_len(data->ssl.tls_in)); 1124 eap_ttls_state(data, FAILURE); 1125 } 1126 eap_ttls_start_tnc(sm, data); 1127 break; 1128 default: 1129 wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s", 1130 data->state, __func__); 1131 break; 1132 } 1133} 1134 1135 1136static void eap_ttls_process(struct eap_sm *sm, void *priv, 1137 struct wpabuf *respData) 1138{ 1139 struct eap_ttls_data *data = priv; 1140 if (eap_server_tls_process(sm, &data->ssl, respData, data, 1141 EAP_TYPE_TTLS, eap_ttls_process_version, 1142 eap_ttls_process_msg) < 0) 1143 eap_ttls_state(data, FAILURE); 1144} 1145 1146 1147static Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv) 1148{ 1149 struct eap_ttls_data *data = priv; 1150 return data->state == SUCCESS || data->state == FAILURE; 1151} 1152 1153 1154static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len) 1155{ 1156 struct eap_ttls_data *data = priv; 1157 u8 *eapKeyData; 1158 1159 if (data->state != SUCCESS) 1160 return NULL; 1161 1162 eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, 1163 "ttls keying material", 1164 EAP_TLS_KEY_LEN); 1165 if (eapKeyData) { 1166 *len = EAP_TLS_KEY_LEN; 1167 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key", 1168 eapKeyData, EAP_TLS_KEY_LEN); 1169 } else { 1170 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key"); 1171 } 1172 1173 return eapKeyData; 1174} 1175 1176 1177static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv) 1178{ 1179 struct eap_ttls_data *data = priv; 1180 return data->state == SUCCESS; 1181} 1182 1183 1184static u8 * eap_ttls_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 1185{ 1186 struct eap_ttls_data *data = priv; 1187 1188 if (data->state != SUCCESS) 1189 return NULL; 1190 1191 return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_TTLS, 1192 len); 1193} 1194 1195 1196static u8 * eap_ttls_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 1197{ 1198 struct eap_ttls_data *data = priv; 1199 u8 *eapKeyData, *emsk; 1200 1201 if (data->state != SUCCESS) 1202 return NULL; 1203 1204 eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, 1205 "ttls keying material", 1206 EAP_TLS_KEY_LEN + EAP_EMSK_LEN); 1207 if (eapKeyData) { 1208 emsk = os_malloc(EAP_EMSK_LEN); 1209 if (emsk) 1210 os_memcpy(emsk, eapKeyData + EAP_TLS_KEY_LEN, 1211 EAP_EMSK_LEN); 1212 bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN); 1213 } else 1214 emsk = NULL; 1215 1216 if (emsk) { 1217 *len = EAP_EMSK_LEN; 1218 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Derived EMSK", 1219 emsk, EAP_EMSK_LEN); 1220 } else { 1221 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive EMSK"); 1222 } 1223 1224 return emsk; 1225} 1226 1227 1228int eap_server_ttls_register(void) 1229{ 1230 struct eap_method *eap; 1231 int ret; 1232 1233 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 1234 EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS"); 1235 if (eap == NULL) 1236 return -1; 1237 1238 eap->init = eap_ttls_init; 1239 eap->reset = eap_ttls_reset; 1240 eap->buildReq = eap_ttls_buildReq; 1241 eap->check = eap_ttls_check; 1242 eap->process = eap_ttls_process; 1243 eap->isDone = eap_ttls_isDone; 1244 eap->getKey = eap_ttls_getKey; 1245 eap->isSuccess = eap_ttls_isSuccess; 1246 eap->getSessionId = eap_ttls_get_session_id; 1247 eap->get_emsk = eap_ttls_get_emsk; 1248 1249 ret = eap_server_method_register(eap); 1250 if (ret) 1251 eap_server_method_free(eap); 1252 return ret; 1253} 1254