00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto/ms_funcs.h"
00019 #include "crypto/sha1.h"
00020 #include "crypto/tls.h"
00021 #include "eap_common/chap.h"
00022 #include "eap_common/eap_ttls.h"
00023 #include "mschapv2.h"
00024 #include "eap_i.h"
00025 #include "eap_tls_common.h"
00026 #include "eap_config.h"
00027
00028
00029
00030
00031
00032
00033 #ifndef EAP_TTLS_VERSION
00034 #define EAP_TTLS_VERSION 0
00035 #endif
00036
00037
00038 #define MSCHAPV2_KEY_LEN 16
00039 #define MSCHAPV2_NT_RESPONSE_LEN 24
00040
00041
00042 static void eap_ttls_deinit(struct eap_sm *sm, void *priv);
00043
00044
00045 struct eap_ttls_data {
00046 struct eap_ssl_data ssl;
00047 int ssl_initialized;
00048
00049 int ttls_version, force_ttls_version;
00050
00051 const struct eap_method *phase2_method;
00052 void *phase2_priv;
00053 int phase2_success;
00054 int phase2_start;
00055
00056 enum phase2_types {
00057 EAP_TTLS_PHASE2_EAP,
00058 EAP_TTLS_PHASE2_MSCHAPV2,
00059 EAP_TTLS_PHASE2_MSCHAP,
00060 EAP_TTLS_PHASE2_PAP,
00061 EAP_TTLS_PHASE2_CHAP
00062 } phase2_type;
00063 struct eap_method_type phase2_eap_type;
00064 struct eap_method_type *phase2_eap_types;
00065 size_t num_phase2_eap_types;
00066
00067 u8 auth_response[MSCHAPV2_AUTH_RESPONSE_LEN];
00068 int auth_response_valid;
00069 u8 master_key[MSCHAPV2_MASTER_KEY_LEN];
00070 u8 ident;
00071 int resuming;
00072 int reauth;
00073 u8 *key_data;
00074
00075 struct wpabuf *pending_phase2_req;
00076
00077 #ifdef EAP_TNC
00078 int ready_for_tnc;
00079 int tnc_started;
00080 #endif
00081 };
00082
00083
00084 static void * eap_ttls_init(struct eap_sm *sm)
00085 {
00086 struct eap_ttls_data *data;
00087 struct eap_peer_config *config = eap_get_config(sm);
00088 char *selected;
00089
00090 data = os_zalloc(sizeof(*data));
00091 if (data == NULL)
00092 return NULL;
00093 data->ttls_version = EAP_TTLS_VERSION;
00094 data->force_ttls_version = -1;
00095 selected = "EAP";
00096 data->phase2_type = EAP_TTLS_PHASE2_EAP;
00097
00098 #if EAP_TTLS_VERSION > 0
00099 if (config && config->phase1) {
00100 const char *pos = os_strstr(config->phase1, "ttlsver=");
00101 if (pos) {
00102 data->force_ttls_version = atoi(pos + 8);
00103 data->ttls_version = data->force_ttls_version;
00104 wpa_printf(MSG_DEBUG, "EAP-TTLS: Forced TTLS version "
00105 "%d", data->force_ttls_version);
00106 }
00107 }
00108 #endif
00109
00110 if (config && config->phase2) {
00111 if (os_strstr(config->phase2, "autheap=")) {
00112 selected = "EAP";
00113 data->phase2_type = EAP_TTLS_PHASE2_EAP;
00114 } else if (os_strstr(config->phase2, "auth=MSCHAPV2")) {
00115 selected = "MSCHAPV2";
00116 data->phase2_type = EAP_TTLS_PHASE2_MSCHAPV2;
00117 } else if (os_strstr(config->phase2, "auth=MSCHAP")) {
00118 selected = "MSCHAP";
00119 data->phase2_type = EAP_TTLS_PHASE2_MSCHAP;
00120 } else if (os_strstr(config->phase2, "auth=PAP")) {
00121 selected = "PAP";
00122 data->phase2_type = EAP_TTLS_PHASE2_PAP;
00123 } else if (os_strstr(config->phase2, "auth=CHAP")) {
00124 selected = "CHAP";
00125 data->phase2_type = EAP_TTLS_PHASE2_CHAP;
00126 }
00127 }
00128 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 type: %s", selected);
00129
00130 if (data->phase2_type == EAP_TTLS_PHASE2_EAP) {
00131 if (eap_peer_select_phase2_methods(config, "autheap=",
00132 &data->phase2_eap_types,
00133 &data->num_phase2_eap_types)
00134 < 0) {
00135 eap_ttls_deinit(sm, data);
00136 return NULL;
00137 }
00138
00139 data->phase2_eap_type.vendor = EAP_VENDOR_IETF;
00140 data->phase2_eap_type.method = EAP_TYPE_NONE;
00141 }
00142
00143 #if EAP_TTLS_VERSION > 0
00144 if (!(tls_capabilities(sm->ssl_ctx) & TLS_CAPABILITY_IA) &&
00145 data->ttls_version > 0) {
00146 if (data->force_ttls_version > 0) {
00147 wpa_printf(MSG_INFO, "EAP-TTLS: Forced TTLSv%d and "
00148 "TLS library does not support TLS/IA.",
00149 data->force_ttls_version);
00150 eap_ttls_deinit(sm, data);
00151 return NULL;
00152 }
00153 data->ttls_version = 0;
00154 }
00155 #endif
00156
00157 return data;
00158 }
00159
00160
00161 static void eap_ttls_phase2_eap_deinit(struct eap_sm *sm,
00162 struct eap_ttls_data *data)
00163 {
00164 if (data->phase2_priv && data->phase2_method) {
00165 data->phase2_method->deinit(sm, data->phase2_priv);
00166 data->phase2_method = NULL;
00167 data->phase2_priv = NULL;
00168 }
00169 }
00170
00171
00172 static void eap_ttls_deinit(struct eap_sm *sm, void *priv)
00173 {
00174 struct eap_ttls_data *data = priv;
00175 if (data == NULL)
00176 return;
00177 eap_ttls_phase2_eap_deinit(sm, data);
00178 os_free(data->phase2_eap_types);
00179 if (data->ssl_initialized)
00180 eap_peer_tls_ssl_deinit(sm, &data->ssl);
00181 os_free(data->key_data);
00182 wpabuf_free(data->pending_phase2_req);
00183 os_free(data);
00184 }
00185
00186
00187 static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
00188 int mandatory, size_t len)
00189 {
00190 struct ttls_avp_vendor *avp;
00191 u8 flags;
00192 size_t hdrlen;
00193
00194 avp = (struct ttls_avp_vendor *) avphdr;
00195 flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
00196 if (vendor_id) {
00197 flags |= AVP_FLAGS_VENDOR;
00198 hdrlen = sizeof(*avp);
00199 avp->vendor_id = host_to_be32(vendor_id);
00200 } else {
00201 hdrlen = sizeof(struct ttls_avp);
00202 }
00203
00204 avp->avp_code = host_to_be32(avp_code);
00205 avp->avp_length = host_to_be32((flags << 24) | (hdrlen + len));
00206
00207 return avphdr + hdrlen;
00208 }
00209
00210
00211 static u8 * eap_ttls_avp_add(u8 *start, u8 *avphdr, u32 avp_code,
00212 u32 vendor_id, int mandatory,
00213 const u8 *data, size_t len)
00214 {
00215 u8 *pos;
00216 pos = eap_ttls_avp_hdr(avphdr, avp_code, vendor_id, mandatory, len);
00217 os_memcpy(pos, data, len);
00218 pos += len;
00219 AVP_PAD(start, pos);
00220 return pos;
00221 }
00222
00223
00224 static int eap_ttls_avp_encapsulate(struct wpabuf **resp, u32 avp_code,
00225 int mandatory)
00226 {
00227 struct wpabuf *msg;
00228 u8 *avp, *pos;
00229
00230 msg = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(*resp) + 4);
00231 if (msg == NULL) {
00232 wpabuf_free(*resp);
00233 *resp = NULL;
00234 return -1;
00235 }
00236
00237 avp = wpabuf_mhead(msg);
00238 pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, wpabuf_len(*resp));
00239 os_memcpy(pos, wpabuf_head(*resp), wpabuf_len(*resp));
00240 pos += wpabuf_len(*resp);
00241 AVP_PAD(avp, pos);
00242 wpabuf_free(*resp);
00243 wpabuf_put(msg, pos - avp);
00244 *resp = msg;
00245 return 0;
00246 }
00247
00248
00249 #if EAP_TTLS_VERSION > 0
00250 static int eap_ttls_ia_permute_inner_secret(struct eap_sm *sm,
00251 struct eap_ttls_data *data,
00252 const u8 *key, size_t key_len)
00253 {
00254 u8 *buf;
00255 size_t buf_len;
00256 int ret;
00257
00258 if (key) {
00259 buf_len = 2 + key_len;
00260 buf = os_malloc(buf_len);
00261 if (buf == NULL)
00262 return -1;
00263 WPA_PUT_BE16(buf, key_len);
00264 os_memcpy(buf + 2, key, key_len);
00265 } else {
00266 buf = NULL;
00267 buf_len = 0;
00268 }
00269
00270 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Session keys for TLS/IA inner "
00271 "secret permutation", buf, buf_len);
00272 ret = tls_connection_ia_permute_inner_secret(sm->ssl_ctx,
00273 data->ssl.conn,
00274 buf, buf_len);
00275 os_free(buf);
00276
00277 return ret;
00278 }
00279 #endif
00280
00281
00282 static int eap_ttls_v0_derive_key(struct eap_sm *sm,
00283 struct eap_ttls_data *data)
00284 {
00285 os_free(data->key_data);
00286 data->key_data = eap_peer_tls_derive_key(sm, &data->ssl,
00287 "ttls keying material",
00288 EAP_TLS_KEY_LEN);
00289 if (!data->key_data) {
00290 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to derive key");
00291 return -1;
00292 }
00293
00294 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
00295 data->key_data, EAP_TLS_KEY_LEN);
00296
00297 return 0;
00298 }
00299
00300
00301 #if EAP_TTLS_VERSION > 0
00302 static int eap_ttls_v1_derive_key(struct eap_sm *sm,
00303 struct eap_ttls_data *data)
00304 {
00305 struct tls_keys keys;
00306 u8 *rnd;
00307
00308 os_free(data->key_data);
00309 data->key_data = NULL;
00310
00311 os_memset(&keys, 0, sizeof(keys));
00312 if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
00313 keys.client_random == NULL || keys.server_random == NULL ||
00314 keys.inner_secret == NULL) {
00315 wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, "
00316 "client random, or server random to derive keying "
00317 "material");
00318 return -1;
00319 }
00320
00321 rnd = os_malloc(keys.client_random_len + keys.server_random_len);
00322 data->key_data = os_malloc(EAP_TLS_KEY_LEN);
00323 if (rnd == NULL || data->key_data == NULL) {
00324 wpa_printf(MSG_INFO, "EAP-TTLS: No memory for key derivation");
00325 os_free(rnd);
00326 os_free(data->key_data);
00327 data->key_data = NULL;
00328 return -1;
00329 }
00330 os_memcpy(rnd, keys.client_random, keys.client_random_len);
00331 os_memcpy(rnd + keys.client_random_len, keys.server_random,
00332 keys.server_random_len);
00333
00334 if (tls_prf(keys.inner_secret, keys.inner_secret_len,
00335 "ttls v1 keying material", rnd, keys.client_random_len +
00336 keys.server_random_len, data->key_data, EAP_TLS_KEY_LEN)) {
00337 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
00338 os_free(rnd);
00339 os_free(data->key_data);
00340 data->key_data = NULL;
00341 return -1;
00342 }
00343
00344 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: client/server random",
00345 rnd, keys.client_random_len + keys.server_random_len);
00346 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: TLS/IA inner secret",
00347 keys.inner_secret, keys.inner_secret_len);
00348
00349 os_free(rnd);
00350
00351 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
00352 data->key_data, EAP_TLS_KEY_LEN);
00353
00354 return 0;
00355 }
00356 #endif
00357
00358
00359 static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
00360 struct eap_ttls_data *data, size_t len)
00361 {
00362 #if EAP_TTLS_VERSION > 0
00363 struct tls_keys keys;
00364 u8 *challenge, *rnd;
00365 #endif
00366
00367 if (data->ttls_version == 0) {
00368 return eap_peer_tls_derive_key(sm, &data->ssl,
00369 "ttls challenge", len);
00370 }
00371
00372 #if EAP_TTLS_VERSION > 0
00373
00374 os_memset(&keys, 0, sizeof(keys));
00375 if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
00376 keys.client_random == NULL || keys.server_random == NULL ||
00377 keys.inner_secret == NULL) {
00378 wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, "
00379 "client random, or server random to derive "
00380 "implicit challenge");
00381 return NULL;
00382 }
00383
00384 rnd = os_malloc(keys.client_random_len + keys.server_random_len);
00385 challenge = os_malloc(len);
00386 if (rnd == NULL || challenge == NULL) {
00387 wpa_printf(MSG_INFO, "EAP-TTLS: No memory for implicit "
00388 "challenge derivation");
00389 os_free(rnd);
00390 os_free(challenge);
00391 return NULL;
00392 }
00393 os_memcpy(rnd, keys.server_random, keys.server_random_len);
00394 os_memcpy(rnd + keys.server_random_len, keys.client_random,
00395 keys.client_random_len);
00396
00397 if (tls_prf(keys.inner_secret, keys.inner_secret_len,
00398 "inner application challenge", rnd,
00399 keys.client_random_len + keys.server_random_len,
00400 challenge, len)) {
00401 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive implicit "
00402 "challenge");
00403 os_free(rnd);
00404 os_free(challenge);
00405 return NULL;
00406 }
00407
00408 os_free(rnd);
00409
00410 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived implicit challenge",
00411 challenge, len);
00412
00413 return challenge;
00414
00415 #else
00416
00417 return NULL;
00418
00419 #endif
00420 }
00421
00422
00423 static void eap_ttlsv1_phase2_eap_finish(struct eap_sm *sm,
00424 struct eap_ttls_data *data,
00425 struct eap_method_ret *ret)
00426 {
00427 #if EAP_TTLS_VERSION > 0
00428 if (data->ttls_version > 0) {
00429 const struct eap_method *m = data->phase2_method;
00430 void *priv = data->phase2_priv;
00431
00432
00433 if (ret->decision == DECISION_UNCOND_SUCC)
00434 ret->decision = DECISION_COND_SUCC;
00435 ret->methodState = METHOD_CONT;
00436
00437 if (ret->decision == DECISION_COND_SUCC &&
00438 m->isKeyAvailable && m->getKey &&
00439 m->isKeyAvailable(sm, priv)) {
00440 u8 *key;
00441 size_t key_len;
00442 key = m->getKey(sm, priv, &key_len);
00443 if (key) {
00444 eap_ttls_ia_permute_inner_secret(
00445 sm, data, key, key_len);
00446 os_free(key);
00447 }
00448 }
00449 }
00450 #endif
00451 }
00452
00453
00454 static void eap_ttls_phase2_select_eap_method(struct eap_ttls_data *data,
00455 u8 method)
00456 {
00457 size_t i;
00458 for (i = 0; i < data->num_phase2_eap_types; i++) {
00459 if (data->phase2_eap_types[i].vendor != EAP_VENDOR_IETF ||
00460 data->phase2_eap_types[i].method != method)
00461 continue;
00462
00463 data->phase2_eap_type.vendor =
00464 data->phase2_eap_types[i].vendor;
00465 data->phase2_eap_type.method =
00466 data->phase2_eap_types[i].method;
00467 wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected "
00468 "Phase 2 EAP vendor %d method %d",
00469 data->phase2_eap_type.vendor,
00470 data->phase2_eap_type.method);
00471 break;
00472 }
00473 }
00474
00475
00476 static int eap_ttls_phase2_eap_process(struct eap_sm *sm,
00477 struct eap_ttls_data *data,
00478 struct eap_method_ret *ret,
00479 struct eap_hdr *hdr, size_t len,
00480 struct wpabuf **resp)
00481 {
00482 struct wpabuf msg;
00483 struct eap_method_ret iret;
00484
00485 os_memset(&iret, 0, sizeof(iret));
00486 wpabuf_set(&msg, hdr, len);
00487 *resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
00488 &msg);
00489 if ((iret.methodState == METHOD_DONE ||
00490 iret.methodState == METHOD_MAY_CONT) &&
00491 (iret.decision == DECISION_UNCOND_SUCC ||
00492 iret.decision == DECISION_COND_SUCC ||
00493 iret.decision == DECISION_FAIL)) {
00494 ret->methodState = iret.methodState;
00495 ret->decision = iret.decision;
00496 }
00497 eap_ttlsv1_phase2_eap_finish(sm, data, ret);
00498
00499 return 0;
00500 }
00501
00502
00503 static int eap_ttls_phase2_request_eap_method(struct eap_sm *sm,
00504 struct eap_ttls_data *data,
00505 struct eap_method_ret *ret,
00506 struct eap_hdr *hdr, size_t len,
00507 u8 method, struct wpabuf **resp)
00508 {
00509 #ifdef EAP_TNC
00510 if (data->tnc_started && data->phase2_method &&
00511 data->phase2_priv && method == EAP_TYPE_TNC &&
00512 data->phase2_eap_type.method == EAP_TYPE_TNC)
00513 return eap_ttls_phase2_eap_process(sm, data, ret, hdr, len,
00514 resp);
00515
00516 if (data->ready_for_tnc && !data->tnc_started &&
00517 method == EAP_TYPE_TNC) {
00518 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start TNC after completed "
00519 "EAP method");
00520 data->tnc_started = 1;
00521 }
00522
00523 if (data->tnc_started) {
00524 if (data->phase2_eap_type.vendor != EAP_VENDOR_IETF ||
00525 data->phase2_eap_type.method == EAP_TYPE_TNC) {
00526 wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected EAP "
00527 "type %d for TNC", method);
00528 return -1;
00529 }
00530
00531 data->phase2_eap_type.vendor = EAP_VENDOR_IETF;
00532 data->phase2_eap_type.method = method;
00533 wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected "
00534 "Phase 2 EAP vendor %d method %d (TNC)",
00535 data->phase2_eap_type.vendor,
00536 data->phase2_eap_type.method);
00537
00538 if (data->phase2_type == EAP_TTLS_PHASE2_EAP)
00539 eap_ttls_phase2_eap_deinit(sm, data);
00540 }
00541 #endif
00542
00543 if (data->phase2_eap_type.vendor == EAP_VENDOR_IETF &&
00544 data->phase2_eap_type.method == EAP_TYPE_NONE)
00545 eap_ttls_phase2_select_eap_method(data, method);
00546
00547 if (method != data->phase2_eap_type.method || method == EAP_TYPE_NONE)
00548 {
00549 if (eap_peer_tls_phase2_nak(data->phase2_eap_types,
00550 data->num_phase2_eap_types,
00551 hdr, resp))
00552 return -1;
00553 return 0;
00554 }
00555
00556 if (data->phase2_priv == NULL) {
00557 data->phase2_method = eap_peer_get_eap_method(
00558 EAP_VENDOR_IETF, method);
00559 if (data->phase2_method) {
00560 sm->init_phase2 = 1;
00561 data->phase2_priv = data->phase2_method->init(sm);
00562 sm->init_phase2 = 0;
00563 }
00564 }
00565 if (data->phase2_priv == NULL || data->phase2_method == NULL) {
00566 wpa_printf(MSG_INFO, "EAP-TTLS: failed to initialize "
00567 "Phase 2 EAP method %d", method);
00568 return -1;
00569 }
00570
00571 return eap_ttls_phase2_eap_process(sm, data, ret, hdr, len, resp);
00572 }
00573
00574
00575 static int eap_ttls_phase2_request_eap(struct eap_sm *sm,
00576 struct eap_ttls_data *data,
00577 struct eap_method_ret *ret,
00578 struct eap_hdr *hdr,
00579 struct wpabuf **resp)
00580 {
00581 size_t len = be_to_host16(hdr->length);
00582 u8 *pos;
00583 struct eap_peer_config *config = eap_get_config(sm);
00584
00585 if (len <= sizeof(struct eap_hdr)) {
00586 wpa_printf(MSG_INFO, "EAP-TTLS: too short "
00587 "Phase 2 request (len=%lu)", (unsigned long) len);
00588 return -1;
00589 }
00590 pos = (u8 *) (hdr + 1);
00591 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP Request: type=%d", *pos);
00592 switch (*pos) {
00593 case EAP_TYPE_IDENTITY:
00594 *resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
00595 break;
00596 default:
00597 if (eap_ttls_phase2_request_eap_method(sm, data, ret, hdr, len,
00598 *pos, resp) < 0)
00599 return -1;
00600 break;
00601 }
00602
00603 if (*resp == NULL &&
00604 (config->pending_req_identity || config->pending_req_password ||
00605 config->pending_req_otp)) {
00606 return 0;
00607 }
00608
00609 if (*resp == NULL)
00610 return -1;
00611
00612 wpa_hexdump_buf(MSG_DEBUG, "EAP-TTLS: AVP encapsulate EAP Response",
00613 *resp);
00614 return eap_ttls_avp_encapsulate(resp, RADIUS_ATTR_EAP_MESSAGE, 1);
00615 }
00616
00617
00618 static void eap_ttlsv1_permute_inner(struct eap_sm *sm,
00619 struct eap_ttls_data *data)
00620 {
00621 #if EAP_TTLS_VERSION > 0
00622 u8 session_key[2 * MSCHAPV2_KEY_LEN];
00623
00624 if (data->ttls_version == 0)
00625 return;
00626
00627 get_asymetric_start_key(data->master_key, session_key,
00628 MSCHAPV2_KEY_LEN, 0, 0);
00629 get_asymetric_start_key(data->master_key,
00630 session_key + MSCHAPV2_KEY_LEN,
00631 MSCHAPV2_KEY_LEN, 1, 0);
00632 eap_ttls_ia_permute_inner_secret(sm, data, session_key,
00633 sizeof(session_key));
00634 #endif
00635 }
00636
00637
00638 static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
00639 struct eap_ttls_data *data,
00640 struct eap_method_ret *ret,
00641 struct wpabuf **resp)
00642 {
00643 struct wpabuf *msg;
00644 u8 *buf, *pos, *challenge, *peer_challenge;
00645 const u8 *identity, *password;
00646 size_t identity_len, password_len;
00647 int pwhash;
00648
00649 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAPV2 Request");
00650
00651 identity = eap_get_config_identity(sm, &identity_len);
00652 password = eap_get_config_password2(sm, &password_len, &pwhash);
00653 if (identity == NULL || password == NULL)
00654 return -1;
00655
00656 msg = wpabuf_alloc(identity_len + 1000);
00657 if (msg == NULL) {
00658 wpa_printf(MSG_ERROR,
00659 "EAP-TTLS/MSCHAPV2: Failed to allocate memory");
00660 return -1;
00661 }
00662 pos = buf = wpabuf_mhead(msg);
00663
00664
00665 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
00666 identity, identity_len);
00667
00668
00669 challenge = eap_ttls_implicit_challenge(
00670 sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
00671 if (challenge == NULL) {
00672 wpabuf_free(msg);
00673 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
00674 "implicit challenge");
00675 return -1;
00676 }
00677 peer_challenge = challenge + 1 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
00678
00679 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
00680 RADIUS_VENDOR_ID_MICROSOFT, 1,
00681 challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
00682
00683
00684 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_RESPONSE,
00685 RADIUS_VENDOR_ID_MICROSOFT, 1,
00686 EAP_TTLS_MSCHAPV2_RESPONSE_LEN);
00687 data->ident = challenge[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN];
00688 *pos++ = data->ident;
00689 *pos++ = 0;
00690 os_memcpy(pos, peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
00691 pos += EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
00692 os_memset(pos, 0, 8);
00693 pos += 8;
00694 if (mschapv2_derive_response(identity, identity_len, password,
00695 password_len, pwhash, challenge,
00696 peer_challenge, pos, data->auth_response,
00697 data->master_key)) {
00698 wpabuf_free(msg);
00699 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
00700 "response");
00701 return -1;
00702 }
00703 data->auth_response_valid = 1;
00704
00705 eap_ttlsv1_permute_inner(sm, data);
00706
00707 pos += 24;
00708 os_free(challenge);
00709 AVP_PAD(buf, pos);
00710
00711 wpabuf_put(msg, pos - buf);
00712 *resp = msg;
00713
00714 if (sm->workaround && data->ttls_version == 0) {
00715
00716
00717
00718 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: EAP workaround - "
00719 "allow success without tunneled response");
00720 ret->methodState = METHOD_MAY_CONT;
00721 ret->decision = DECISION_COND_SUCC;
00722 }
00723
00724 return 0;
00725 }
00726
00727
00728 static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
00729 struct eap_ttls_data *data,
00730 struct eap_method_ret *ret,
00731 struct wpabuf **resp)
00732 {
00733 struct wpabuf *msg;
00734 u8 *buf, *pos, *challenge;
00735 const u8 *identity, *password;
00736 size_t identity_len, password_len;
00737 int pwhash;
00738
00739 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAP Request");
00740
00741 identity = eap_get_config_identity(sm, &identity_len);
00742 password = eap_get_config_password2(sm, &password_len, &pwhash);
00743 if (identity == NULL || password == NULL)
00744 return -1;
00745
00746 msg = wpabuf_alloc(identity_len + 1000);
00747 if (msg == NULL) {
00748 wpa_printf(MSG_ERROR,
00749 "EAP-TTLS/MSCHAP: Failed to allocate memory");
00750 return -1;
00751 }
00752 pos = buf = wpabuf_mhead(msg);
00753
00754
00755 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
00756 identity, identity_len);
00757
00758
00759 challenge = eap_ttls_implicit_challenge(
00760 sm, data, EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
00761 if (challenge == NULL) {
00762 wpabuf_free(msg);
00763 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive "
00764 "implicit challenge");
00765 return -1;
00766 }
00767
00768 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
00769 RADIUS_VENDOR_ID_MICROSOFT, 1,
00770 challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);
00771
00772
00773 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_RESPONSE,
00774 RADIUS_VENDOR_ID_MICROSOFT, 1,
00775 EAP_TTLS_MSCHAP_RESPONSE_LEN);
00776 data->ident = challenge[EAP_TTLS_MSCHAP_CHALLENGE_LEN];
00777 *pos++ = data->ident;
00778 *pos++ = 1;
00779 os_memset(pos, 0, 24);
00780 pos += 24;
00781 if (pwhash) {
00782 challenge_response(challenge, password, pos);
00783 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password hash",
00784 password, 16);
00785 } else {
00786 nt_challenge_response(challenge, password, password_len,
00787 pos);
00788 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password",
00789 password, password_len);
00790 }
00791 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP implicit challenge",
00792 challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);
00793 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP response", pos, 24);
00794 pos += 24;
00795 os_free(challenge);
00796 AVP_PAD(buf, pos);
00797
00798 wpabuf_put(msg, pos - buf);
00799 *resp = msg;
00800
00801 if (data->ttls_version > 0) {
00802
00803
00804 ret->methodState = METHOD_CONT;
00805 ret->decision = DECISION_COND_SUCC;
00806 } else {
00807
00808
00809 ret->methodState = METHOD_DONE;
00810 ret->decision = DECISION_COND_SUCC;
00811 }
00812
00813 return 0;
00814 }
00815
00816
00817 static int eap_ttls_phase2_request_pap(struct eap_sm *sm,
00818 struct eap_ttls_data *data,
00819 struct eap_method_ret *ret,
00820 struct wpabuf **resp)
00821 {
00822 struct wpabuf *msg;
00823 u8 *buf, *pos;
00824 size_t pad;
00825 const u8 *identity, *password;
00826 size_t identity_len, password_len;
00827
00828 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 PAP Request");
00829
00830 identity = eap_get_config_identity(sm, &identity_len);
00831 password = eap_get_config_password(sm, &password_len);
00832 if (identity == NULL || password == NULL)
00833 return -1;
00834
00835 msg = wpabuf_alloc(identity_len + password_len + 100);
00836 if (msg == NULL) {
00837 wpa_printf(MSG_ERROR,
00838 "EAP-TTLS/PAP: Failed to allocate memory");
00839 return -1;
00840 }
00841 pos = buf = wpabuf_mhead(msg);
00842
00843
00844 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
00845 identity, identity_len);
00846
00847
00848
00849
00850 pad = password_len == 0 ? 16 : (16 - (password_len & 15)) & 15;
00851 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_USER_PASSWORD, 0, 1,
00852 password_len + pad);
00853 os_memcpy(pos, password, password_len);
00854 pos += password_len;
00855 os_memset(pos, 0, pad);
00856 pos += pad;
00857 AVP_PAD(buf, pos);
00858
00859 wpabuf_put(msg, pos - buf);
00860 *resp = msg;
00861
00862 if (data->ttls_version > 0) {
00863
00864
00865 ret->methodState = METHOD_CONT;
00866 ret->decision = DECISION_COND_SUCC;
00867 } else {
00868
00869
00870 ret->methodState = METHOD_DONE;
00871 ret->decision = DECISION_COND_SUCC;
00872 }
00873
00874 return 0;
00875 }
00876
00877
00878 static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
00879 struct eap_ttls_data *data,
00880 struct eap_method_ret *ret,
00881 struct wpabuf **resp)
00882 {
00883 struct wpabuf *msg;
00884 u8 *buf, *pos, *challenge;
00885 const u8 *identity, *password;
00886 size_t identity_len, password_len;
00887
00888 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 CHAP Request");
00889
00890 identity = eap_get_config_identity(sm, &identity_len);
00891 password = eap_get_config_password(sm, &password_len);
00892 if (identity == NULL || password == NULL)
00893 return -1;
00894
00895 msg = wpabuf_alloc(identity_len + 1000);
00896 if (msg == NULL) {
00897 wpa_printf(MSG_ERROR,
00898 "EAP-TTLS/CHAP: Failed to allocate memory");
00899 return -1;
00900 }
00901 pos = buf = wpabuf_mhead(msg);
00902
00903
00904 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
00905 identity, identity_len);
00906
00907
00908 challenge = eap_ttls_implicit_challenge(
00909 sm, data, EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
00910 if (challenge == NULL) {
00911 wpabuf_free(msg);
00912 wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive "
00913 "implicit challenge");
00914 return -1;
00915 }
00916
00917 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_CHAP_CHALLENGE, 0, 1,
00918 challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);
00919
00920
00921 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_CHAP_PASSWORD, 0, 1,
00922 1 + EAP_TTLS_CHAP_PASSWORD_LEN);
00923 data->ident = challenge[EAP_TTLS_CHAP_CHALLENGE_LEN];
00924 *pos++ = data->ident;
00925
00926
00927 chap_md5(data->ident, password, password_len, challenge,
00928 EAP_TTLS_CHAP_CHALLENGE_LEN, pos);
00929
00930 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: CHAP username",
00931 identity, identity_len);
00932 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: CHAP password",
00933 password, password_len);
00934 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP implicit challenge",
00935 challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);
00936 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP password",
00937 pos, EAP_TTLS_CHAP_PASSWORD_LEN);
00938 pos += EAP_TTLS_CHAP_PASSWORD_LEN;
00939 os_free(challenge);
00940 AVP_PAD(buf, pos);
00941
00942 wpabuf_put(msg, pos - buf);
00943 *resp = msg;
00944
00945 if (data->ttls_version > 0) {
00946
00947
00948 ret->methodState = METHOD_CONT;
00949 ret->decision = DECISION_COND_SUCC;
00950 } else {
00951
00952
00953 ret->methodState = METHOD_DONE;
00954 ret->decision = DECISION_COND_SUCC;
00955 }
00956
00957 return 0;
00958 }
00959
00960
00961 static int eap_ttls_phase2_request(struct eap_sm *sm,
00962 struct eap_ttls_data *data,
00963 struct eap_method_ret *ret,
00964 struct eap_hdr *hdr,
00965 struct wpabuf **resp)
00966 {
00967 int res = 0;
00968 size_t len;
00969 enum phase2_types phase2_type = data->phase2_type;
00970
00971 #ifdef EAP_TNC
00972 if (data->tnc_started) {
00973 wpa_printf(MSG_DEBUG, "EAP-TTLS: Processing TNC");
00974 phase2_type = EAP_TTLS_PHASE2_EAP;
00975 }
00976 #endif
00977
00978 if (phase2_type == EAP_TTLS_PHASE2_MSCHAPV2 ||
00979 phase2_type == EAP_TTLS_PHASE2_MSCHAP ||
00980 phase2_type == EAP_TTLS_PHASE2_PAP ||
00981 phase2_type == EAP_TTLS_PHASE2_CHAP) {
00982 if (eap_get_config_identity(sm, &len) == NULL) {
00983 wpa_printf(MSG_INFO,
00984 "EAP-TTLS: Identity not configured");
00985 eap_sm_request_identity(sm);
00986 if (eap_get_config_password(sm, &len) == NULL)
00987 eap_sm_request_password(sm);
00988 return 0;
00989 }
00990
00991 if (eap_get_config_password(sm, &len) == NULL) {
00992 wpa_printf(MSG_INFO,
00993 "EAP-TTLS: Password not configured");
00994 eap_sm_request_password(sm);
00995 return 0;
00996 }
00997 }
00998
00999 switch (phase2_type) {
01000 case EAP_TTLS_PHASE2_EAP:
01001 res = eap_ttls_phase2_request_eap(sm, data, ret, hdr, resp);
01002 break;
01003 case EAP_TTLS_PHASE2_MSCHAPV2:
01004 res = eap_ttls_phase2_request_mschapv2(sm, data, ret, resp);
01005 break;
01006 case EAP_TTLS_PHASE2_MSCHAP:
01007 res = eap_ttls_phase2_request_mschap(sm, data, ret, resp);
01008 break;
01009 case EAP_TTLS_PHASE2_PAP:
01010 res = eap_ttls_phase2_request_pap(sm, data, ret, resp);
01011 break;
01012 case EAP_TTLS_PHASE2_CHAP:
01013 res = eap_ttls_phase2_request_chap(sm, data, ret, resp);
01014 break;
01015 default:
01016 wpa_printf(MSG_ERROR, "EAP-TTLS: Phase 2 - Unknown");
01017 res = -1;
01018 break;
01019 }
01020
01021 if (res < 0) {
01022 ret->methodState = METHOD_DONE;
01023 ret->decision = DECISION_FAIL;
01024 }
01025
01026 return res;
01027 }
01028
01029
01030 #if EAP_TTLS_VERSION > 0
01031 static struct wpabuf * eap_ttls_build_phase_finished(
01032 struct eap_sm *sm, struct eap_ttls_data *data, int id, int final)
01033 {
01034 struct wpabuf *req, *buf;
01035
01036 buf = tls_connection_ia_send_phase_finished(sm->ssl_ctx,
01037 data->ssl.conn,
01038 final);
01039 if (buf == NULL)
01040 return NULL;
01041
01042 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS,
01043 1 + wpabuf_len(buf),
01044 EAP_CODE_RESPONSE, id);
01045 if (req == NULL) {
01046 wpabuf_free(buf);
01047 return NULL;
01048 }
01049
01050 wpabuf_put_u8(req, data->ttls_version);
01051 wpabuf_put_buf(req, buf);
01052 wpabuf_free(buf);
01053 eap_update_len(req);
01054
01055 return req;
01056 }
01057 #endif
01058
01059
01060 struct ttls_parse_avp {
01061 u8 *mschapv2;
01062 u8 *eapdata;
01063 size_t eap_len;
01064 int mschapv2_error;
01065 };
01066
01067
01068 static int eap_ttls_parse_attr_eap(const u8 *dpos, size_t dlen,
01069 struct ttls_parse_avp *parse)
01070 {
01071 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
01072 if (parse->eapdata == NULL) {
01073 parse->eapdata = os_malloc(dlen);
01074 if (parse->eapdata == NULL) {
01075 wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate "
01076 "memory for Phase 2 EAP data");
01077 return -1;
01078 }
01079 os_memcpy(parse->eapdata, dpos, dlen);
01080 parse->eap_len = dlen;
01081 } else {
01082 u8 *neweap = os_realloc(parse->eapdata, parse->eap_len + dlen);
01083 if (neweap == NULL) {
01084 wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate "
01085 "memory for Phase 2 EAP data");
01086 return -1;
01087 }
01088 os_memcpy(neweap + parse->eap_len, dpos, dlen);
01089 parse->eapdata = neweap;
01090 parse->eap_len += dlen;
01091 }
01092
01093 return 0;
01094 }
01095
01096
01097 static int eap_ttls_parse_avp(u8 *pos, size_t left,
01098 struct ttls_parse_avp *parse)
01099 {
01100 struct ttls_avp *avp;
01101 u32 avp_code, avp_length, vendor_id = 0;
01102 u8 avp_flags, *dpos;
01103 size_t dlen;
01104
01105 avp = (struct ttls_avp *) pos;
01106 avp_code = be_to_host32(avp->avp_code);
01107 avp_length = be_to_host32(avp->avp_length);
01108 avp_flags = (avp_length >> 24) & 0xff;
01109 avp_length &= 0xffffff;
01110 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
01111 "length=%d", (int) avp_code, avp_flags,
01112 (int) avp_length);
01113
01114 if (avp_length > left) {
01115 wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
01116 "(len=%d, left=%lu) - dropped",
01117 (int) avp_length, (unsigned long) left);
01118 return -1;
01119 }
01120
01121 if (avp_length < sizeof(*avp)) {
01122 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length %d",
01123 avp_length);
01124 return -1;
01125 }
01126
01127 dpos = (u8 *) (avp + 1);
01128 dlen = avp_length - sizeof(*avp);
01129 if (avp_flags & AVP_FLAGS_VENDOR) {
01130 if (dlen < 4) {
01131 wpa_printf(MSG_WARNING, "EAP-TTLS: Vendor AVP "
01132 "underflow");
01133 return -1;
01134 }
01135 vendor_id = WPA_GET_BE32(dpos);
01136 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
01137 (int) vendor_id);
01138 dpos += 4;
01139 dlen -= 4;
01140 }
01141
01142 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
01143
01144 if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
01145 if (eap_ttls_parse_attr_eap(dpos, dlen, parse) < 0)
01146 return -1;
01147 } else if (vendor_id == 0 && avp_code == RADIUS_ATTR_REPLY_MESSAGE) {
01148
01149
01150 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: AVP - Reply-Message",
01151 dpos, dlen);
01152 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
01153 avp_code == RADIUS_ATTR_MS_CHAP2_SUCCESS) {
01154 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP2-Success",
01155 dpos, dlen);
01156 if (dlen != 43) {
01157 wpa_printf(MSG_WARNING, "EAP-TTLS: Unexpected "
01158 "MS-CHAP2-Success length "
01159 "(len=%lu, expected 43)",
01160 (unsigned long) dlen);
01161 return -1;
01162 }
01163 parse->mschapv2 = dpos;
01164 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
01165 avp_code == RADIUS_ATTR_MS_CHAP_ERROR) {
01166 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP-Error",
01167 dpos, dlen);
01168 parse->mschapv2_error = 1;
01169 } else if (avp_flags & AVP_FLAGS_MANDATORY) {
01170 wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported mandatory AVP "
01171 "code %d vendor_id %d - dropped",
01172 (int) avp_code, (int) vendor_id);
01173 return -1;
01174 } else {
01175 wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported AVP "
01176 "code %d vendor_id %d",
01177 (int) avp_code, (int) vendor_id);
01178 }
01179
01180 return avp_length;
01181 }
01182
01183
01184 static int eap_ttls_parse_avps(struct wpabuf *in_decrypted,
01185 struct ttls_parse_avp *parse)
01186 {
01187 u8 *pos;
01188 size_t left, pad;
01189 int avp_length;
01190
01191 pos = wpabuf_mhead(in_decrypted);
01192 left = wpabuf_len(in_decrypted);
01193 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 AVPs", pos, left);
01194 if (left < sizeof(struct ttls_avp)) {
01195 wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 AVP frame"
01196 " len=%lu expected %lu or more - dropped",
01197 (unsigned long) left,
01198 (unsigned long) sizeof(struct ttls_avp));
01199 return -1;
01200 }
01201
01202
01203 os_memset(parse, 0, sizeof(*parse));
01204
01205 while (left > 0) {
01206 avp_length = eap_ttls_parse_avp(pos, left, parse);
01207 if (avp_length < 0)
01208 return -1;
01209
01210 pad = (4 - (avp_length & 3)) & 3;
01211 pos += avp_length + pad;
01212 if (left < avp_length + pad)
01213 left = 0;
01214 else
01215 left -= avp_length + pad;
01216 }
01217
01218 return 0;
01219 }
01220
01221
01222 static u8 * eap_ttls_fake_identity_request(void)
01223 {
01224 struct eap_hdr *hdr;
01225 u8 *buf;
01226
01227 wpa_printf(MSG_DEBUG, "EAP-TTLS: empty data in beginning of "
01228 "Phase 2 - use fake EAP-Request Identity");
01229 buf = os_malloc(sizeof(*hdr) + 1);
01230 if (buf == NULL) {
01231 wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate "
01232 "memory for fake EAP-Identity Request");
01233 return NULL;
01234 }
01235
01236 hdr = (struct eap_hdr *) buf;
01237 hdr->code = EAP_CODE_REQUEST;
01238 hdr->identifier = 0;
01239 hdr->length = host_to_be16(sizeof(*hdr) + 1);
01240 buf[sizeof(*hdr)] = EAP_TYPE_IDENTITY;
01241
01242 return buf;
01243 }
01244
01245
01246 static int eap_ttls_encrypt_response(struct eap_sm *sm,
01247 struct eap_ttls_data *data,
01248 struct wpabuf *resp, u8 identifier,
01249 struct wpabuf **out_data)
01250 {
01251 if (resp == NULL)
01252 return 0;
01253
01254 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Encrypting Phase 2 data",
01255 resp);
01256 if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,
01257 data->ttls_version, identifier,
01258 resp, out_data)) {
01259 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt a Phase 2 "
01260 "frame");
01261 return -1;
01262 }
01263 wpabuf_free(resp);
01264
01265 return 0;
01266 }
01267
01268
01269 static int eap_ttls_process_phase2_eap(struct eap_sm *sm,
01270 struct eap_ttls_data *data,
01271 struct eap_method_ret *ret,
01272 struct ttls_parse_avp *parse,
01273 struct wpabuf **resp)
01274 {
01275 struct eap_hdr *hdr;
01276 size_t len;
01277
01278 if (parse->eapdata == NULL) {
01279 wpa_printf(MSG_WARNING, "EAP-TTLS: No EAP Message in the "
01280 "packet - dropped");
01281 return -1;
01282 }
01283
01284 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP",
01285 parse->eapdata, parse->eap_len);
01286 hdr = (struct eap_hdr *) parse->eapdata;
01287
01288 if (parse->eap_len < sizeof(*hdr)) {
01289 wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 EAP "
01290 "frame (len=%lu, expected %lu or more) - dropped",
01291 (unsigned long) parse->eap_len,
01292 (unsigned long) sizeof(*hdr));
01293 return -1;
01294 }
01295 len = be_to_host16(hdr->length);
01296 if (len > parse->eap_len) {
01297 wpa_printf(MSG_INFO, "EAP-TTLS: Length mismatch in Phase 2 "
01298 "EAP frame (EAP hdr len=%lu, EAP data len in "
01299 "AVP=%lu)",
01300 (unsigned long) len,
01301 (unsigned long) parse->eap_len);
01302 return -1;
01303 }
01304 wpa_printf(MSG_DEBUG, "EAP-TTLS: received Phase 2: code=%d "
01305 "identifier=%d length=%lu",
01306 hdr->code, hdr->identifier, (unsigned long) len);
01307 switch (hdr->code) {
01308 case EAP_CODE_REQUEST:
01309 if (eap_ttls_phase2_request(sm, data, ret, hdr, resp)) {
01310 wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "
01311 "processing failed");
01312 return -1;
01313 }
01314 break;
01315 default:
01316 wpa_printf(MSG_INFO, "EAP-TTLS: Unexpected code=%d in "
01317 "Phase 2 EAP header", hdr->code);
01318 return -1;
01319 }
01320
01321 return 0;
01322 }
01323
01324
01325 static int eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
01326 struct eap_ttls_data *data,
01327 struct eap_method_ret *ret,
01328 struct ttls_parse_avp *parse)
01329 {
01330 if (parse->mschapv2_error) {
01331 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Received "
01332 "MS-CHAP-Error - failed");
01333 ret->methodState = METHOD_DONE;
01334 ret->decision = DECISION_FAIL;
01335
01336 return 1;
01337 }
01338
01339 if (parse->mschapv2 == NULL) {
01340 #ifdef EAP_TNC
01341 if (data->phase2_success && parse->eapdata) {
01342
01343
01344
01345
01346 return 1;
01347 }
01348 #endif
01349 wpa_printf(MSG_WARNING, "EAP-TTLS: no MS-CHAP2-Success AVP "
01350 "received for Phase2 MSCHAPV2");
01351 return -1;
01352 }
01353 if (parse->mschapv2[0] != data->ident) {
01354 wpa_printf(MSG_WARNING, "EAP-TTLS: Ident mismatch for Phase 2 "
01355 "MSCHAPV2 (received Ident 0x%02x, expected 0x%02x)",
01356 parse->mschapv2[0], data->ident);
01357 return -1;
01358 }
01359 if (!data->auth_response_valid ||
01360 mschapv2_verify_auth_response(data->auth_response,
01361 parse->mschapv2 + 1, 42)) {
01362 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid authenticator "
01363 "response in Phase 2 MSCHAPV2 success request");
01364 return -1;
01365 }
01366
01367 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 MSCHAPV2 "
01368 "authentication succeeded");
01369 if (data->ttls_version > 0) {
01370
01371
01372
01373
01374
01375 ret->methodState = METHOD_CONT;
01376 ret->decision = DECISION_COND_SUCC;
01377 } else {
01378 ret->methodState = METHOD_DONE;
01379 ret->decision = DECISION_UNCOND_SUCC;
01380 data->phase2_success = 1;
01381 }
01382
01383
01384
01385
01386
01387 return 1;
01388 }
01389
01390
01391 #ifdef EAP_TNC
01392 static int eap_ttls_process_tnc_start(struct eap_sm *sm,
01393 struct eap_ttls_data *data,
01394 struct eap_method_ret *ret,
01395 struct ttls_parse_avp *parse,
01396 struct wpabuf **resp)
01397 {
01398
01399 if (parse->eapdata == NULL) {
01400 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received "
01401 "unexpected tunneled data (no EAP)");
01402 return -1;
01403 }
01404
01405 if (!data->ready_for_tnc) {
01406 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received "
01407 "EAP after non-EAP, but not ready for TNC");
01408 return -1;
01409 }
01410
01411 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start TNC after completed "
01412 "non-EAP method");
01413 data->tnc_started = 1;
01414
01415 if (eap_ttls_process_phase2_eap(sm, data, ret, parse, resp) < 0)
01416 return -1;
01417
01418 return 0;
01419 }
01420 #endif
01421
01422
01423 static int eap_ttls_process_decrypted(struct eap_sm *sm,
01424 struct eap_ttls_data *data,
01425 struct eap_method_ret *ret,
01426 u8 identifier,
01427 struct ttls_parse_avp *parse,
01428 struct wpabuf *in_decrypted,
01429 struct wpabuf **out_data)
01430 {
01431 struct wpabuf *resp = NULL;
01432 struct eap_peer_config *config = eap_get_config(sm);
01433 int res;
01434 enum phase2_types phase2_type = data->phase2_type;
01435
01436 #ifdef EAP_TNC
01437 if (data->tnc_started)
01438 phase2_type = EAP_TTLS_PHASE2_EAP;
01439 #endif
01440
01441 switch (phase2_type) {
01442 case EAP_TTLS_PHASE2_EAP:
01443 if (eap_ttls_process_phase2_eap(sm, data, ret, parse, &resp) <
01444 0)
01445 return -1;
01446 break;
01447 case EAP_TTLS_PHASE2_MSCHAPV2:
01448 res = eap_ttls_process_phase2_mschapv2(sm, data, ret, parse);
01449 #ifdef EAP_TNC
01450 if (res == 1 && parse->eapdata && data->phase2_success) {
01451
01452
01453
01454
01455 ret->methodState = METHOD_MAY_CONT;
01456 data->ready_for_tnc = 1;
01457 if (eap_ttls_process_tnc_start(sm, data, ret, parse,
01458 &resp) == 0)
01459 break;
01460 }
01461 #endif
01462 return res;
01463 case EAP_TTLS_PHASE2_MSCHAP:
01464 case EAP_TTLS_PHASE2_PAP:
01465 case EAP_TTLS_PHASE2_CHAP:
01466 #ifdef EAP_TNC
01467 if (eap_ttls_process_tnc_start(sm, data, ret, parse, &resp) <
01468 0)
01469 return -1;
01470 break;
01471 #else
01472
01473
01474 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received unexpected "
01475 "tunneled data");
01476 return -1;
01477 #endif
01478 }
01479
01480 if (resp) {
01481 if (eap_ttls_encrypt_response(sm, data, resp, identifier,
01482 out_data) < 0)
01483 return -1;
01484 } else if (config->pending_req_identity ||
01485 config->pending_req_password ||
01486 config->pending_req_otp ||
01487 config->pending_req_new_password) {
01488 wpabuf_free(data->pending_phase2_req);
01489 data->pending_phase2_req = wpabuf_dup(in_decrypted);
01490 }
01491
01492 return 0;
01493 }
01494
01495
01496 #if EAP_TTLS_VERSION > 0
01497 static void eap_ttls_final_phase_finished(struct eap_sm *sm,
01498 struct eap_ttls_data *data,
01499 struct eap_method_ret *ret,
01500 u8 identifier,
01501 struct wpabuf **out_data)
01502 {
01503 wpa_printf(MSG_DEBUG, "EAP-TTLS: FinalPhaseFinished received");
01504 wpa_printf(MSG_INFO, "EAP-TTLS: TLS/IA authentication succeeded");
01505 ret->methodState = METHOD_DONE;
01506 ret->decision = DECISION_UNCOND_SUCC;
01507 data->phase2_success = 1;
01508 *out_data = eap_ttls_build_phase_finished(sm, data, identifier, 1);
01509 eap_ttls_v1_derive_key(sm, data);
01510 }
01511 #endif
01512
01513
01514 static int eap_ttls_implicit_identity_request(struct eap_sm *sm,
01515 struct eap_ttls_data *data,
01516 struct eap_method_ret *ret,
01517 u8 identifier,
01518 struct wpabuf **out_data)
01519 {
01520 int retval = 0;
01521 struct eap_hdr *hdr;
01522 struct wpabuf *resp;
01523
01524 hdr = (struct eap_hdr *) eap_ttls_fake_identity_request();
01525 if (hdr == NULL) {
01526 ret->methodState = METHOD_DONE;
01527 ret->decision = DECISION_FAIL;
01528 return -1;
01529 }
01530
01531 resp = NULL;
01532 if (eap_ttls_phase2_request(sm, data, ret, hdr, &resp)) {
01533 wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "
01534 "processing failed");
01535 retval = -1;
01536 } else {
01537 retval = eap_ttls_encrypt_response(sm, data, resp, identifier,
01538 out_data);
01539 }
01540
01541 os_free(hdr);
01542
01543 if (retval < 0) {
01544 ret->methodState = METHOD_DONE;
01545 ret->decision = DECISION_FAIL;
01546 }
01547
01548 return retval;
01549 }
01550
01551
01552 static int eap_ttls_phase2_start(struct eap_sm *sm, struct eap_ttls_data *data,
01553 struct eap_method_ret *ret, u8 identifier,
01554 struct wpabuf **out_data)
01555 {
01556 data->phase2_start = 0;
01557
01558
01559
01560
01561
01562
01563
01564
01565 if (data->reauth &&
01566 tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) {
01567 wpa_printf(MSG_DEBUG, "EAP-TTLS: Session resumption - "
01568 "skip phase 2");
01569 *out_data = eap_peer_tls_build_ack(identifier, EAP_TYPE_TTLS,
01570 data->ttls_version);
01571 ret->methodState = METHOD_DONE;
01572 ret->decision = DECISION_UNCOND_SUCC;
01573 data->phase2_success = 1;
01574 return 0;
01575 }
01576
01577 return eap_ttls_implicit_identity_request(sm, data, ret, identifier,
01578 out_data);
01579 }
01580
01581
01582 static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,
01583 struct eap_method_ret *ret, u8 identifier,
01584 const struct wpabuf *in_data,
01585 struct wpabuf **out_data)
01586 {
01587 struct wpabuf *in_decrypted = NULL;
01588 int retval = 0;
01589 struct ttls_parse_avp parse;
01590
01591 os_memset(&parse, 0, sizeof(parse));
01592
01593 wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
01594 " Phase 2",
01595 in_data ? (unsigned long) wpabuf_len(in_data) : 0);
01596
01597 if (data->pending_phase2_req) {
01598 wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 request - "
01599 "skip decryption and use old data");
01600
01601 eap_peer_tls_reset_input(&data->ssl);
01602
01603 in_decrypted = data->pending_phase2_req;
01604 data->pending_phase2_req = NULL;
01605 if (wpabuf_len(in_decrypted) == 0) {
01606 wpabuf_free(in_decrypted);
01607 return eap_ttls_implicit_identity_request(
01608 sm, data, ret, identifier, out_data);
01609 }
01610 goto continue_req;
01611 }
01612
01613 if ((in_data == NULL || wpabuf_len(in_data) == 0) &&
01614 data->phase2_start) {
01615 return eap_ttls_phase2_start(sm, data, ret, identifier,
01616 out_data);
01617 }
01618
01619 if (in_data == NULL || wpabuf_len(in_data) == 0) {
01620
01621 return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,
01622 data->ttls_version,
01623 identifier, NULL, out_data);
01624 }
01625
01626 retval = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
01627 if (retval)
01628 goto done;
01629
01630 #if EAP_TTLS_VERSION > 0
01631 if (data->ttls_version > 0 &&
01632 (in_decrypted == NULL || wpabuf_len(in_decrypted) == 0) &&
01633 tls_connection_ia_final_phase_finished(sm->ssl_ctx,
01634 data->ssl.conn)) {
01635 eap_ttls_final_phase_finished(sm, data, ret, identifier,
01636 out_data);
01637 goto done;
01638 }
01639 #endif
01640
01641 continue_req:
01642 data->phase2_start = 0;
01643
01644 if (eap_ttls_parse_avps(in_decrypted, &parse) < 0) {
01645 retval = -1;
01646 goto done;
01647 }
01648
01649 retval = eap_ttls_process_decrypted(sm, data, ret, identifier,
01650 &parse, in_decrypted, out_data);
01651
01652 done:
01653 wpabuf_free(in_decrypted);
01654 os_free(parse.eapdata);
01655
01656 if (retval < 0) {
01657 ret->methodState = METHOD_DONE;
01658 ret->decision = DECISION_FAIL;
01659 }
01660
01661 return retval;
01662 }
01663
01664
01665 static int eap_ttls_process_start(struct eap_sm *sm,
01666 struct eap_ttls_data *data, u8 flags,
01667 struct eap_method_ret *ret)
01668 {
01669 struct eap_peer_config *config = eap_get_config(sm);
01670
01671 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start (server ver=%d, own ver=%d)",
01672 flags & EAP_TLS_VERSION_MASK, data->ttls_version);
01673 #if EAP_TTLS_VERSION > 0
01674 if ((flags & EAP_TLS_VERSION_MASK) < data->ttls_version)
01675 data->ttls_version = flags & EAP_TLS_VERSION_MASK;
01676 if (data->force_ttls_version >= 0 &&
01677 data->force_ttls_version != data->ttls_version) {
01678 wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to select "
01679 "forced TTLS version %d",
01680 data->force_ttls_version);
01681 ret->methodState = METHOD_DONE;
01682 ret->decision = DECISION_FAIL;
01683 ret->allowNotifications = FALSE;
01684 return -1;
01685 }
01686 wpa_printf(MSG_DEBUG, "EAP-TTLS: Using TTLS version %d",
01687 data->ttls_version);
01688
01689 if (data->ttls_version > 0)
01690 data->ssl.tls_ia = 1;
01691 #endif
01692 if (!data->ssl_initialized &&
01693 eap_peer_tls_ssl_init(sm, &data->ssl, config)) {
01694 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
01695 return -1;
01696 }
01697 data->ssl_initialized = 1;
01698
01699 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start");
01700
01701 return 0;
01702 }
01703
01704
01705 static int eap_ttls_process_handshake(struct eap_sm *sm,
01706 struct eap_ttls_data *data,
01707 struct eap_method_ret *ret,
01708 u8 identifier,
01709 const u8 *in_data, size_t in_len,
01710 struct wpabuf **out_data)
01711 {
01712 int res;
01713
01714 res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS,
01715 data->ttls_version, identifier,
01716 in_data, in_len, out_data);
01717
01718 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
01719 wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS done, proceed to "
01720 "Phase 2");
01721 if (data->resuming) {
01722 wpa_printf(MSG_DEBUG, "EAP-TTLS: fast reauth - may "
01723 "skip Phase 2");
01724 ret->decision = DECISION_COND_SUCC;
01725 ret->methodState = METHOD_MAY_CONT;
01726 }
01727 data->phase2_start = 1;
01728 if (data->ttls_version == 0)
01729 eap_ttls_v0_derive_key(sm, data);
01730
01731 if (*out_data == NULL || wpabuf_len(*out_data) == 0) {
01732 if (eap_ttls_decrypt(sm, data, ret, identifier,
01733 NULL, out_data)) {
01734 wpa_printf(MSG_WARNING, "EAP-TTLS: "
01735 "failed to process early "
01736 "start for Phase 2");
01737 }
01738 res = 0;
01739 }
01740 data->resuming = 0;
01741 }
01742
01743 if (res == 2) {
01744 struct wpabuf msg;
01745
01746
01747
01748 wpabuf_free(data->pending_phase2_req);
01749 data->pending_phase2_req = *out_data;
01750 *out_data = NULL;
01751 wpabuf_set(&msg, in_data, in_len);
01752 res = eap_ttls_decrypt(sm, data, ret, identifier, &msg,
01753 out_data);
01754 }
01755
01756 return res;
01757 }
01758
01759
01760 static void eap_ttls_check_auth_status(struct eap_sm *sm,
01761 struct eap_ttls_data *data,
01762 struct eap_method_ret *ret)
01763 {
01764 if (data->ttls_version == 0 && ret->methodState == METHOD_DONE) {
01765 ret->allowNotifications = FALSE;
01766 if (ret->decision == DECISION_UNCOND_SUCC ||
01767 ret->decision == DECISION_COND_SUCC) {
01768 wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
01769 "completed successfully");
01770 data->phase2_success = 1;
01771 #ifdef EAP_TNC
01772 if (!data->ready_for_tnc && !data->tnc_started) {
01773
01774
01775
01776
01777 ret->methodState = METHOD_MAY_CONT;
01778 data->ready_for_tnc = 1;
01779 }
01780 #endif
01781 }
01782 } else if (data->ttls_version == 0 &&
01783 ret->methodState == METHOD_MAY_CONT &&
01784 (ret->decision == DECISION_UNCOND_SUCC ||
01785 ret->decision == DECISION_COND_SUCC)) {
01786 wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
01787 "completed successfully (MAY_CONT)");
01788 data->phase2_success = 1;
01789 }
01790 }
01791
01792
01793 static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv,
01794 struct eap_method_ret *ret,
01795 const struct wpabuf *reqData)
01796 {
01797 size_t left;
01798 int res;
01799 u8 flags, id;
01800 struct wpabuf *resp;
01801 const u8 *pos;
01802 struct eap_ttls_data *data = priv;
01803
01804 pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TTLS, ret,
01805 reqData, &left, &flags);
01806 if (pos == NULL)
01807 return NULL;
01808 id = eap_get_id(reqData);
01809
01810 if (flags & EAP_TLS_FLAGS_START) {
01811 if (eap_ttls_process_start(sm, data, flags, ret) < 0)
01812 return NULL;
01813
01814
01815
01816
01817
01818
01819 left = 0;
01820 } else if (!data->ssl_initialized) {
01821 wpa_printf(MSG_DEBUG, "EAP-TTLS: First message did not "
01822 "include Start flag");
01823 ret->methodState = METHOD_DONE;
01824 ret->decision = DECISION_FAIL;
01825 ret->allowNotifications = FALSE;
01826 return NULL;
01827 }
01828
01829 resp = NULL;
01830 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
01831 !data->resuming) {
01832 struct wpabuf msg;
01833 wpabuf_set(&msg, pos, left);
01834 res = eap_ttls_decrypt(sm, data, ret, id, &msg, &resp);
01835 } else {
01836 res = eap_ttls_process_handshake(sm, data, ret, id,
01837 pos, left, &resp);
01838 }
01839
01840 eap_ttls_check_auth_status(sm, data, ret);
01841
01842
01843
01844 if (res == 1) {
01845 wpabuf_free(resp);
01846 return eap_peer_tls_build_ack(id, EAP_TYPE_TTLS,
01847 data->ttls_version);
01848 }
01849 return resp;
01850 }
01851
01852
01853 static Boolean eap_ttls_has_reauth_data(struct eap_sm *sm, void *priv)
01854 {
01855 struct eap_ttls_data *data = priv;
01856 return tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
01857 data->phase2_success;
01858 }
01859
01860
01861 static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv)
01862 {
01863 struct eap_ttls_data *data = priv;
01864 wpabuf_free(data->pending_phase2_req);
01865 data->pending_phase2_req = NULL;
01866 #ifdef EAP_TNC
01867 data->ready_for_tnc = 0;
01868 data->tnc_started = 0;
01869 #endif
01870 }
01871
01872
01873 static void * eap_ttls_init_for_reauth(struct eap_sm *sm, void *priv)
01874 {
01875 struct eap_ttls_data *data = priv;
01876 os_free(data->key_data);
01877 data->key_data = NULL;
01878 if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
01879 os_free(data);
01880 return NULL;
01881 }
01882 if (data->phase2_priv && data->phase2_method &&
01883 data->phase2_method->init_for_reauth)
01884 data->phase2_method->init_for_reauth(sm, data->phase2_priv);
01885 data->phase2_start = 0;
01886 data->phase2_success = 0;
01887 data->resuming = 1;
01888 data->reauth = 1;
01889 return priv;
01890 }
01891
01892
01893 static int eap_ttls_get_status(struct eap_sm *sm, void *priv, char *buf,
01894 size_t buflen, int verbose)
01895 {
01896 struct eap_ttls_data *data = priv;
01897 int len, ret;
01898
01899 len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);
01900 ret = os_snprintf(buf + len, buflen - len,
01901 "EAP-TTLSv%d Phase2 method=",
01902 data->ttls_version);
01903 if (ret < 0 || (size_t) ret >= buflen - len)
01904 return len;
01905 len += ret;
01906 switch (data->phase2_type) {
01907 case EAP_TTLS_PHASE2_EAP:
01908 ret = os_snprintf(buf + len, buflen - len, "EAP-%s\n",
01909 data->phase2_method ?
01910 data->phase2_method->name : "?");
01911 break;
01912 case EAP_TTLS_PHASE2_MSCHAPV2:
01913 ret = os_snprintf(buf + len, buflen - len, "MSCHAPV2\n");
01914 break;
01915 case EAP_TTLS_PHASE2_MSCHAP:
01916 ret = os_snprintf(buf + len, buflen - len, "MSCHAP\n");
01917 break;
01918 case EAP_TTLS_PHASE2_PAP:
01919 ret = os_snprintf(buf + len, buflen - len, "PAP\n");
01920 break;
01921 case EAP_TTLS_PHASE2_CHAP:
01922 ret = os_snprintf(buf + len, buflen - len, "CHAP\n");
01923 break;
01924 default:
01925 ret = 0;
01926 break;
01927 }
01928 if (ret < 0 || (size_t) ret >= buflen - len)
01929 return len;
01930 len += ret;
01931
01932 return len;
01933 }
01934
01935
01936 static Boolean eap_ttls_isKeyAvailable(struct eap_sm *sm, void *priv)
01937 {
01938 struct eap_ttls_data *data = priv;
01939 return data->key_data != NULL && data->phase2_success;
01940 }
01941
01942
01943 static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
01944 {
01945 struct eap_ttls_data *data = priv;
01946 u8 *key;
01947
01948 if (data->key_data == NULL || !data->phase2_success)
01949 return NULL;
01950
01951 key = os_malloc(EAP_TLS_KEY_LEN);
01952 if (key == NULL)
01953 return NULL;
01954
01955 *len = EAP_TLS_KEY_LEN;
01956 os_memcpy(key, data->key_data, EAP_TLS_KEY_LEN);
01957
01958 return key;
01959 }
01960
01961
01962 int eap_peer_ttls_register(void)
01963 {
01964 struct eap_method *eap;
01965 int ret;
01966
01967 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
01968 EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
01969 if (eap == NULL)
01970 return -1;
01971
01972 eap->init = eap_ttls_init;
01973 eap->deinit = eap_ttls_deinit;
01974 eap->process = eap_ttls_process;
01975 eap->isKeyAvailable = eap_ttls_isKeyAvailable;
01976 eap->getKey = eap_ttls_getKey;
01977 eap->get_status = eap_ttls_get_status;
01978 eap->has_reauth_data = eap_ttls_has_reauth_data;
01979 eap->deinit_for_reauth = eap_ttls_deinit_for_reauth;
01980 eap->init_for_reauth = eap_ttls_init_for_reauth;
01981
01982 ret = eap_peer_method_register(eap);
01983 if (ret)
01984 eap_peer_method_free(eap);
01985 return ret;
01986 }