1/* 2 * EAP peer method: EAP-TTLS (RFC 5281) 3 * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15#include "includes.h" 16 17#include "common.h" 18#include "eap_peer/eap_i.h" 19#include "eap_peer/eap_tls_common.h" 20#include "eap_peer/eap_config.h" 21#include "crypto/ms_funcs.h" 22#include "crypto/sha1.h" 23#include "eap_common/chap.h" 24#include "crypto/tls.h" 25#include "mschapv2.h" 26#include "eap_common/eap_ttls.h" 27 28 29/* Maximum supported TTLS version 30 * 0 = RFC 5281 31 * 1 = draft-funk-eap-ttls-v1-00.txt 32 */ 33#ifndef EAP_TTLS_VERSION 34#define EAP_TTLS_VERSION 0 /* TTLSv1 implementation is not yet complete */ 35#endif /* EAP_TTLS_VERSION */ 36 37 38#define MSCHAPV2_KEY_LEN 16 39#define MSCHAPV2_NT_RESPONSE_LEN 24 40 41 42static void eap_ttls_deinit(struct eap_sm *sm, void *priv); 43 44 45struct eap_ttls_data { 46 struct eap_ssl_data ssl; 47 int ssl_initialized; 48 49 int ttls_version, force_ttls_version; 50 51 const struct eap_method *phase2_method; 52 void *phase2_priv; 53 int phase2_success; 54 int phase2_start; 55 56 enum phase2_types { 57 EAP_TTLS_PHASE2_EAP, 58 EAP_TTLS_PHASE2_MSCHAPV2, 59 EAP_TTLS_PHASE2_MSCHAP, 60 EAP_TTLS_PHASE2_PAP, 61 EAP_TTLS_PHASE2_CHAP 62 } phase2_type; 63 struct eap_method_type phase2_eap_type; 64 struct eap_method_type *phase2_eap_types; 65 size_t num_phase2_eap_types; 66 67 u8 auth_response[MSCHAPV2_AUTH_RESPONSE_LEN]; 68 int auth_response_valid; 69 u8 master_key[MSCHAPV2_MASTER_KEY_LEN]; /* MSCHAPv2 master key */ 70 u8 ident; 71 int resuming; /* starting a resumed session */ 72 int reauth; /* reauthentication */ 73 u8 *key_data; 74 75 struct wpabuf *pending_phase2_req; 76 77#ifdef EAP_TNC 78 int ready_for_tnc; 79 int tnc_started; 80#endif /* EAP_TNC */ 81}; 82 83 84static void * eap_ttls_init(struct eap_sm *sm) 85{ 86 struct eap_ttls_data *data; 87 struct eap_peer_config *config = eap_get_config(sm); 88 char *selected; 89 90 data = os_zalloc(sizeof(*data)); 91 if (data == NULL) 92 return NULL; 93 data->ttls_version = EAP_TTLS_VERSION; 94 data->force_ttls_version = -1; 95 selected = "EAP"; 96 data->phase2_type = EAP_TTLS_PHASE2_EAP; 97 98#if EAP_TTLS_VERSION > 0 99 if (config && config->phase1) { 100 const char *pos = os_strstr(config->phase1, "ttlsver="); 101 if (pos) { 102 data->force_ttls_version = atoi(pos + 8); 103 data->ttls_version = data->force_ttls_version; 104 wpa_printf(MSG_DEBUG, "EAP-TTLS: Forced TTLS version " 105 "%d", data->force_ttls_version); 106 } 107 } 108#endif /* EAP_TTLS_VERSION */ 109 110 if (config && config->phase2) { 111 if (os_strstr(config->phase2, "autheap=")) { 112 selected = "EAP"; 113 data->phase2_type = EAP_TTLS_PHASE2_EAP; 114 } else if (os_strstr(config->phase2, "auth=MSCHAPV2")) { 115 selected = "MSCHAPV2"; 116 data->phase2_type = EAP_TTLS_PHASE2_MSCHAPV2; 117 } else if (os_strstr(config->phase2, "auth=MSCHAP")) { 118 selected = "MSCHAP"; 119 data->phase2_type = EAP_TTLS_PHASE2_MSCHAP; 120 } else if (os_strstr(config->phase2, "auth=PAP")) { 121 selected = "PAP"; 122 data->phase2_type = EAP_TTLS_PHASE2_PAP; 123 } else if (os_strstr(config->phase2, "auth=CHAP")) { 124 selected = "CHAP"; 125 data->phase2_type = EAP_TTLS_PHASE2_CHAP; 126 } 127 } 128 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 type: %s", selected); 129 130 if (data->phase2_type == EAP_TTLS_PHASE2_EAP) { 131 if (eap_peer_select_phase2_methods(config, "autheap=", 132 &data->phase2_eap_types, 133 &data->num_phase2_eap_types) 134 < 0) { 135 eap_ttls_deinit(sm, data); 136 return NULL; 137 } 138 139 data->phase2_eap_type.vendor = EAP_VENDOR_IETF; 140 data->phase2_eap_type.method = EAP_TYPE_NONE; 141 } 142 143#if EAP_TTLS_VERSION > 0 144 if (!(tls_capabilities(sm->ssl_ctx) & TLS_CAPABILITY_IA) && 145 data->ttls_version > 0) { 146 if (data->force_ttls_version > 0) { 147 wpa_printf(MSG_INFO, "EAP-TTLS: Forced TTLSv%d and " 148 "TLS library does not support TLS/IA.", 149 data->force_ttls_version); 150 eap_ttls_deinit(sm, data); 151 return NULL; 152 } 153 data->ttls_version = 0; 154 } 155#endif /* EAP_TTLS_VERSION */ 156 157 return data; 158} 159 160 161static void eap_ttls_phase2_eap_deinit(struct eap_sm *sm, 162 struct eap_ttls_data *data) 163{ 164 if (data->phase2_priv && data->phase2_method) { 165 data->phase2_method->deinit(sm, data->phase2_priv); 166 data->phase2_method = NULL; 167 data->phase2_priv = NULL; 168 } 169} 170 171 172static void eap_ttls_deinit(struct eap_sm *sm, void *priv) 173{ 174 struct eap_ttls_data *data = priv; 175 if (data == NULL) 176 return; 177 eap_ttls_phase2_eap_deinit(sm, data); 178 os_free(data->phase2_eap_types); 179 if (data->ssl_initialized) 180 eap_peer_tls_ssl_deinit(sm, &data->ssl); 181 os_free(data->key_data); 182 wpabuf_free(data->pending_phase2_req); 183 os_free(data); 184} 185 186 187static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id, 188 int mandatory, size_t len) 189{ 190 struct ttls_avp_vendor *avp; 191 u8 flags; 192 size_t hdrlen; 193 194 avp = (struct ttls_avp_vendor *) avphdr; 195 flags = mandatory ? AVP_FLAGS_MANDATORY : 0; 196 if (vendor_id) { 197 flags |= AVP_FLAGS_VENDOR; 198 hdrlen = sizeof(*avp); 199 avp->vendor_id = host_to_be32(vendor_id); 200 } else { 201 hdrlen = sizeof(struct ttls_avp); 202 } 203 204 avp->avp_code = host_to_be32(avp_code); 205 avp->avp_length = host_to_be32((flags << 24) | (hdrlen + len)); 206 207 return avphdr + hdrlen; 208} 209 210 211static u8 * eap_ttls_avp_add(u8 *start, u8 *avphdr, u32 avp_code, 212 u32 vendor_id, int mandatory, 213 const u8 *data, size_t len) 214{ 215 u8 *pos; 216 pos = eap_ttls_avp_hdr(avphdr, avp_code, vendor_id, mandatory, len); 217 os_memcpy(pos, data, len); 218 pos += len; 219 AVP_PAD(start, pos); 220 return pos; 221} 222 223 224static int eap_ttls_avp_encapsulate(struct wpabuf **resp, u32 avp_code, 225 int mandatory) 226{ 227 struct wpabuf *msg; 228 u8 *avp, *pos; 229 230 msg = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(*resp) + 4); 231 if (msg == NULL) { 232 wpabuf_free(*resp); 233 *resp = NULL; 234 return -1; 235 } 236 237 avp = wpabuf_mhead(msg); 238 pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, wpabuf_len(*resp)); 239 os_memcpy(pos, wpabuf_head(*resp), wpabuf_len(*resp)); 240 pos += wpabuf_len(*resp); 241 AVP_PAD(avp, pos); 242 wpabuf_free(*resp); 243 wpabuf_put(msg, pos - avp); 244 *resp = msg; 245 return 0; 246} 247 248 249#if EAP_TTLS_VERSION > 0 250static int eap_ttls_ia_permute_inner_secret(struct eap_sm *sm, 251 struct eap_ttls_data *data, 252 const u8 *key, size_t key_len) 253{ 254 u8 *buf; 255 size_t buf_len; 256 int ret; 257 258 if (key) { 259 buf_len = 2 + key_len; 260 buf = os_malloc(buf_len); 261 if (buf == NULL) 262 return -1; 263 WPA_PUT_BE16(buf, key_len); 264 os_memcpy(buf + 2, key, key_len); 265 } else { 266 buf = NULL; 267 buf_len = 0; 268 } 269 270 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Session keys for TLS/IA inner " 271 "secret permutation", buf, buf_len); 272 ret = tls_connection_ia_permute_inner_secret(sm->ssl_ctx, 273 data->ssl.conn, 274 buf, buf_len); 275 os_free(buf); 276 277 return ret; 278} 279#endif /* EAP_TTLS_VERSION */ 280 281 282static int eap_ttls_v0_derive_key(struct eap_sm *sm, 283 struct eap_ttls_data *data) 284{ 285 os_free(data->key_data); 286 data->key_data = eap_peer_tls_derive_key(sm, &data->ssl, 287 "ttls keying material", 288 EAP_TLS_KEY_LEN); 289 if (!data->key_data) { 290 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to derive key"); 291 return -1; 292 } 293 294 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key", 295 data->key_data, EAP_TLS_KEY_LEN); 296 297 return 0; 298} 299 300 301#if EAP_TTLS_VERSION > 0 302static int eap_ttls_v1_derive_key(struct eap_sm *sm, 303 struct eap_ttls_data *data) 304{ 305 struct tls_keys keys; 306 u8 *rnd; 307 308 os_free(data->key_data); 309 data->key_data = NULL; 310 311 os_memset(&keys, 0, sizeof(keys)); 312 if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) || 313 keys.client_random == NULL || keys.server_random == NULL || 314 keys.inner_secret == NULL) { 315 wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, " 316 "client random, or server random to derive keying " 317 "material"); 318 return -1; 319 } 320 321 rnd = os_malloc(keys.client_random_len + keys.server_random_len); 322 data->key_data = os_malloc(EAP_TLS_KEY_LEN); 323 if (rnd == NULL || data->key_data == NULL) { 324 wpa_printf(MSG_INFO, "EAP-TTLS: No memory for key derivation"); 325 os_free(rnd); 326 os_free(data->key_data); 327 data->key_data = NULL; 328 return -1; 329 } 330 os_memcpy(rnd, keys.client_random, keys.client_random_len); 331 os_memcpy(rnd + keys.client_random_len, keys.server_random, 332 keys.server_random_len); 333 334 if (tls_prf(keys.inner_secret, keys.inner_secret_len, 335 "ttls v1 keying material", rnd, keys.client_random_len + 336 keys.server_random_len, data->key_data, EAP_TLS_KEY_LEN)) { 337 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key"); 338 os_free(rnd); 339 os_free(data->key_data); 340 data->key_data = NULL; 341 return -1; 342 } 343 344 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: client/server random", 345 rnd, keys.client_random_len + keys.server_random_len); 346 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: TLS/IA inner secret", 347 keys.inner_secret, keys.inner_secret_len); 348 349 os_free(rnd); 350 351 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key", 352 data->key_data, EAP_TLS_KEY_LEN); 353 354 return 0; 355} 356#endif /* EAP_TTLS_VERSION */ 357 358 359static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm, 360 struct eap_ttls_data *data, size_t len) 361{ 362#if EAP_TTLS_VERSION > 0 363 struct tls_keys keys; 364 u8 *challenge, *rnd; 365#endif /* EAP_TTLS_VERSION */ 366 367 if (data->ttls_version == 0) { 368 return eap_peer_tls_derive_key(sm, &data->ssl, 369 "ttls challenge", len); 370 } 371 372#if EAP_TTLS_VERSION > 0 373 374 os_memset(&keys, 0, sizeof(keys)); 375 if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) || 376 keys.client_random == NULL || keys.server_random == NULL || 377 keys.inner_secret == NULL) { 378 wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, " 379 "client random, or server random to derive " 380 "implicit challenge"); 381 return NULL; 382 } 383 384 rnd = os_malloc(keys.client_random_len + keys.server_random_len); 385 challenge = os_malloc(len); 386 if (rnd == NULL || challenge == NULL) { 387 wpa_printf(MSG_INFO, "EAP-TTLS: No memory for implicit " 388 "challenge derivation"); 389 os_free(rnd); 390 os_free(challenge); 391 return NULL; 392 } 393 os_memcpy(rnd, keys.server_random, keys.server_random_len); 394 os_memcpy(rnd + keys.server_random_len, keys.client_random, 395 keys.client_random_len); 396 397 if (tls_prf(keys.inner_secret, keys.inner_secret_len, 398 "inner application challenge", rnd, 399 keys.client_random_len + keys.server_random_len, 400 challenge, len)) { 401 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive implicit " 402 "challenge"); 403 os_free(rnd); 404 os_free(challenge); 405 return NULL; 406 } 407 408 os_free(rnd); 409 410 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived implicit challenge", 411 challenge, len); 412 413 return challenge; 414 415#else /* EAP_TTLS_VERSION */ 416 417 return NULL; 418 419#endif /* EAP_TTLS_VERSION */ 420} 421 422 423static void eap_ttlsv1_phase2_eap_finish(struct eap_sm *sm, 424 struct eap_ttls_data *data, 425 struct eap_method_ret *ret) 426{ 427#if EAP_TTLS_VERSION > 0 428 if (data->ttls_version > 0) { 429 const struct eap_method *m = data->phase2_method; 430 void *priv = data->phase2_priv; 431 432 /* TTLSv1 requires TLS/IA FinalPhaseFinished */ 433 if (ret->decision == DECISION_UNCOND_SUCC) 434 ret->decision = DECISION_COND_SUCC; 435 ret->methodState = METHOD_CONT; 436 437 if (ret->decision == DECISION_COND_SUCC && 438 m->isKeyAvailable && m->getKey && 439 m->isKeyAvailable(sm, priv)) { 440 u8 *key; 441 size_t key_len; 442 key = m->getKey(sm, priv, &key_len); 443 if (key) { 444 eap_ttls_ia_permute_inner_secret( 445 sm, data, key, key_len); 446 os_free(key); 447 } 448 } 449 } 450#endif /* EAP_TTLS_VERSION */ 451} 452 453 454static void eap_ttls_phase2_select_eap_method(struct eap_ttls_data *data, 455 u8 method) 456{ 457 size_t i; 458 for (i = 0; i < data->num_phase2_eap_types; i++) { 459 if (data->phase2_eap_types[i].vendor != EAP_VENDOR_IETF || 460 data->phase2_eap_types[i].method != method) 461 continue; 462 463 data->phase2_eap_type.vendor = 464 data->phase2_eap_types[i].vendor; 465 data->phase2_eap_type.method = 466 data->phase2_eap_types[i].method; 467 wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected " 468 "Phase 2 EAP vendor %d method %d", 469 data->phase2_eap_type.vendor, 470 data->phase2_eap_type.method); 471 break; 472 } 473} 474 475 476static int eap_ttls_phase2_eap_process(struct eap_sm *sm, 477 struct eap_ttls_data *data, 478 struct eap_method_ret *ret, 479 struct eap_hdr *hdr, size_t len, 480 struct wpabuf **resp) 481{ 482 struct wpabuf msg; 483 struct eap_method_ret iret; 484 485 os_memset(&iret, 0, sizeof(iret)); 486 wpabuf_set(&msg, hdr, len); 487 *resp = data->phase2_method->process(sm, data->phase2_priv, &iret, 488 &msg); 489 if ((iret.methodState == METHOD_DONE || 490 iret.methodState == METHOD_MAY_CONT) && 491 (iret.decision == DECISION_UNCOND_SUCC || 492 iret.decision == DECISION_COND_SUCC || 493 iret.decision == DECISION_FAIL)) { 494 ret->methodState = iret.methodState; 495 ret->decision = iret.decision; 496 } 497 eap_ttlsv1_phase2_eap_finish(sm, data, ret); 498 499 return 0; 500} 501 502 503static int eap_ttls_phase2_request_eap_method(struct eap_sm *sm, 504 struct eap_ttls_data *data, 505 struct eap_method_ret *ret, 506 struct eap_hdr *hdr, size_t len, 507 u8 method, struct wpabuf **resp) 508{ 509#ifdef EAP_TNC 510 if (data->tnc_started && data->phase2_method && 511 data->phase2_priv && method == EAP_TYPE_TNC && 512 data->phase2_eap_type.method == EAP_TYPE_TNC) 513 return eap_ttls_phase2_eap_process(sm, data, ret, hdr, len, 514 resp); 515 516 if (data->ready_for_tnc && !data->tnc_started && 517 method == EAP_TYPE_TNC) { 518 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start TNC after completed " 519 "EAP method"); 520 data->tnc_started = 1; 521 } 522 523 if (data->tnc_started) { 524 if (data->phase2_eap_type.vendor != EAP_VENDOR_IETF || 525 data->phase2_eap_type.method == EAP_TYPE_TNC) { 526 wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected EAP " 527 "type %d for TNC", method); 528 return -1; 529 } 530 531 data->phase2_eap_type.vendor = EAP_VENDOR_IETF; 532 data->phase2_eap_type.method = method; 533 wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected " 534 "Phase 2 EAP vendor %d method %d (TNC)", 535 data->phase2_eap_type.vendor, 536 data->phase2_eap_type.method); 537 538 if (data->phase2_type == EAP_TTLS_PHASE2_EAP) 539 eap_ttls_phase2_eap_deinit(sm, data); 540 } 541#endif /* EAP_TNC */ 542 543 if (data->phase2_eap_type.vendor == EAP_VENDOR_IETF && 544 data->phase2_eap_type.method == EAP_TYPE_NONE) 545 eap_ttls_phase2_select_eap_method(data, method); 546 547 if (method != data->phase2_eap_type.method || method == EAP_TYPE_NONE) 548 { 549 if (eap_peer_tls_phase2_nak(data->phase2_eap_types, 550 data->num_phase2_eap_types, 551 hdr, resp)) 552 return -1; 553 return 0; 554 } 555 556 if (data->phase2_priv == NULL) { 557 data->phase2_method = eap_peer_get_eap_method( 558 EAP_VENDOR_IETF, method); 559 if (data->phase2_method) { 560 sm->init_phase2 = 1; 561 data->phase2_priv = data->phase2_method->init(sm); 562 sm->init_phase2 = 0; 563 } 564 } 565 if (data->phase2_priv == NULL || data->phase2_method == NULL) { 566 wpa_printf(MSG_INFO, "EAP-TTLS: failed to initialize " 567 "Phase 2 EAP method %d", method); 568 return -1; 569 } 570 571 return eap_ttls_phase2_eap_process(sm, data, ret, hdr, len, resp); 572} 573 574 575static int eap_ttls_phase2_request_eap(struct eap_sm *sm, 576 struct eap_ttls_data *data, 577 struct eap_method_ret *ret, 578 struct eap_hdr *hdr, 579 struct wpabuf **resp) 580{ 581 size_t len = be_to_host16(hdr->length); 582 u8 *pos; 583 struct eap_peer_config *config = eap_get_config(sm); 584 585 if (len <= sizeof(struct eap_hdr)) { 586 wpa_printf(MSG_INFO, "EAP-TTLS: too short " 587 "Phase 2 request (len=%lu)", (unsigned long) len); 588 return -1; 589 } 590 pos = (u8 *) (hdr + 1); 591 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP Request: type=%d", *pos); 592 switch (*pos) { 593 case EAP_TYPE_IDENTITY: 594 *resp = eap_sm_buildIdentity(sm, hdr->identifier, 1); 595 break; 596 default: 597 if (eap_ttls_phase2_request_eap_method(sm, data, ret, hdr, len, 598 *pos, resp) < 0) 599 return -1; 600 break; 601 } 602 603 if (*resp == NULL && 604 (config->pending_req_identity || config->pending_req_password || 605 config->pending_req_otp)) { 606 return 0; 607 } 608 609 if (*resp == NULL) 610 return -1; 611 612 wpa_hexdump_buf(MSG_DEBUG, "EAP-TTLS: AVP encapsulate EAP Response", 613 *resp); 614 return eap_ttls_avp_encapsulate(resp, RADIUS_ATTR_EAP_MESSAGE, 1); 615} 616 617 618static void eap_ttlsv1_permute_inner(struct eap_sm *sm, 619 struct eap_ttls_data *data) 620{ 621#if EAP_TTLS_VERSION > 0 622 u8 session_key[2 * MSCHAPV2_KEY_LEN]; 623 624 if (data->ttls_version == 0) 625 return; 626 627 get_asymetric_start_key(data->master_key, session_key, 628 MSCHAPV2_KEY_LEN, 0, 0); 629 get_asymetric_start_key(data->master_key, 630 session_key + MSCHAPV2_KEY_LEN, 631 MSCHAPV2_KEY_LEN, 1, 0); 632 eap_ttls_ia_permute_inner_secret(sm, data, session_key, 633 sizeof(session_key)); 634#endif /* EAP_TTLS_VERSION */ 635} 636 637 638static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm, 639 struct eap_ttls_data *data, 640 struct eap_method_ret *ret, 641 struct wpabuf **resp) 642{ 643 struct wpabuf *msg; 644 u8 *buf, *pos, *challenge, *peer_challenge; 645 const u8 *identity, *password; 646 size_t identity_len, password_len; 647 int pwhash; 648 649 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAPV2 Request"); 650 651 identity = eap_get_config_identity(sm, &identity_len); 652 password = eap_get_config_password2(sm, &password_len, &pwhash); 653 if (identity == NULL || password == NULL) 654 return -1; 655 656 msg = wpabuf_alloc(identity_len + 1000); 657 if (msg == NULL) { 658 wpa_printf(MSG_ERROR, 659 "EAP-TTLS/MSCHAPV2: Failed to allocate memory"); 660 return -1; 661 } 662 pos = buf = wpabuf_mhead(msg); 663 664 /* User-Name */ 665 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1, 666 identity, identity_len); 667 668 /* MS-CHAP-Challenge */ 669 challenge = eap_ttls_implicit_challenge( 670 sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1); 671 if (challenge == NULL) { 672 wpabuf_free(msg); 673 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive " 674 "implicit challenge"); 675 return -1; 676 } 677 peer_challenge = challenge + 1 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN; 678 679 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE, 680 RADIUS_VENDOR_ID_MICROSOFT, 1, 681 challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN); 682 683 /* MS-CHAP2-Response */ 684 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_RESPONSE, 685 RADIUS_VENDOR_ID_MICROSOFT, 1, 686 EAP_TTLS_MSCHAPV2_RESPONSE_LEN); 687 data->ident = challenge[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]; 688 *pos++ = data->ident; 689 *pos++ = 0; /* Flags */ 690 os_memcpy(pos, peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN); 691 pos += EAP_TTLS_MSCHAPV2_CHALLENGE_LEN; 692 os_memset(pos, 0, 8); /* Reserved, must be zero */ 693 pos += 8; 694 mschapv2_derive_response(identity, identity_len, password, 695 password_len, pwhash, challenge, 696 peer_challenge, pos, data->auth_response, 697 data->master_key); 698 data->auth_response_valid = 1; 699 700 eap_ttlsv1_permute_inner(sm, data); 701 702 pos += 24; 703 os_free(challenge); 704 AVP_PAD(buf, pos); 705 706 wpabuf_put(msg, pos - buf); 707 *resp = msg; 708 709 if (sm->workaround && data->ttls_version == 0) { 710 /* At least FreeRADIUS seems to be terminating 711 * EAP-TTLS/MSHCAPV2 without the expected MS-CHAP-v2 Success 712 * packet. */ 713 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: EAP workaround - " 714 "allow success without tunneled response"); 715 ret->methodState = METHOD_MAY_CONT; 716 ret->decision = DECISION_COND_SUCC; 717 } 718 719 return 0; 720} 721 722 723static int eap_ttls_phase2_request_mschap(struct eap_sm *sm, 724 struct eap_ttls_data *data, 725 struct eap_method_ret *ret, 726 struct wpabuf **resp) 727{ 728 struct wpabuf *msg; 729 u8 *buf, *pos, *challenge; 730 const u8 *identity, *password; 731 size_t identity_len, password_len; 732 int pwhash; 733 734 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAP Request"); 735 736 identity = eap_get_config_identity(sm, &identity_len); 737 password = eap_get_config_password2(sm, &password_len, &pwhash); 738 if (identity == NULL || password == NULL) 739 return -1; 740 741 msg = wpabuf_alloc(identity_len + 1000); 742 if (msg == NULL) { 743 wpa_printf(MSG_ERROR, 744 "EAP-TTLS/MSCHAP: Failed to allocate memory"); 745 return -1; 746 } 747 pos = buf = wpabuf_mhead(msg); 748 749 /* User-Name */ 750 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1, 751 identity, identity_len); 752 753 /* MS-CHAP-Challenge */ 754 challenge = eap_ttls_implicit_challenge( 755 sm, data, EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1); 756 if (challenge == NULL) { 757 wpabuf_free(msg); 758 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive " 759 "implicit challenge"); 760 return -1; 761 } 762 763 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE, 764 RADIUS_VENDOR_ID_MICROSOFT, 1, 765 challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN); 766 767 /* MS-CHAP-Response */ 768 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_RESPONSE, 769 RADIUS_VENDOR_ID_MICROSOFT, 1, 770 EAP_TTLS_MSCHAP_RESPONSE_LEN); 771 data->ident = challenge[EAP_TTLS_MSCHAP_CHALLENGE_LEN]; 772 *pos++ = data->ident; 773 *pos++ = 1; /* Flags: Use NT style passwords */ 774 os_memset(pos, 0, 24); /* LM-Response */ 775 pos += 24; 776 if (pwhash) { 777 challenge_response(challenge, password, pos); /* NT-Response */ 778 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password hash", 779 password, 16); 780 } else { 781 nt_challenge_response(challenge, password, password_len, 782 pos); /* NT-Response */ 783 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password", 784 password, password_len); 785 } 786 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP implicit challenge", 787 challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN); 788 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP response", pos, 24); 789 pos += 24; 790 os_free(challenge); 791 AVP_PAD(buf, pos); 792 793 wpabuf_put(msg, pos - buf); 794 *resp = msg; 795 796 if (data->ttls_version > 0) { 797 /* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success, 798 * so do not allow connection to be terminated yet. */ 799 ret->methodState = METHOD_CONT; 800 ret->decision = DECISION_COND_SUCC; 801 } else { 802 /* EAP-TTLS/MSCHAP does not provide tunneled success 803 * notification, so assume that Phase2 succeeds. */ 804 ret->methodState = METHOD_DONE; 805 ret->decision = DECISION_COND_SUCC; 806 } 807 808 return 0; 809} 810 811 812static int eap_ttls_phase2_request_pap(struct eap_sm *sm, 813 struct eap_ttls_data *data, 814 struct eap_method_ret *ret, 815 struct wpabuf **resp) 816{ 817 struct wpabuf *msg; 818 u8 *buf, *pos; 819 size_t pad; 820 const u8 *identity, *password; 821 size_t identity_len, password_len; 822 823 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 PAP Request"); 824 825 identity = eap_get_config_identity(sm, &identity_len); 826 password = eap_get_config_password(sm, &password_len); 827 if (identity == NULL || password == NULL) 828 return -1; 829 830 msg = wpabuf_alloc(identity_len + password_len + 100); 831 if (msg == NULL) { 832 wpa_printf(MSG_ERROR, 833 "EAP-TTLS/PAP: Failed to allocate memory"); 834 return -1; 835 } 836 pos = buf = wpabuf_mhead(msg); 837 838 /* User-Name */ 839 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1, 840 identity, identity_len); 841 842 /* User-Password; in RADIUS, this is encrypted, but EAP-TTLS encrypts 843 * the data, so no separate encryption is used in the AVP itself. 844 * However, the password is padded to obfuscate its length. */ 845 pad = password_len == 0 ? 16 : (16 - (password_len & 15)) & 15; 846 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_USER_PASSWORD, 0, 1, 847 password_len + pad); 848 os_memcpy(pos, password, password_len); 849 pos += password_len; 850 os_memset(pos, 0, pad); 851 pos += pad; 852 AVP_PAD(buf, pos); 853 854 wpabuf_put(msg, pos - buf); 855 *resp = msg; 856 857 if (data->ttls_version > 0) { 858 /* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success, 859 * so do not allow connection to be terminated yet. */ 860 ret->methodState = METHOD_CONT; 861 ret->decision = DECISION_COND_SUCC; 862 } else { 863 /* EAP-TTLS/PAP does not provide tunneled success notification, 864 * so assume that Phase2 succeeds. */ 865 ret->methodState = METHOD_DONE; 866 ret->decision = DECISION_COND_SUCC; 867 } 868 869 return 0; 870} 871 872 873static int eap_ttls_phase2_request_chap(struct eap_sm *sm, 874 struct eap_ttls_data *data, 875 struct eap_method_ret *ret, 876 struct wpabuf **resp) 877{ 878 struct wpabuf *msg; 879 u8 *buf, *pos, *challenge; 880 const u8 *identity, *password; 881 size_t identity_len, password_len; 882 883 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 CHAP Request"); 884 885 identity = eap_get_config_identity(sm, &identity_len); 886 password = eap_get_config_password(sm, &password_len); 887 if (identity == NULL || password == NULL) 888 return -1; 889 890 msg = wpabuf_alloc(identity_len + 1000); 891 if (msg == NULL) { 892 wpa_printf(MSG_ERROR, 893 "EAP-TTLS/CHAP: Failed to allocate memory"); 894 return -1; 895 } 896 pos = buf = wpabuf_mhead(msg); 897 898 /* User-Name */ 899 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1, 900 identity, identity_len); 901 902 /* CHAP-Challenge */ 903 challenge = eap_ttls_implicit_challenge( 904 sm, data, EAP_TTLS_CHAP_CHALLENGE_LEN + 1); 905 if (challenge == NULL) { 906 wpabuf_free(msg); 907 wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive " 908 "implicit challenge"); 909 return -1; 910 } 911 912 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_CHAP_CHALLENGE, 0, 1, 913 challenge, EAP_TTLS_CHAP_CHALLENGE_LEN); 914 915 /* CHAP-Password */ 916 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_CHAP_PASSWORD, 0, 1, 917 1 + EAP_TTLS_CHAP_PASSWORD_LEN); 918 data->ident = challenge[EAP_TTLS_CHAP_CHALLENGE_LEN]; 919 *pos++ = data->ident; 920 921 /* MD5(Ident + Password + Challenge) */ 922 chap_md5(data->ident, password, password_len, challenge, 923 EAP_TTLS_CHAP_CHALLENGE_LEN, pos); 924 925 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: CHAP username", 926 identity, identity_len); 927 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: CHAP password", 928 password, password_len); 929 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP implicit challenge", 930 challenge, EAP_TTLS_CHAP_CHALLENGE_LEN); 931 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP password", 932 pos, EAP_TTLS_CHAP_PASSWORD_LEN); 933 pos += EAP_TTLS_CHAP_PASSWORD_LEN; 934 os_free(challenge); 935 AVP_PAD(buf, pos); 936 937 wpabuf_put(msg, pos - buf); 938 *resp = msg; 939 940 if (data->ttls_version > 0) { 941 /* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success, 942 * so do not allow connection to be terminated yet. */ 943 ret->methodState = METHOD_CONT; 944 ret->decision = DECISION_COND_SUCC; 945 } else { 946 /* EAP-TTLS/CHAP does not provide tunneled success 947 * notification, so assume that Phase2 succeeds. */ 948 ret->methodState = METHOD_DONE; 949 ret->decision = DECISION_COND_SUCC; 950 } 951 952 return 0; 953} 954 955 956static int eap_ttls_phase2_request(struct eap_sm *sm, 957 struct eap_ttls_data *data, 958 struct eap_method_ret *ret, 959 struct eap_hdr *hdr, 960 struct wpabuf **resp) 961{ 962 int res = 0; 963 size_t len; 964 enum phase2_types phase2_type = data->phase2_type; 965 966#ifdef EAP_TNC 967 if (data->tnc_started) { 968 wpa_printf(MSG_DEBUG, "EAP-TTLS: Processing TNC"); 969 phase2_type = EAP_TTLS_PHASE2_EAP; 970 } 971#endif /* EAP_TNC */ 972 973 if (phase2_type == EAP_TTLS_PHASE2_MSCHAPV2 || 974 phase2_type == EAP_TTLS_PHASE2_MSCHAP || 975 phase2_type == EAP_TTLS_PHASE2_PAP || 976 phase2_type == EAP_TTLS_PHASE2_CHAP) { 977 if (eap_get_config_identity(sm, &len) == NULL) { 978 wpa_printf(MSG_INFO, 979 "EAP-TTLS: Identity not configured"); 980 eap_sm_request_identity(sm); 981 if (eap_get_config_password(sm, &len) == NULL) 982 eap_sm_request_password(sm); 983 return 0; 984 } 985 986 if (eap_get_config_password(sm, &len) == NULL) { 987 wpa_printf(MSG_INFO, 988 "EAP-TTLS: Password not configured"); 989 eap_sm_request_password(sm); 990 return 0; 991 } 992 } 993 994 switch (phase2_type) { 995 case EAP_TTLS_PHASE2_EAP: 996 res = eap_ttls_phase2_request_eap(sm, data, ret, hdr, resp); 997 break; 998 case EAP_TTLS_PHASE2_MSCHAPV2: 999 res = eap_ttls_phase2_request_mschapv2(sm, data, ret, resp); 1000 break; 1001 case EAP_TTLS_PHASE2_MSCHAP: 1002 res = eap_ttls_phase2_request_mschap(sm, data, ret, resp); 1003 break; 1004 case EAP_TTLS_PHASE2_PAP: 1005 res = eap_ttls_phase2_request_pap(sm, data, ret, resp); 1006 break; 1007 case EAP_TTLS_PHASE2_CHAP: 1008 res = eap_ttls_phase2_request_chap(sm, data, ret, resp); 1009 break; 1010 default: 1011 wpa_printf(MSG_ERROR, "EAP-TTLS: Phase 2 - Unknown"); 1012 res = -1; 1013 break; 1014 } 1015 1016 if (res < 0) { 1017 ret->methodState = METHOD_DONE; 1018 ret->decision = DECISION_FAIL; 1019 } 1020 1021 return res; 1022} 1023 1024 1025#if EAP_TTLS_VERSION > 0 1026static struct wpabuf * eap_ttls_build_phase_finished( 1027 struct eap_sm *sm, struct eap_ttls_data *data, int id, int final) 1028{ 1029 int len; 1030 struct wpabuf *req; 1031 u8 *pos; 1032 const int max_len = 300; 1033 1034 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1 + max_len, 1035 EAP_CODE_RESPONSE, id); 1036 if (req == NULL) 1037 return NULL; 1038 1039 wpabuf_put_u8(req, data->ttls_version); 1040 1041 pos = wpabuf_put(req, 0); 1042 len = tls_connection_ia_send_phase_finished(sm->ssl_ctx, 1043 data->ssl.conn, 1044 final, pos, max_len); 1045 if (len < 0) { 1046 wpabuf_free(req); 1047 return NULL; 1048 } 1049 wpabuf_put(req, len); 1050 eap_update_len(req); 1051 1052 return req; 1053} 1054#endif /* EAP_TTLS_VERSION */ 1055 1056 1057struct ttls_parse_avp { 1058 u8 *mschapv2; 1059 u8 *eapdata; 1060 size_t eap_len; 1061 int mschapv2_error; 1062}; 1063 1064 1065static int eap_ttls_parse_attr_eap(const u8 *dpos, size_t dlen, 1066 struct ttls_parse_avp *parse) 1067{ 1068 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message"); 1069 if (parse->eapdata == NULL) { 1070 parse->eapdata = os_malloc(dlen); 1071 if (parse->eapdata == NULL) { 1072 wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate " 1073 "memory for Phase 2 EAP data"); 1074 return -1; 1075 } 1076 os_memcpy(parse->eapdata, dpos, dlen); 1077 parse->eap_len = dlen; 1078 } else { 1079 u8 *neweap = os_realloc(parse->eapdata, parse->eap_len + dlen); 1080 if (neweap == NULL) { 1081 wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate " 1082 "memory for Phase 2 EAP data"); 1083 return -1; 1084 } 1085 os_memcpy(neweap + parse->eap_len, dpos, dlen); 1086 parse->eapdata = neweap; 1087 parse->eap_len += dlen; 1088 } 1089 1090 return 0; 1091} 1092 1093 1094static int eap_ttls_parse_avp(u8 *pos, size_t left, 1095 struct ttls_parse_avp *parse) 1096{ 1097 struct ttls_avp *avp; 1098 u32 avp_code, avp_length, vendor_id = 0; 1099 u8 avp_flags, *dpos; 1100 size_t dlen; 1101 1102 avp = (struct ttls_avp *) pos; 1103 avp_code = be_to_host32(avp->avp_code); 1104 avp_length = be_to_host32(avp->avp_length); 1105 avp_flags = (avp_length >> 24) & 0xff; 1106 avp_length &= 0xffffff; 1107 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x " 1108 "length=%d", (int) avp_code, avp_flags, 1109 (int) avp_length); 1110 1111 if (avp_length > left) { 1112 wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow " 1113 "(len=%d, left=%lu) - dropped", 1114 (int) avp_length, (unsigned long) left); 1115 return -1; 1116 } 1117 1118 if (avp_length < sizeof(*avp)) { 1119 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length %d", 1120 avp_length); 1121 return -1; 1122 } 1123 1124 dpos = (u8 *) (avp + 1); 1125 dlen = avp_length - sizeof(*avp); 1126 if (avp_flags & AVP_FLAGS_VENDOR) { 1127 if (dlen < 4) { 1128 wpa_printf(MSG_WARNING, "EAP-TTLS: Vendor AVP " 1129 "underflow"); 1130 return -1; 1131 } 1132 vendor_id = WPA_GET_BE32(dpos); 1133 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d", 1134 (int) vendor_id); 1135 dpos += 4; 1136 dlen -= 4; 1137 } 1138 1139 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen); 1140 1141 if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) { 1142 if (eap_ttls_parse_attr_eap(dpos, dlen, parse) < 0) 1143 return -1; 1144 } else if (vendor_id == 0 && avp_code == RADIUS_ATTR_REPLY_MESSAGE) { 1145 /* This is an optional message that can be displayed to 1146 * the user. */ 1147 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: AVP - Reply-Message", 1148 dpos, dlen); 1149 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT && 1150 avp_code == RADIUS_ATTR_MS_CHAP2_SUCCESS) { 1151 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP2-Success", 1152 dpos, dlen); 1153 if (dlen != 43) { 1154 wpa_printf(MSG_WARNING, "EAP-TTLS: Unexpected " 1155 "MS-CHAP2-Success length " 1156 "(len=%lu, expected 43)", 1157 (unsigned long) dlen); 1158 return -1; 1159 } 1160 parse->mschapv2 = dpos; 1161 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT && 1162 avp_code == RADIUS_ATTR_MS_CHAP_ERROR) { 1163 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP-Error", 1164 dpos, dlen); 1165 parse->mschapv2_error = 1; 1166 } else if (avp_flags & AVP_FLAGS_MANDATORY) { 1167 wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported mandatory AVP " 1168 "code %d vendor_id %d - dropped", 1169 (int) avp_code, (int) vendor_id); 1170 return -1; 1171 } else { 1172 wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported AVP " 1173 "code %d vendor_id %d", 1174 (int) avp_code, (int) vendor_id); 1175 } 1176 1177 return avp_length; 1178} 1179 1180 1181static int eap_ttls_parse_avps(struct wpabuf *in_decrypted, 1182 struct ttls_parse_avp *parse) 1183{ 1184 u8 *pos; 1185 size_t left, pad; 1186 int avp_length; 1187 1188 pos = wpabuf_mhead(in_decrypted); 1189 left = wpabuf_len(in_decrypted); 1190 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 AVPs", pos, left); 1191 if (left < sizeof(struct ttls_avp)) { 1192 wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 AVP frame" 1193 " len=%lu expected %lu or more - dropped", 1194 (unsigned long) left, 1195 (unsigned long) sizeof(struct ttls_avp)); 1196 return -1; 1197 } 1198 1199 /* Parse AVPs */ 1200 os_memset(parse, 0, sizeof(*parse)); 1201 1202 while (left > 0) { 1203 avp_length = eap_ttls_parse_avp(pos, left, parse); 1204 if (avp_length < 0) 1205 return -1; 1206 1207 pad = (4 - (avp_length & 3)) & 3; 1208 pos += avp_length + pad; 1209 if (left < avp_length + pad) 1210 left = 0; 1211 else 1212 left -= avp_length + pad; 1213 } 1214 1215 return 0; 1216} 1217 1218 1219static u8 * eap_ttls_fake_identity_request(void) 1220{ 1221 struct eap_hdr *hdr; 1222 u8 *buf; 1223 1224 wpa_printf(MSG_DEBUG, "EAP-TTLS: empty data in beginning of " 1225 "Phase 2 - use fake EAP-Request Identity"); 1226 buf = os_malloc(sizeof(*hdr) + 1); 1227 if (buf == NULL) { 1228 wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate " 1229 "memory for fake EAP-Identity Request"); 1230 return NULL; 1231 } 1232 1233 hdr = (struct eap_hdr *) buf; 1234 hdr->code = EAP_CODE_REQUEST; 1235 hdr->identifier = 0; 1236 hdr->length = host_to_be16(sizeof(*hdr) + 1); 1237 buf[sizeof(*hdr)] = EAP_TYPE_IDENTITY; 1238 1239 return buf; 1240} 1241 1242 1243static int eap_ttls_encrypt_response(struct eap_sm *sm, 1244 struct eap_ttls_data *data, 1245 struct wpabuf *resp, u8 identifier, 1246 struct wpabuf **out_data) 1247{ 1248 if (resp == NULL) 1249 return 0; 1250 1251 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Encrypting Phase 2 data", 1252 resp); 1253 if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS, 1254 data->ttls_version, identifier, 1255 resp, out_data)) { 1256 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt a Phase 2 " 1257 "frame"); 1258 return -1; 1259 } 1260 wpabuf_free(resp); 1261 1262 return 0; 1263} 1264 1265 1266static int eap_ttls_process_phase2_eap(struct eap_sm *sm, 1267 struct eap_ttls_data *data, 1268 struct eap_method_ret *ret, 1269 struct ttls_parse_avp *parse, 1270 struct wpabuf **resp) 1271{ 1272 struct eap_hdr *hdr; 1273 size_t len; 1274 1275 if (parse->eapdata == NULL) { 1276 wpa_printf(MSG_WARNING, "EAP-TTLS: No EAP Message in the " 1277 "packet - dropped"); 1278 return -1; 1279 } 1280 1281 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP", 1282 parse->eapdata, parse->eap_len); 1283 hdr = (struct eap_hdr *) parse->eapdata; 1284 1285 if (parse->eap_len < sizeof(*hdr)) { 1286 wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 EAP " 1287 "frame (len=%lu, expected %lu or more) - dropped", 1288 (unsigned long) parse->eap_len, 1289 (unsigned long) sizeof(*hdr)); 1290 return -1; 1291 } 1292 len = be_to_host16(hdr->length); 1293 if (len > parse->eap_len) { 1294 wpa_printf(MSG_INFO, "EAP-TTLS: Length mismatch in Phase 2 " 1295 "EAP frame (EAP hdr len=%lu, EAP data len in " 1296 "AVP=%lu)", 1297 (unsigned long) len, 1298 (unsigned long) parse->eap_len); 1299 return -1; 1300 } 1301 wpa_printf(MSG_DEBUG, "EAP-TTLS: received Phase 2: code=%d " 1302 "identifier=%d length=%lu", 1303 hdr->code, hdr->identifier, (unsigned long) len); 1304 switch (hdr->code) { 1305 case EAP_CODE_REQUEST: 1306 if (eap_ttls_phase2_request(sm, data, ret, hdr, resp)) { 1307 wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request " 1308 "processing failed"); 1309 return -1; 1310 } 1311 break; 1312 default: 1313 wpa_printf(MSG_INFO, "EAP-TTLS: Unexpected code=%d in " 1314 "Phase 2 EAP header", hdr->code); 1315 return -1; 1316 } 1317 1318 return 0; 1319} 1320 1321 1322static int eap_ttls_process_phase2_mschapv2(struct eap_sm *sm, 1323 struct eap_ttls_data *data, 1324 struct eap_method_ret *ret, 1325 struct ttls_parse_avp *parse) 1326{ 1327 if (parse->mschapv2_error) { 1328 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Received " 1329 "MS-CHAP-Error - failed"); 1330 ret->methodState = METHOD_DONE; 1331 ret->decision = DECISION_FAIL; 1332 /* Reply with empty data to ACK error */ 1333 return 1; 1334 } 1335 1336 if (parse->mschapv2 == NULL) { 1337#ifdef EAP_TNC 1338 if (data->phase2_success && parse->eapdata) { 1339 /* 1340 * Allow EAP-TNC to be started after successfully 1341 * completed MSCHAPV2. 1342 */ 1343 return 1; 1344 } 1345#endif /* EAP_TNC */ 1346 wpa_printf(MSG_WARNING, "EAP-TTLS: no MS-CHAP2-Success AVP " 1347 "received for Phase2 MSCHAPV2"); 1348 return -1; 1349 } 1350 if (parse->mschapv2[0] != data->ident) { 1351 wpa_printf(MSG_WARNING, "EAP-TTLS: Ident mismatch for Phase 2 " 1352 "MSCHAPV2 (received Ident 0x%02x, expected 0x%02x)", 1353 parse->mschapv2[0], data->ident); 1354 return -1; 1355 } 1356 if (!data->auth_response_valid || 1357 mschapv2_verify_auth_response(data->auth_response, 1358 parse->mschapv2 + 1, 42)) { 1359 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid authenticator " 1360 "response in Phase 2 MSCHAPV2 success request"); 1361 return -1; 1362 } 1363 1364 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 MSCHAPV2 " 1365 "authentication succeeded"); 1366 if (data->ttls_version > 0) { 1367 /* 1368 * EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report 1369 * success, so do not allow connection to be terminated 1370 * yet. 1371 */ 1372 ret->methodState = METHOD_CONT; 1373 ret->decision = DECISION_COND_SUCC; 1374 } else { 1375 ret->methodState = METHOD_DONE; 1376 ret->decision = DECISION_UNCOND_SUCC; 1377 data->phase2_success = 1; 1378 } 1379 1380 /* 1381 * Reply with empty data; authentication server will reply 1382 * with EAP-Success after this. 1383 */ 1384 return 1; 1385} 1386 1387 1388#ifdef EAP_TNC 1389static int eap_ttls_process_tnc_start(struct eap_sm *sm, 1390 struct eap_ttls_data *data, 1391 struct eap_method_ret *ret, 1392 struct ttls_parse_avp *parse, 1393 struct wpabuf **resp) 1394{ 1395 /* TNC uses inner EAP method after non-EAP TTLS phase 2. */ 1396 if (parse->eapdata == NULL) { 1397 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received " 1398 "unexpected tunneled data (no EAP)"); 1399 return -1; 1400 } 1401 1402 if (!data->ready_for_tnc) { 1403 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received " 1404 "EAP after non-EAP, but not ready for TNC"); 1405 return -1; 1406 } 1407 1408 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start TNC after completed " 1409 "non-EAP method"); 1410 data->tnc_started = 1; 1411 1412 if (eap_ttls_process_phase2_eap(sm, data, ret, parse, resp) < 0) 1413 return -1; 1414 1415 return 0; 1416} 1417#endif /* EAP_TNC */ 1418 1419 1420static int eap_ttls_process_decrypted(struct eap_sm *sm, 1421 struct eap_ttls_data *data, 1422 struct eap_method_ret *ret, 1423 u8 identifier, 1424 struct ttls_parse_avp *parse, 1425 struct wpabuf *in_decrypted, 1426 struct wpabuf **out_data) 1427{ 1428 struct wpabuf *resp = NULL; 1429 struct eap_peer_config *config = eap_get_config(sm); 1430 int res; 1431 enum phase2_types phase2_type = data->phase2_type; 1432 1433#ifdef EAP_TNC 1434 if (data->tnc_started) 1435 phase2_type = EAP_TTLS_PHASE2_EAP; 1436#endif /* EAP_TNC */ 1437 1438 switch (phase2_type) { 1439 case EAP_TTLS_PHASE2_EAP: 1440 if (eap_ttls_process_phase2_eap(sm, data, ret, parse, &resp) < 1441 0) 1442 return -1; 1443 break; 1444 case EAP_TTLS_PHASE2_MSCHAPV2: 1445 res = eap_ttls_process_phase2_mschapv2(sm, data, ret, parse); 1446#ifdef EAP_TNC 1447 if (res == 1 && parse->eapdata && data->phase2_success) { 1448 /* 1449 * TNC may be required as the next 1450 * authentication method within the tunnel. 1451 */ 1452 ret->methodState = METHOD_MAY_CONT; 1453 data->ready_for_tnc = 1; 1454 if (eap_ttls_process_tnc_start(sm, data, ret, parse, 1455 &resp) == 0) 1456 break; 1457 } 1458#endif /* EAP_TNC */ 1459 return res; 1460 case EAP_TTLS_PHASE2_MSCHAP: 1461 case EAP_TTLS_PHASE2_PAP: 1462 case EAP_TTLS_PHASE2_CHAP: 1463#ifdef EAP_TNC 1464 if (eap_ttls_process_tnc_start(sm, data, ret, parse, &resp) < 1465 0) 1466 return -1; 1467 break; 1468#else /* EAP_TNC */ 1469 /* EAP-TTLS/{MSCHAP,PAP,CHAP} should not send any TLS tunneled 1470 * requests to the supplicant */ 1471 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received unexpected " 1472 "tunneled data"); 1473 return -1; 1474#endif /* EAP_TNC */ 1475 } 1476 1477 if (resp) { 1478 if (eap_ttls_encrypt_response(sm, data, resp, identifier, 1479 out_data) < 0) 1480 return -1; 1481 } else if (config->pending_req_identity || 1482 config->pending_req_password || 1483 config->pending_req_otp || 1484 config->pending_req_new_password) { 1485 wpabuf_free(data->pending_phase2_req); 1486 data->pending_phase2_req = wpabuf_dup(in_decrypted); 1487 } 1488 1489 return 0; 1490} 1491 1492 1493#if EAP_TTLS_VERSION > 0 1494static void eap_ttls_final_phase_finished(struct eap_sm *sm, 1495 struct eap_ttls_data *data, 1496 struct eap_method_ret *ret, 1497 u8 identifier, 1498 struct wpabuf **out_data) 1499{ 1500 wpa_printf(MSG_DEBUG, "EAP-TTLS: FinalPhaseFinished received"); 1501 wpa_printf(MSG_INFO, "EAP-TTLS: TLS/IA authentication succeeded"); 1502 ret->methodState = METHOD_DONE; 1503 ret->decision = DECISION_UNCOND_SUCC; 1504 data->phase2_success = 1; 1505 *out_data = eap_ttls_build_phase_finished(sm, data, identifier, 1); 1506 eap_ttls_v1_derive_key(sm, data); 1507} 1508#endif /* EAP_TTLS_VERSION */ 1509 1510 1511static int eap_ttls_implicit_identity_request(struct eap_sm *sm, 1512 struct eap_ttls_data *data, 1513 struct eap_method_ret *ret, 1514 u8 identifier, 1515 struct wpabuf **out_data) 1516{ 1517 int retval = 0; 1518 struct eap_hdr *hdr; 1519 struct wpabuf *resp; 1520 1521 hdr = (struct eap_hdr *) eap_ttls_fake_identity_request(); 1522 if (hdr == NULL) { 1523 ret->methodState = METHOD_DONE; 1524 ret->decision = DECISION_FAIL; 1525 return -1; 1526 } 1527 1528 resp = NULL; 1529 if (eap_ttls_phase2_request(sm, data, ret, hdr, &resp)) { 1530 wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request " 1531 "processing failed"); 1532 retval = -1; 1533 } else { 1534 retval = eap_ttls_encrypt_response(sm, data, resp, identifier, 1535 out_data); 1536 } 1537 1538 os_free(hdr); 1539 1540 if (retval < 0) { 1541 ret->methodState = METHOD_DONE; 1542 ret->decision = DECISION_FAIL; 1543 } 1544 1545 return retval; 1546} 1547 1548 1549static int eap_ttls_phase2_start(struct eap_sm *sm, struct eap_ttls_data *data, 1550 struct eap_method_ret *ret, u8 identifier, 1551 struct wpabuf **out_data) 1552{ 1553 data->phase2_start = 0; 1554 1555 /* 1556 * EAP-TTLS does not use Phase2 on fast re-auth; this must be done only 1557 * if TLS part was indeed resuming a previous session. Most 1558 * Authentication Servers terminate EAP-TTLS before reaching this 1559 * point, but some do not. Make wpa_supplicant stop phase 2 here, if 1560 * needed. 1561 */ 1562 if (data->reauth && 1563 tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) { 1564 wpa_printf(MSG_DEBUG, "EAP-TTLS: Session resumption - " 1565 "skip phase 2"); 1566 *out_data = eap_peer_tls_build_ack(identifier, EAP_TYPE_TTLS, 1567 data->ttls_version); 1568 ret->methodState = METHOD_DONE; 1569 ret->decision = DECISION_UNCOND_SUCC; 1570 data->phase2_success = 1; 1571 return 0; 1572 } 1573 1574 return eap_ttls_implicit_identity_request(sm, data, ret, identifier, 1575 out_data); 1576} 1577 1578 1579static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data, 1580 struct eap_method_ret *ret, u8 identifier, 1581 const struct wpabuf *in_data, 1582 struct wpabuf **out_data) 1583{ 1584 struct wpabuf *in_decrypted = NULL; 1585 int retval = 0; 1586 struct ttls_parse_avp parse; 1587 1588 os_memset(&parse, 0, sizeof(parse)); 1589 1590 wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for" 1591 " Phase 2", 1592 in_data ? (unsigned long) wpabuf_len(in_data) : 0); 1593 1594 if (data->pending_phase2_req) { 1595 wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 request - " 1596 "skip decryption and use old data"); 1597 /* Clear TLS reassembly state. */ 1598 eap_peer_tls_reset_input(&data->ssl); 1599 1600 in_decrypted = data->pending_phase2_req; 1601 data->pending_phase2_req = NULL; 1602 if (wpabuf_len(in_decrypted) == 0) { 1603 wpabuf_free(in_decrypted); 1604 return eap_ttls_implicit_identity_request( 1605 sm, data, ret, identifier, out_data); 1606 } 1607 goto continue_req; 1608 } 1609 1610 if ((in_data == NULL || wpabuf_len(in_data) == 0) && 1611 data->phase2_start) { 1612 return eap_ttls_phase2_start(sm, data, ret, identifier, 1613 out_data); 1614 } 1615 1616 if (in_data == NULL || wpabuf_len(in_data) == 0) { 1617 /* Received TLS ACK - requesting more fragments */ 1618 return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS, 1619 data->ttls_version, 1620 identifier, NULL, out_data); 1621 } 1622 1623 retval = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted); 1624 if (retval) 1625 goto done; 1626 1627#if EAP_TTLS_VERSION > 0 1628 if (data->ttls_version > 0 && 1629 (in_decrypted == NULL || wpabuf_len(in_decrypted) == 0) && 1630 tls_connection_ia_final_phase_finished(sm->ssl_ctx, 1631 data->ssl.conn)) { 1632 eap_ttls_final_phase_finished(sm, data, ret, identifier, 1633 out_data); 1634 goto done; 1635 } 1636#endif /* EAP_TTLS_VERSION */ 1637 1638continue_req: 1639 data->phase2_start = 0; 1640 1641 if (eap_ttls_parse_avps(in_decrypted, &parse) < 0) { 1642 retval = -1; 1643 goto done; 1644 } 1645 1646 retval = eap_ttls_process_decrypted(sm, data, ret, identifier, 1647 &parse, in_decrypted, out_data); 1648 1649done: 1650 wpabuf_free(in_decrypted); 1651 os_free(parse.eapdata); 1652 1653 if (retval < 0) { 1654 ret->methodState = METHOD_DONE; 1655 ret->decision = DECISION_FAIL; 1656 } 1657 1658 return retval; 1659} 1660 1661 1662static int eap_ttls_process_start(struct eap_sm *sm, 1663 struct eap_ttls_data *data, u8 flags, 1664 struct eap_method_ret *ret) 1665{ 1666 struct eap_peer_config *config = eap_get_config(sm); 1667 1668 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start (server ver=%d, own ver=%d)", 1669 flags & EAP_PEAP_VERSION_MASK, data->ttls_version); 1670#if EAP_TTLS_VERSION > 0 1671 if ((flags & EAP_PEAP_VERSION_MASK) < data->ttls_version) 1672 data->ttls_version = flags & EAP_PEAP_VERSION_MASK; 1673 if (data->force_ttls_version >= 0 && 1674 data->force_ttls_version != data->ttls_version) { 1675 wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to select " 1676 "forced TTLS version %d", 1677 data->force_ttls_version); 1678 ret->methodState = METHOD_DONE; 1679 ret->decision = DECISION_FAIL; 1680 ret->allowNotifications = FALSE; 1681 return -1; 1682 } 1683 wpa_printf(MSG_DEBUG, "EAP-TTLS: Using TTLS version %d", 1684 data->ttls_version); 1685 1686 if (data->ttls_version > 0) 1687 data->ssl.tls_ia = 1; 1688#endif /* EAP_TTLS_VERSION */ 1689 if (!data->ssl_initialized && 1690 eap_peer_tls_ssl_init(sm, &data->ssl, config)) { 1691 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL."); 1692 return -1; 1693 } 1694 data->ssl_initialized = 1; 1695 1696 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start"); 1697 1698 return 0; 1699} 1700 1701 1702static int eap_ttls_process_handshake(struct eap_sm *sm, 1703 struct eap_ttls_data *data, 1704 struct eap_method_ret *ret, 1705 u8 identifier, 1706 const u8 *in_data, size_t in_len, 1707 struct wpabuf **out_data) 1708{ 1709 int res; 1710 1711 res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS, 1712 data->ttls_version, identifier, 1713 in_data, in_len, out_data); 1714 1715 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { 1716 wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS done, proceed to " 1717 "Phase 2"); 1718 if (data->resuming) { 1719 wpa_printf(MSG_DEBUG, "EAP-TTLS: fast reauth - may " 1720 "skip Phase 2"); 1721 ret->decision = DECISION_COND_SUCC; 1722 ret->methodState = METHOD_MAY_CONT; 1723 } 1724 data->phase2_start = 1; 1725 if (data->ttls_version == 0) 1726 eap_ttls_v0_derive_key(sm, data); 1727 1728 if (*out_data == NULL || wpabuf_len(*out_data) == 0) { 1729 if (eap_ttls_decrypt(sm, data, ret, identifier, 1730 NULL, out_data)) { 1731 wpa_printf(MSG_WARNING, "EAP-TTLS: " 1732 "failed to process early " 1733 "start for Phase 2"); 1734 } 1735 res = 0; 1736 } 1737 data->resuming = 0; 1738 } 1739 1740 if (res == 2) { 1741 struct wpabuf msg; 1742 /* 1743 * Application data included in the handshake message. 1744 */ 1745 wpabuf_free(data->pending_phase2_req); 1746 data->pending_phase2_req = *out_data; 1747 *out_data = NULL; 1748 wpabuf_set(&msg, in_data, in_len); 1749 res = eap_ttls_decrypt(sm, data, ret, identifier, &msg, 1750 out_data); 1751 } 1752 1753 return res; 1754} 1755 1756 1757static void eap_ttls_check_auth_status(struct eap_sm *sm, 1758 struct eap_ttls_data *data, 1759 struct eap_method_ret *ret) 1760{ 1761 if (data->ttls_version == 0 && ret->methodState == METHOD_DONE) { 1762 ret->allowNotifications = FALSE; 1763 if (ret->decision == DECISION_UNCOND_SUCC || 1764 ret->decision == DECISION_COND_SUCC) { 1765 wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication " 1766 "completed successfully"); 1767 data->phase2_success = 1; 1768#ifdef EAP_TNC 1769 if (!data->ready_for_tnc && !data->tnc_started) { 1770 /* 1771 * TNC may be required as the next 1772 * authentication method within the tunnel. 1773 */ 1774 ret->methodState = METHOD_MAY_CONT; 1775 data->ready_for_tnc = 1; 1776 } 1777#endif /* EAP_TNC */ 1778 } 1779 } else if (data->ttls_version == 0 && 1780 ret->methodState == METHOD_MAY_CONT && 1781 (ret->decision == DECISION_UNCOND_SUCC || 1782 ret->decision == DECISION_COND_SUCC)) { 1783 wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication " 1784 "completed successfully (MAY_CONT)"); 1785 data->phase2_success = 1; 1786 } 1787} 1788 1789 1790static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv, 1791 struct eap_method_ret *ret, 1792 const struct wpabuf *reqData) 1793{ 1794 size_t left; 1795 int res; 1796 u8 flags, id; 1797 struct wpabuf *resp; 1798 const u8 *pos; 1799 struct eap_ttls_data *data = priv; 1800 1801 pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TTLS, ret, 1802 reqData, &left, &flags); 1803 if (pos == NULL) 1804 return NULL; 1805 id = eap_get_id(reqData); 1806 1807 if (flags & EAP_TLS_FLAGS_START) { 1808 if (eap_ttls_process_start(sm, data, flags, ret) < 0) 1809 return NULL; 1810 1811 /* RFC 5281, Ch. 9.2: 1812 * "This packet MAY contain additional information in the form 1813 * of AVPs, which may provide useful hints to the client" 1814 * For now, ignore any potential extra data. 1815 */ 1816 left = 0; 1817 } else if (!data->ssl_initialized) { 1818 wpa_printf(MSG_DEBUG, "EAP-TTLS: First message did not " 1819 "include Start flag"); 1820 ret->methodState = METHOD_DONE; 1821 ret->decision = DECISION_FAIL; 1822 ret->allowNotifications = FALSE; 1823 return NULL; 1824 } 1825 1826 resp = NULL; 1827 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) && 1828 !data->resuming) { 1829 struct wpabuf msg; 1830 wpabuf_set(&msg, pos, left); 1831 res = eap_ttls_decrypt(sm, data, ret, id, &msg, &resp); 1832 } else { 1833 res = eap_ttls_process_handshake(sm, data, ret, id, 1834 pos, left, &resp); 1835 } 1836 1837 eap_ttls_check_auth_status(sm, data, ret); 1838 1839 /* FIX: what about res == -1? Could just move all error processing into 1840 * the other functions and get rid of this res==1 case here. */ 1841 if (res == 1) { 1842 wpabuf_free(resp); 1843 return eap_peer_tls_build_ack(id, EAP_TYPE_TTLS, 1844 data->ttls_version); 1845 } 1846 return resp; 1847} 1848 1849 1850static Boolean eap_ttls_has_reauth_data(struct eap_sm *sm, void *priv) 1851{ 1852 struct eap_ttls_data *data = priv; 1853 return tls_connection_established(sm->ssl_ctx, data->ssl.conn) && 1854 data->phase2_success; 1855} 1856 1857 1858static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv) 1859{ 1860 struct eap_ttls_data *data = priv; 1861 wpabuf_free(data->pending_phase2_req); 1862 data->pending_phase2_req = NULL; 1863#ifdef EAP_TNC 1864 data->ready_for_tnc = 0; 1865 data->tnc_started = 0; 1866#endif /* EAP_TNC */ 1867} 1868 1869 1870static void * eap_ttls_init_for_reauth(struct eap_sm *sm, void *priv) 1871{ 1872 struct eap_ttls_data *data = priv; 1873 os_free(data->key_data); 1874 data->key_data = NULL; 1875 if (eap_peer_tls_reauth_init(sm, &data->ssl)) { 1876 os_free(data); 1877 return NULL; 1878 } 1879 if (data->phase2_priv && data->phase2_method && 1880 data->phase2_method->init_for_reauth) 1881 data->phase2_method->init_for_reauth(sm, data->phase2_priv); 1882 data->phase2_start = 0; 1883 data->phase2_success = 0; 1884 data->resuming = 1; 1885 data->reauth = 1; 1886 return priv; 1887} 1888 1889 1890static int eap_ttls_get_status(struct eap_sm *sm, void *priv, char *buf, 1891 size_t buflen, int verbose) 1892{ 1893 struct eap_ttls_data *data = priv; 1894 int len, ret; 1895 1896 len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose); 1897 ret = os_snprintf(buf + len, buflen - len, 1898 "EAP-TTLSv%d Phase2 method=", 1899 data->ttls_version); 1900 if (ret < 0 || (size_t) ret >= buflen - len) 1901 return len; 1902 len += ret; 1903 switch (data->phase2_type) { 1904 case EAP_TTLS_PHASE2_EAP: 1905 ret = os_snprintf(buf + len, buflen - len, "EAP-%s\n", 1906 data->phase2_method ? 1907 data->phase2_method->name : "?"); 1908 break; 1909 case EAP_TTLS_PHASE2_MSCHAPV2: 1910 ret = os_snprintf(buf + len, buflen - len, "MSCHAPV2\n"); 1911 break; 1912 case EAP_TTLS_PHASE2_MSCHAP: 1913 ret = os_snprintf(buf + len, buflen - len, "MSCHAP\n"); 1914 break; 1915 case EAP_TTLS_PHASE2_PAP: 1916 ret = os_snprintf(buf + len, buflen - len, "PAP\n"); 1917 break; 1918 case EAP_TTLS_PHASE2_CHAP: 1919 ret = os_snprintf(buf + len, buflen - len, "CHAP\n"); 1920 break; 1921 default: 1922 ret = 0; 1923 break; 1924 } 1925 if (ret < 0 || (size_t) ret >= buflen - len) 1926 return len; 1927 len += ret; 1928 1929 return len; 1930} 1931 1932 1933static Boolean eap_ttls_isKeyAvailable(struct eap_sm *sm, void *priv) 1934{ 1935 struct eap_ttls_data *data = priv; 1936 return data->key_data != NULL && data->phase2_success; 1937} 1938 1939 1940static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len) 1941{ 1942 struct eap_ttls_data *data = priv; 1943 u8 *key; 1944 1945 if (data->key_data == NULL || !data->phase2_success) 1946 return NULL; 1947 1948 key = os_malloc(EAP_TLS_KEY_LEN); 1949 if (key == NULL) 1950 return NULL; 1951 1952 *len = EAP_TLS_KEY_LEN; 1953 os_memcpy(key, data->key_data, EAP_TLS_KEY_LEN); 1954 1955 return key; 1956} 1957 1958 1959int eap_peer_ttls_register(void) 1960{ 1961 struct eap_method *eap; 1962 int ret; 1963 1964 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 1965 EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS"); 1966 if (eap == NULL) 1967 return -1; 1968 1969 eap->init = eap_ttls_init; 1970 eap->deinit = eap_ttls_deinit; 1971 eap->process = eap_ttls_process; 1972 eap->isKeyAvailable = eap_ttls_isKeyAvailable; 1973 eap->getKey = eap_ttls_getKey; 1974 eap->get_status = eap_ttls_get_status; 1975 eap->has_reauth_data = eap_ttls_has_reauth_data; 1976 eap->deinit_for_reauth = eap_ttls_deinit_for_reauth; 1977 eap->init_for_reauth = eap_ttls_init_for_reauth; 1978 1979 ret = eap_peer_method_register(eap); 1980 if (ret) 1981 eap_peer_method_free(eap); 1982 return ret; 1983} 1984