eap_server_ttls.c
Go to the documentation of this file.
00001 /*
00002  * hostapd / EAP-TTLS (RFC 5281)
00003  * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
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_server/eap_i.h"
00022 #include "eap_server/eap_tls_common.h"
00023 #include "eap_common/chap.h"
00024 #include "eap_common/eap_ttls.h"
00025 
00026 
00027 /* Maximum supported TTLS version
00028  * 0 = RFC 5281
00029  * 1 = draft-funk-eap-ttls-v1-00.txt
00030  */
00031 #ifndef EAP_TTLS_VERSION
00032 #define EAP_TTLS_VERSION 0 /* TTLSv1 implementation is not yet complete */
00033 #endif /* EAP_TTLS_VERSION */
00034 
00035 
00036 #define MSCHAPV2_KEY_LEN 16
00037 
00038 
00039 static void eap_ttls_reset(struct eap_sm *sm, void *priv);
00040 
00041 
00042 struct eap_ttls_data {
00043         struct eap_ssl_data ssl;
00044         enum {
00045                 START, PHASE1, PHASE2_START, PHASE2_METHOD,
00046                 PHASE2_MSCHAPV2_RESP, PHASE_FINISHED, SUCCESS, FAILURE
00047         } state;
00048 
00049         int ttls_version;
00050         int force_version;
00051         const struct eap_method *phase2_method;
00052         void *phase2_priv;
00053         int mschapv2_resp_ok;
00054         u8 mschapv2_auth_response[20];
00055         u8 mschapv2_ident;
00056         int tls_ia_configured;
00057         struct wpabuf *pending_phase2_eap_resp;
00058         int tnc_started;
00059 };
00060 
00061 
00062 static const char * eap_ttls_state_txt(int state)
00063 {
00064         switch (state) {
00065         case START:
00066                 return "START";
00067         case PHASE1:
00068                 return "PHASE1";
00069         case PHASE2_START:
00070                 return "PHASE2_START";
00071         case PHASE2_METHOD:
00072                 return "PHASE2_METHOD";
00073         case PHASE2_MSCHAPV2_RESP:
00074                 return "PHASE2_MSCHAPV2_RESP";
00075         case PHASE_FINISHED:
00076                 return "PHASE_FINISHED";
00077         case SUCCESS:
00078                 return "SUCCESS";
00079         case FAILURE:
00080                 return "FAILURE";
00081         default:
00082                 return "Unknown?!";
00083         }
00084 }
00085 
00086 
00087 static void eap_ttls_state(struct eap_ttls_data *data, int state)
00088 {
00089         wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s",
00090                    eap_ttls_state_txt(data->state),
00091                    eap_ttls_state_txt(state));
00092         data->state = state;
00093 }
00094 
00095 
00096 static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
00097                              int mandatory, size_t len)
00098 {
00099         struct ttls_avp_vendor *avp;
00100         u8 flags;
00101         size_t hdrlen;
00102 
00103         avp = (struct ttls_avp_vendor *) avphdr;
00104         flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
00105         if (vendor_id) {
00106                 flags |= AVP_FLAGS_VENDOR;
00107                 hdrlen = sizeof(*avp);
00108                 avp->vendor_id = host_to_be32(vendor_id);
00109         } else {
00110                 hdrlen = sizeof(struct ttls_avp);
00111         }
00112 
00113         avp->avp_code = host_to_be32(avp_code);
00114         avp->avp_length = host_to_be32((flags << 24) | (hdrlen + len));
00115 
00116         return avphdr + hdrlen;
00117 }
00118 
00119 
00120 static struct wpabuf * eap_ttls_avp_encapsulate(struct wpabuf *resp,
00121                                                 u32 avp_code, int mandatory)
00122 {
00123         struct wpabuf *avp;
00124         u8 *pos;
00125 
00126         avp = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(resp) + 4);
00127         if (avp == NULL) {
00128                 wpabuf_free(resp);
00129                 return NULL;
00130         }
00131 
00132         pos = eap_ttls_avp_hdr(wpabuf_mhead(avp), avp_code, 0, mandatory,
00133                                wpabuf_len(resp));
00134         os_memcpy(pos, wpabuf_head(resp), wpabuf_len(resp));
00135         pos += wpabuf_len(resp);
00136         AVP_PAD((const u8 *) wpabuf_head(avp), pos);
00137         wpabuf_free(resp);
00138         wpabuf_put(avp, pos - (u8 *) wpabuf_head(avp));
00139         return avp;
00140 }
00141 
00142 
00143 struct eap_ttls_avp {
00144          /* Note: eap is allocated memory; caller is responsible for freeing
00145           * it. All the other pointers are pointing to the packet data, i.e.,
00146           * they must not be freed separately. */
00147         u8 *eap;
00148         size_t eap_len;
00149         u8 *user_name;
00150         size_t user_name_len;
00151         u8 *user_password;
00152         size_t user_password_len;
00153         u8 *chap_challenge;
00154         size_t chap_challenge_len;
00155         u8 *chap_password;
00156         size_t chap_password_len;
00157         u8 *mschap_challenge;
00158         size_t mschap_challenge_len;
00159         u8 *mschap_response;
00160         size_t mschap_response_len;
00161         u8 *mschap2_response;
00162         size_t mschap2_response_len;
00163 };
00164 
00165 
00166 static int eap_ttls_avp_parse(struct wpabuf *buf, struct eap_ttls_avp *parse)
00167 {
00168         struct ttls_avp *avp;
00169         u8 *pos;
00170         int left;
00171 
00172         pos = wpabuf_mhead(buf);
00173         left = wpabuf_len(buf);
00174         os_memset(parse, 0, sizeof(*parse));
00175 
00176         while (left > 0) {
00177                 u32 avp_code, avp_length, vendor_id = 0;
00178                 u8 avp_flags, *dpos;
00179                 size_t pad, dlen;
00180                 avp = (struct ttls_avp *) pos;
00181                 avp_code = be_to_host32(avp->avp_code);
00182                 avp_length = be_to_host32(avp->avp_length);
00183                 avp_flags = (avp_length >> 24) & 0xff;
00184                 avp_length &= 0xffffff;
00185                 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
00186                            "length=%d", (int) avp_code, avp_flags,
00187                            (int) avp_length);
00188                 if ((int) avp_length > left) {
00189                         wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
00190                                    "(len=%d, left=%d) - dropped",
00191                                    (int) avp_length, left);
00192                         goto fail;
00193                 }
00194                 if (avp_length < sizeof(*avp)) {
00195                         wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length "
00196                                    "%d", avp_length);
00197                         goto fail;
00198                 }
00199                 dpos = (u8 *) (avp + 1);
00200                 dlen = avp_length - sizeof(*avp);
00201                 if (avp_flags & AVP_FLAGS_VENDOR) {
00202                         if (dlen < 4) {
00203                                 wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP "
00204                                            "underflow");
00205                                 goto fail;
00206                         }
00207                         vendor_id = be_to_host32(* (be32 *) dpos);
00208                         wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
00209                                    (int) vendor_id);
00210                         dpos += 4;
00211                         dlen -= 4;
00212                 }
00213 
00214                 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
00215 
00216                 if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
00217                         wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
00218                         if (parse->eap == NULL) {
00219                                 parse->eap = os_malloc(dlen);
00220                                 if (parse->eap == NULL) {
00221                                         wpa_printf(MSG_WARNING, "EAP-TTLS: "
00222                                                    "failed to allocate memory "
00223                                                    "for Phase 2 EAP data");
00224                                         goto fail;
00225                                 }
00226                                 os_memcpy(parse->eap, dpos, dlen);
00227                                 parse->eap_len = dlen;
00228                         } else {
00229                                 u8 *neweap = os_realloc(parse->eap,
00230                                                         parse->eap_len + dlen);
00231                                 if (neweap == NULL) {
00232                                         wpa_printf(MSG_WARNING, "EAP-TTLS: "
00233                                                    "failed to allocate memory "
00234                                                    "for Phase 2 EAP data");
00235                                         goto fail;
00236                                 }
00237                                 os_memcpy(neweap + parse->eap_len, dpos, dlen);
00238                                 parse->eap = neweap;
00239                                 parse->eap_len += dlen;
00240                         }
00241                 } else if (vendor_id == 0 &&
00242                            avp_code == RADIUS_ATTR_USER_NAME) {
00243                         wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name",
00244                                           dpos, dlen);
00245                         parse->user_name = dpos;
00246                         parse->user_name_len = dlen;
00247                 } else if (vendor_id == 0 &&
00248                            avp_code == RADIUS_ATTR_USER_PASSWORD) {
00249                         u8 *password = dpos;
00250                         size_t password_len = dlen;
00251                         while (password_len > 0 &&
00252                                password[password_len - 1] == '\0') {
00253                                 password_len--;
00254                         }
00255                         wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: "
00256                                               "User-Password (PAP)",
00257                                               password, password_len);
00258                         parse->user_password = password;
00259                         parse->user_password_len = password_len;
00260                 } else if (vendor_id == 0 &&
00261                            avp_code == RADIUS_ATTR_CHAP_CHALLENGE) {
00262                         wpa_hexdump(MSG_DEBUG,
00263                                     "EAP-TTLS: CHAP-Challenge (CHAP)",
00264                                     dpos, dlen);
00265                         parse->chap_challenge = dpos;
00266                         parse->chap_challenge_len = dlen;
00267                 } else if (vendor_id == 0 &&
00268                            avp_code == RADIUS_ATTR_CHAP_PASSWORD) {
00269                         wpa_hexdump(MSG_DEBUG,
00270                                     "EAP-TTLS: CHAP-Password (CHAP)",
00271                                     dpos, dlen);
00272                         parse->chap_password = dpos;
00273                         parse->chap_password_len = dlen;
00274                 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
00275                            avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) {
00276                         wpa_hexdump(MSG_DEBUG,
00277                                     "EAP-TTLS: MS-CHAP-Challenge",
00278                                     dpos, dlen);
00279                         parse->mschap_challenge = dpos;
00280                         parse->mschap_challenge_len = dlen;
00281                 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
00282                            avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) {
00283                         wpa_hexdump(MSG_DEBUG,
00284                                     "EAP-TTLS: MS-CHAP-Response (MSCHAP)",
00285                                     dpos, dlen);
00286                         parse->mschap_response = dpos;
00287                         parse->mschap_response_len = dlen;
00288                 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
00289                            avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) {
00290                         wpa_hexdump(MSG_DEBUG,
00291                                     "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)",
00292                                     dpos, dlen);
00293                         parse->mschap2_response = dpos;
00294                         parse->mschap2_response_len = dlen;
00295                 } else if (avp_flags & AVP_FLAGS_MANDATORY) {
00296                         wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported "
00297                                    "mandatory AVP code %d vendor_id %d - "
00298                                    "dropped", (int) avp_code, (int) vendor_id);
00299                         goto fail;
00300                 } else {
00301                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported "
00302                                    "AVP code %d vendor_id %d",
00303                                    (int) avp_code, (int) vendor_id);
00304                 }
00305 
00306                 pad = (4 - (avp_length & 3)) & 3;
00307                 pos += avp_length + pad;
00308                 left -= avp_length + pad;
00309         }
00310 
00311         return 0;
00312 
00313 fail:
00314         os_free(parse->eap);
00315         parse->eap = NULL;
00316         return -1;
00317 }
00318 
00319 
00320 static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
00321                                         struct eap_ttls_data *data, size_t len)
00322 {
00323         struct tls_keys keys;
00324         u8 *challenge, *rnd;
00325 
00326         if (data->ttls_version == 0) {
00327                 return eap_server_tls_derive_key(sm, &data->ssl,
00328                                                  "ttls challenge", len);
00329         }
00330 
00331         os_memset(&keys, 0, sizeof(keys));
00332         if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
00333             keys.client_random == NULL || keys.server_random == NULL ||
00334             keys.inner_secret == NULL) {
00335                 wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, "
00336                            "client random, or server random to derive "
00337                            "implicit challenge");
00338                 return NULL;
00339         }
00340 
00341         rnd = os_malloc(keys.client_random_len + keys.server_random_len);
00342         challenge = os_malloc(len);
00343         if (rnd == NULL || challenge == NULL) {
00344                 wpa_printf(MSG_INFO, "EAP-TTLS: No memory for implicit "
00345                            "challenge derivation");
00346                 os_free(rnd);
00347                 os_free(challenge);
00348                 return NULL;
00349         }
00350         os_memcpy(rnd, keys.server_random, keys.server_random_len);
00351         os_memcpy(rnd + keys.server_random_len, keys.client_random,
00352                   keys.client_random_len);
00353 
00354         if (tls_prf(keys.inner_secret, keys.inner_secret_len,
00355                     "inner application challenge", rnd,
00356                     keys.client_random_len + keys.server_random_len,
00357                     challenge, len)) {
00358                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive implicit "
00359                            "challenge");
00360                 os_free(rnd);
00361                 os_free(challenge);
00362                 return NULL;
00363         }
00364 
00365         os_free(rnd);
00366 
00367         wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived implicit challenge",
00368                         challenge, len);
00369 
00370         return challenge;
00371 }
00372 
00373 
00374 static void * eap_ttls_init(struct eap_sm *sm)
00375 {
00376         struct eap_ttls_data *data;
00377 
00378         data = os_zalloc(sizeof(*data));
00379         if (data == NULL)
00380                 return NULL;
00381         data->ttls_version = EAP_TTLS_VERSION;
00382         data->force_version = -1;
00383         if (sm->user && sm->user->force_version >= 0) {
00384                 data->force_version = sm->user->force_version;
00385                 wpa_printf(MSG_DEBUG, "EAP-TTLS: forcing version %d",
00386                            data->force_version);
00387                 data->ttls_version = data->force_version;
00388         }
00389         data->state = START;
00390 
00391         if (!(tls_capabilities(sm->ssl_ctx) & TLS_CAPABILITY_IA) &&
00392             data->ttls_version > 0) {
00393                 if (data->force_version > 0) {
00394                         wpa_printf(MSG_INFO, "EAP-TTLS: Forced TTLSv%d and "
00395                                    "TLS library does not support TLS/IA.",
00396                                    data->force_version);
00397                         eap_ttls_reset(sm, data);
00398                         return NULL;
00399                 }
00400                 data->ttls_version = 0;
00401         }
00402 
00403         if (eap_server_tls_ssl_init(sm, &data->ssl, 0)) {
00404                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
00405                 eap_ttls_reset(sm, data);
00406                 return NULL;
00407         }
00408 
00409         return data;
00410 }
00411 
00412 
00413 static void eap_ttls_reset(struct eap_sm *sm, void *priv)
00414 {
00415         struct eap_ttls_data *data = priv;
00416         if (data == NULL)
00417                 return;
00418         if (data->phase2_priv && data->phase2_method)
00419                 data->phase2_method->reset(sm, data->phase2_priv);
00420         eap_server_tls_ssl_deinit(sm, &data->ssl);
00421         wpabuf_free(data->pending_phase2_eap_resp);
00422         os_free(data);
00423 }
00424 
00425 
00426 static struct wpabuf * eap_ttls_build_start(struct eap_sm *sm,
00427                                             struct eap_ttls_data *data, u8 id)
00428 {       
00429         struct wpabuf *req;
00430 
00431         req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1,
00432                             EAP_CODE_REQUEST, id);
00433         if (req == NULL) {
00434                 wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for"
00435                            " request");
00436                 eap_ttls_state(data, FAILURE);
00437                 return NULL;
00438         }
00439 
00440         wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->ttls_version);
00441 
00442         eap_ttls_state(data, PHASE1);
00443 
00444         return req;
00445 }
00446 
00447 
00448 static struct wpabuf * eap_ttls_build_phase2_eap_req(
00449         struct eap_sm *sm, struct eap_ttls_data *data, u8 id)
00450 {
00451         struct wpabuf *buf, *encr_req;
00452 
00453 
00454         buf = data->phase2_method->buildReq(sm, data->phase2_priv, id);
00455         if (buf == NULL)
00456                 return NULL;
00457 
00458         wpa_hexdump_buf_key(MSG_DEBUG,
00459                             "EAP-TTLS/EAP: Encapsulate Phase 2 data", buf);
00460 
00461         buf = eap_ttls_avp_encapsulate(buf, RADIUS_ATTR_EAP_MESSAGE, 1);
00462         if (buf == NULL) {
00463                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "
00464                            "packet");
00465                 return NULL;
00466         }
00467 
00468         wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated "
00469                             "Phase 2 data", buf);
00470 
00471         encr_req = eap_server_tls_encrypt(sm, &data->ssl, buf);
00472         wpabuf_free(buf);
00473 
00474         return encr_req;
00475 }
00476 
00477 
00478 static struct wpabuf * eap_ttls_build_phase2_mschapv2(
00479         struct eap_sm *sm, struct eap_ttls_data *data)
00480 {
00481         struct wpabuf *encr_req, msgbuf;
00482         u8 *req, *pos, *end;
00483         int ret;
00484 
00485         pos = req = os_malloc(100);
00486         if (req == NULL)
00487                 return NULL;
00488         end = req + 100;
00489 
00490         if (data->mschapv2_resp_ok) {
00491                 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS,
00492                                        RADIUS_VENDOR_ID_MICROSOFT, 1, 43);
00493                 *pos++ = data->mschapv2_ident;
00494                 ret = os_snprintf((char *) pos, end - pos, "S=");
00495                 if (ret >= 0 && ret < end - pos)
00496                         pos += ret;
00497                 pos += wpa_snprintf_hex_uppercase(
00498                         (char *) pos, end - pos, data->mschapv2_auth_response,
00499                         sizeof(data->mschapv2_auth_response));
00500         } else {
00501                 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR,
00502                                        RADIUS_VENDOR_ID_MICROSOFT, 1, 6);
00503                 os_memcpy(pos, "Failed", 6);
00504                 pos += 6;
00505                 AVP_PAD(req, pos);
00506         }
00507 
00508         wpabuf_set(&msgbuf, req, pos - req);
00509         wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 "
00510                             "data", &msgbuf);
00511 
00512         encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf);
00513         os_free(req);
00514 
00515         return encr_req;
00516 }
00517 
00518 
00519 static struct wpabuf * eap_ttls_build_phase_finished(
00520         struct eap_sm *sm, struct eap_ttls_data *data, int final)
00521 {
00522         return tls_connection_ia_send_phase_finished(sm->ssl_ctx,
00523                                                      data->ssl.conn, final);
00524 }
00525 
00526 
00527 static struct wpabuf * eap_ttls_buildReq(struct eap_sm *sm, void *priv, u8 id)
00528 {
00529         struct eap_ttls_data *data = priv;
00530 
00531         if (data->ssl.state == FRAG_ACK) {
00532                 return eap_server_tls_build_ack(id, EAP_TYPE_TTLS,
00533                                                 data->ttls_version);
00534         }
00535 
00536         if (data->ssl.state == WAIT_FRAG_ACK) {
00537                 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,
00538                                                 data->ttls_version, id);
00539         }
00540 
00541         switch (data->state) {
00542         case START:
00543                 return eap_ttls_build_start(sm, data, id);
00544         case PHASE1:
00545                 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
00546                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, "
00547                                    "starting Phase2");
00548                         eap_ttls_state(data, PHASE2_START);
00549                 }
00550                 break;
00551         case PHASE2_METHOD:
00552                 wpabuf_free(data->ssl.tls_out);
00553                 data->ssl.tls_out_pos = 0;
00554                 data->ssl.tls_out = eap_ttls_build_phase2_eap_req(sm, data,
00555                                                                   id);
00556                 break;
00557         case PHASE2_MSCHAPV2_RESP:
00558                 wpabuf_free(data->ssl.tls_out);
00559                 data->ssl.tls_out_pos = 0;
00560                 data->ssl.tls_out = eap_ttls_build_phase2_mschapv2(sm, data);
00561                 break;
00562         case PHASE_FINISHED:
00563                 wpabuf_free(data->ssl.tls_out);
00564                 data->ssl.tls_out_pos = 0;
00565                 data->ssl.tls_out = eap_ttls_build_phase_finished(sm, data, 1);
00566                 break;
00567         default:
00568                 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
00569                            __func__, data->state);
00570                 return NULL;
00571         }
00572 
00573         return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,
00574                                         data->ttls_version, id);
00575 }
00576 
00577 
00578 static Boolean eap_ttls_check(struct eap_sm *sm, void *priv,
00579                               struct wpabuf *respData)
00580 {
00581         const u8 *pos;
00582         size_t len;
00583 
00584         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TTLS, respData, &len);
00585         if (pos == NULL || len < 1) {
00586                 wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame");
00587                 return TRUE;
00588         }
00589 
00590         return FALSE;
00591 }
00592 
00593 
00594 static int eap_ttls_ia_permute_inner_secret(struct eap_sm *sm,
00595                                             struct eap_ttls_data *data,
00596                                             const u8 *key, size_t key_len)
00597 {
00598         u8 *buf;
00599         size_t buf_len;
00600         int ret;
00601 
00602         if (key) {
00603                 buf_len = 2 + key_len;
00604                 buf = os_malloc(buf_len);
00605                 if (buf == NULL)
00606                         return -1;
00607                 WPA_PUT_BE16(buf, key_len);
00608                 os_memcpy(buf + 2, key, key_len);
00609         } else {
00610                 buf = NULL;
00611                 buf_len = 0;
00612         }
00613 
00614         wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Session keys for TLS/IA inner "
00615                         "secret permutation", buf, buf_len);
00616         ret = tls_connection_ia_permute_inner_secret(sm->ssl_ctx,
00617                                                      data->ssl.conn,
00618                                                      buf, buf_len);
00619         os_free(buf);
00620 
00621         return ret;
00622 }
00623 
00624 
00625 static void eap_ttls_process_phase2_pap(struct eap_sm *sm,
00626                                         struct eap_ttls_data *data,
00627                                         const u8 *user_password,
00628                                         size_t user_password_len)
00629 {
00630         if (!sm->user || !sm->user->password || sm->user->password_hash ||
00631             !(sm->user->ttls_auth & EAP_TTLS_AUTH_PAP)) {
00632                 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No plaintext user "
00633                            "password configured");
00634                 eap_ttls_state(data, FAILURE);
00635                 return;
00636         }
00637 
00638         if (sm->user->password_len != user_password_len ||
00639             os_memcmp(sm->user->password, user_password, user_password_len) !=
00640             0) {
00641                 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");
00642                 eap_ttls_state(data, FAILURE);
00643                 return;
00644         }
00645 
00646         wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password");
00647         eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :
00648                        SUCCESS);
00649 }
00650 
00651 
00652 static void eap_ttls_process_phase2_chap(struct eap_sm *sm,
00653                                          struct eap_ttls_data *data,
00654                                          const u8 *challenge,
00655                                          size_t challenge_len,
00656                                          const u8 *password,
00657                                          size_t password_len)
00658 {
00659         u8 *chal, hash[CHAP_MD5_LEN];
00660 
00661         if (challenge == NULL || password == NULL ||
00662             challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN ||
00663             password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) {
00664                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes "
00665                            "(challenge len %lu password len %lu)",
00666                            (unsigned long) challenge_len,
00667                            (unsigned long) password_len);
00668                 eap_ttls_state(data, FAILURE);
00669                 return;
00670         }
00671 
00672         if (!sm->user || !sm->user->password || sm->user->password_hash ||
00673             !(sm->user->ttls_auth & EAP_TTLS_AUTH_CHAP)) {
00674                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No plaintext user "
00675                            "password configured");
00676                 eap_ttls_state(data, FAILURE);
00677                 return;
00678         }
00679 
00680         chal = eap_ttls_implicit_challenge(sm, data,
00681                                            EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
00682         if (chal == NULL) {
00683                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate "
00684                            "challenge from TLS data");
00685                 eap_ttls_state(data, FAILURE);
00686                 return;
00687         }
00688 
00689         if (os_memcmp(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) != 0 ||
00690             password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) {
00691                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch");
00692                 os_free(chal);
00693                 eap_ttls_state(data, FAILURE);
00694                 return;
00695         }
00696         os_free(chal);
00697 
00698         /* MD5(Ident + Password + Challenge) */
00699         chap_md5(password[0], sm->user->password, sm->user->password_len,
00700                  challenge, challenge_len, hash);
00701 
00702         if (os_memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) {
00703                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
00704                 eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :
00705                                SUCCESS);
00706         } else {
00707                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password");
00708                 eap_ttls_state(data, FAILURE);
00709         }
00710 }
00711 
00712 
00713 static void eap_ttls_process_phase2_mschap(struct eap_sm *sm,
00714                                            struct eap_ttls_data *data,
00715                                            u8 *challenge, size_t challenge_len,
00716                                            u8 *response, size_t response_len)
00717 {
00718         u8 *chal, nt_response[24];
00719 
00720         if (challenge == NULL || response == NULL ||
00721             challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN ||
00722             response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) {
00723                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP "
00724                            "attributes (challenge len %lu response len %lu)",
00725                            (unsigned long) challenge_len,
00726                            (unsigned long) response_len);
00727                 eap_ttls_state(data, FAILURE);
00728                 return;
00729         }
00730 
00731         if (!sm->user || !sm->user->password ||
00732             !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAP)) {
00733                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password "
00734                            "configured");
00735                 eap_ttls_state(data, FAILURE);
00736                 return;
00737         }
00738 
00739         chal = eap_ttls_implicit_challenge(sm, data,
00740                                            EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
00741         if (chal == NULL) {
00742                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate "
00743                            "challenge from TLS data");
00744                 eap_ttls_state(data, FAILURE);
00745                 return;
00746         }
00747 
00748         if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) != 0 ||
00749             response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {
00750                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch");
00751                 os_free(chal);
00752                 eap_ttls_state(data, FAILURE);
00753                 return;
00754         }
00755         os_free(chal);
00756 
00757         if (sm->user->password_hash)
00758                 challenge_response(challenge, sm->user->password, nt_response);
00759         else
00760                 nt_challenge_response(challenge, sm->user->password,
00761                                       sm->user->password_len, nt_response);
00762 
00763         if (os_memcmp(nt_response, response + 2 + 24, 24) == 0) {
00764                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
00765                 eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :
00766                                SUCCESS);
00767         } else {
00768                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response");
00769                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received",
00770                             response + 2 + 24, 24);
00771                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected",
00772                             nt_response, 24);
00773                 eap_ttls_state(data, FAILURE);
00774         }
00775 }
00776 
00777 
00778 static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
00779                                              struct eap_ttls_data *data,
00780                                              u8 *challenge,
00781                                              size_t challenge_len,
00782                                              u8 *response, size_t response_len)
00783 {
00784         u8 *chal, *username, nt_response[24], *rx_resp, *peer_challenge,
00785                 *auth_challenge;
00786         size_t username_len, i;
00787 
00788         if (challenge == NULL || response == NULL ||
00789             challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN ||
00790             response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) {
00791                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 "
00792                            "attributes (challenge len %lu response len %lu)",
00793                            (unsigned long) challenge_len,
00794                            (unsigned long) response_len);
00795                 eap_ttls_state(data, FAILURE);
00796                 return;
00797         }
00798 
00799         if (!sm->user || !sm->user->password ||
00800             !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAPV2)) {
00801                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password "
00802                            "configured");
00803                 eap_ttls_state(data, FAILURE);
00804                 return;
00805         }
00806 
00807         /* MSCHAPv2 does not include optional domain name in the
00808          * challenge-response calculation, so remove domain prefix
00809          * (if present). */
00810         username = sm->identity;
00811         username_len = sm->identity_len;
00812         for (i = 0; i < username_len; i++) {
00813                 if (username[i] == '\\') {
00814                         username_len -= i + 1;
00815                         username += i + 1;
00816                         break;
00817                 }
00818         }
00819 
00820         chal = eap_ttls_implicit_challenge(
00821                 sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
00822         if (chal == NULL) {
00823                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate "
00824                            "challenge from TLS data");
00825                 eap_ttls_state(data, FAILURE);
00826                 return;
00827         }
00828 
00829         if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) != 0 ||
00830             response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) {
00831                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch");
00832                 os_free(chal);
00833                 eap_ttls_state(data, FAILURE);
00834                 return;
00835         }
00836         os_free(chal);
00837 
00838         auth_challenge = challenge;
00839         peer_challenge = response + 2;
00840 
00841         wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User",
00842                           username, username_len);
00843         wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge",
00844                     auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
00845         wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge",
00846                     peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
00847 
00848         if (sm->user->password_hash) {
00849                 generate_nt_response_pwhash(auth_challenge, peer_challenge,
00850                                             username, username_len,
00851                                             sm->user->password,
00852                                             nt_response);
00853         } else {
00854                 generate_nt_response(auth_challenge, peer_challenge,
00855                                      username, username_len,
00856                                      sm->user->password,
00857                                      sm->user->password_len,
00858                                      nt_response);
00859         }
00860 
00861         rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
00862         if (os_memcmp(nt_response, rx_resp, 24) == 0) {
00863                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
00864                            "NT-Response");
00865                 data->mschapv2_resp_ok = 1;
00866                 if (data->ttls_version > 0) {
00867                         const u8 *pw_hash;
00868                         u8 pw_hash_buf[16], pw_hash_hash[16], master_key[16];
00869                         u8 session_key[2 * MSCHAPV2_KEY_LEN];
00870 
00871                         if (sm->user->password_hash)
00872                                 pw_hash = sm->user->password;
00873                         else {
00874                                 nt_password_hash(sm->user->password,
00875                                                  sm->user->password_len,
00876                                                  pw_hash_buf);
00877                                 pw_hash = pw_hash_buf;
00878                         }
00879                         hash_nt_password_hash(pw_hash, pw_hash_hash);
00880                         get_master_key(pw_hash_hash, nt_response, master_key);
00881                         get_asymetric_start_key(master_key, session_key,
00882                                                 MSCHAPV2_KEY_LEN, 0, 0);
00883                         get_asymetric_start_key(master_key,
00884                                                 session_key + MSCHAPV2_KEY_LEN,
00885                                                 MSCHAPV2_KEY_LEN, 1, 0);
00886                         eap_ttls_ia_permute_inner_secret(sm, data,
00887                                                          session_key,
00888                                                          sizeof(session_key));
00889                 }
00890 
00891                 if (sm->user->password_hash) {
00892                         generate_authenticator_response_pwhash(
00893                                 sm->user->password,
00894                                 peer_challenge, auth_challenge,
00895                                 username, username_len, nt_response,
00896                                 data->mschapv2_auth_response);
00897                 } else {
00898                         generate_authenticator_response(
00899                                 sm->user->password, sm->user->password_len,
00900                                 peer_challenge, auth_challenge,
00901                                 username, username_len, nt_response,
00902                                 data->mschapv2_auth_response);
00903                 }
00904         } else {
00905                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid "
00906                            "NT-Response");
00907                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received",
00908                             rx_resp, 24);
00909                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected",
00910                             nt_response, 24);
00911                 data->mschapv2_resp_ok = 0;
00912         }
00913         eap_ttls_state(data, PHASE2_MSCHAPV2_RESP);
00914         data->mschapv2_ident = response[0];
00915 }
00916 
00917 
00918 static int eap_ttls_phase2_eap_init(struct eap_sm *sm,
00919                                     struct eap_ttls_data *data,
00920                                     EapType eap_type)
00921 {
00922         if (data->phase2_priv && data->phase2_method) {
00923                 data->phase2_method->reset(sm, data->phase2_priv);
00924                 data->phase2_method = NULL;
00925                 data->phase2_priv = NULL;
00926         }
00927         data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
00928                                                         eap_type);
00929         if (!data->phase2_method)
00930                 return -1;
00931 
00932         sm->init_phase2 = 1;
00933         data->phase2_priv = data->phase2_method->init(sm);
00934         sm->init_phase2 = 0;
00935         return data->phase2_priv == NULL ? -1 : 0;
00936 }
00937 
00938 
00939 static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm,
00940                                                  struct eap_ttls_data *data,
00941                                                  u8 *in_data, size_t in_len)
00942 {
00943         u8 next_type = EAP_TYPE_NONE;
00944         struct eap_hdr *hdr;
00945         u8 *pos;
00946         size_t left;
00947         struct wpabuf buf;
00948         const struct eap_method *m = data->phase2_method;
00949         void *priv = data->phase2_priv;
00950 
00951         if (priv == NULL) {
00952                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not "
00953                            "initialized?!", __func__);
00954                 return;
00955         }
00956 
00957         hdr = (struct eap_hdr *) in_data;
00958         pos = (u8 *) (hdr + 1);
00959 
00960         if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
00961                 left = in_len - sizeof(*hdr);
00962                 wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; "
00963                             "allowed types", pos + 1, left - 1);
00964                 eap_sm_process_nak(sm, pos + 1, left - 1);
00965                 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
00966                     sm->user->methods[sm->user_eap_method_index].method !=
00967                     EAP_TYPE_NONE) {
00968                         next_type = sm->user->methods[
00969                                 sm->user_eap_method_index++].method;
00970                         wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d",
00971                                    next_type);
00972                         if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
00973                                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to "
00974                                            "initialize EAP type %d",
00975                                            next_type);
00976                                 eap_ttls_state(data, FAILURE);
00977                                 return;
00978                         }
00979                 } else {
00980                         eap_ttls_state(data, FAILURE);
00981                 }
00982                 return;
00983         }
00984 
00985         wpabuf_set(&buf, in_data, in_len);
00986 
00987         if (m->check(sm, priv, &buf)) {
00988                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to "
00989                            "ignore the packet");
00990                 return;
00991         }
00992 
00993         m->process(sm, priv, &buf);
00994 
00995         if (sm->method_pending == METHOD_PENDING_WAIT) {
00996                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method is in "
00997                            "pending wait state - save decrypted response");
00998                 wpabuf_free(data->pending_phase2_eap_resp);
00999                 data->pending_phase2_eap_resp = wpabuf_dup(&buf);
01000         }
01001 
01002         if (!m->isDone(sm, priv))
01003                 return;
01004 
01005         if (!m->isSuccess(sm, priv)) {
01006                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed");
01007                 eap_ttls_state(data, FAILURE);
01008                 return;
01009         }
01010 
01011         switch (data->state) {
01012         case PHASE2_START:
01013                 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
01014                         wpa_hexdump_ascii(MSG_DEBUG, "EAP_TTLS: Phase2 "
01015                                           "Identity not found in the user "
01016                                           "database",
01017                                           sm->identity, sm->identity_len);
01018                         eap_ttls_state(data, FAILURE);
01019                         break;
01020                 }
01021 
01022                 eap_ttls_state(data, PHASE2_METHOD);
01023                 next_type = sm->user->methods[0].method;
01024                 sm->user_eap_method_index = 1;
01025                 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type);
01026                 if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
01027                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize "
01028                                    "EAP type %d", next_type);
01029                         eap_ttls_state(data, FAILURE);
01030                 }
01031                 break;
01032         case PHASE2_METHOD:
01033                 if (data->ttls_version > 0) {
01034                         if (m->getKey) {
01035                                 u8 *key;
01036                                 size_t key_len;
01037                                 key = m->getKey(sm, priv, &key_len);
01038                                 eap_ttls_ia_permute_inner_secret(sm, data,
01039                                                                  key, key_len);
01040                         }
01041                         eap_ttls_state(data, PHASE_FINISHED);
01042                 } else
01043                         eap_ttls_state(data, SUCCESS);
01044                 break;
01045         case FAILURE:
01046                 break;
01047         default:
01048                 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
01049                            __func__, data->state);
01050                 break;
01051         }
01052 }
01053 
01054 
01055 static void eap_ttls_process_phase2_eap(struct eap_sm *sm,
01056                                         struct eap_ttls_data *data,
01057                                         const u8 *eap, size_t eap_len)
01058 {
01059         struct eap_hdr *hdr;
01060         size_t len;
01061 
01062         if (data->state == PHASE2_START) {
01063                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2");
01064                 if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_IDENTITY) < 0)
01065                 {
01066                         wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: failed to "
01067                                    "initialize EAP-Identity");
01068                         return;
01069                 }
01070         }
01071 
01072         if (eap_len < sizeof(*hdr)) {
01073                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: too short Phase 2 EAP "
01074                            "packet (len=%lu)", (unsigned long) eap_len);
01075                 return;
01076         }
01077 
01078         hdr = (struct eap_hdr *) eap;
01079         len = be_to_host16(hdr->length);
01080         wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d "
01081                    "identifier=%d length=%lu", hdr->code, hdr->identifier,
01082                    (unsigned long) len);
01083         if (len > eap_len) {
01084                 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Length mismatch in Phase 2"
01085                            " EAP frame (hdr len=%lu, data len in AVP=%lu)",
01086                            (unsigned long) len, (unsigned long) eap_len);
01087                 return;
01088         }
01089 
01090         switch (hdr->code) {
01091         case EAP_CODE_RESPONSE:
01092                 eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr,
01093                                                      len);
01094                 break;
01095         default:
01096                 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in "
01097                            "Phase 2 EAP header", hdr->code);
01098                 break;
01099         }
01100 }
01101 
01102 
01103 static void eap_ttls_process_phase2(struct eap_sm *sm,
01104                                     struct eap_ttls_data *data,
01105                                     struct wpabuf *in_buf)
01106 {
01107         struct wpabuf *in_decrypted;
01108         struct eap_ttls_avp parse;
01109 
01110         wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
01111                    " Phase 2", (unsigned long) wpabuf_len(in_buf));
01112 
01113         if (data->pending_phase2_eap_resp) {
01114                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 EAP response "
01115                            "- skip decryption and use old data");
01116                 eap_ttls_process_phase2_eap(
01117                         sm, data, wpabuf_head(data->pending_phase2_eap_resp),
01118                         wpabuf_len(data->pending_phase2_eap_resp));
01119                 wpabuf_free(data->pending_phase2_eap_resp);
01120                 data->pending_phase2_eap_resp = NULL;
01121                 return;
01122         }
01123 
01124         in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
01125                                               in_buf);
01126         if (in_decrypted == NULL) {
01127                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "
01128                            "data");
01129                 eap_ttls_state(data, FAILURE);
01130                 return;
01131         }
01132 
01133         if (data->state == PHASE_FINISHED) {
01134                 if (wpabuf_len(in_decrypted) == 0 &&
01135                     tls_connection_ia_final_phase_finished(sm->ssl_ctx,
01136                                                            data->ssl.conn)) {
01137                         wpa_printf(MSG_DEBUG, "EAP-TTLS: FinalPhaseFinished "
01138                                    "received");
01139                         eap_ttls_state(data, SUCCESS);
01140                 } else {
01141                         wpa_printf(MSG_INFO, "EAP-TTLS: Did not receive valid "
01142                                    "FinalPhaseFinished");
01143                         eap_ttls_state(data, FAILURE);
01144                 }
01145 
01146                 wpabuf_free(in_decrypted);
01147                 return;
01148         }
01149 
01150         wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP",
01151                             in_decrypted);
01152 
01153         if (eap_ttls_avp_parse(in_decrypted, &parse) < 0) {
01154                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs");
01155                 wpabuf_free(in_decrypted);
01156                 eap_ttls_state(data, FAILURE);
01157                 return;
01158         }
01159 
01160         if (parse.user_name) {
01161                 os_free(sm->identity);
01162                 sm->identity = os_malloc(parse.user_name_len);
01163                 if (sm->identity) {
01164                         os_memcpy(sm->identity, parse.user_name,
01165                                   parse.user_name_len);
01166                         sm->identity_len = parse.user_name_len;
01167                 }
01168                 if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1)
01169                     != 0) {
01170                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not "
01171                                    "found in the user database");
01172                         eap_ttls_state(data, FAILURE);
01173                         goto done;
01174                 }
01175         }
01176 
01177 #ifdef EAP_SERVER_TNC
01178         if (data->tnc_started && parse.eap == NULL) {
01179                 wpa_printf(MSG_DEBUG, "EAP-TTLS: TNC started but no EAP "
01180                            "response from peer");
01181                 eap_ttls_state(data, FAILURE);
01182                 goto done;
01183         }
01184 #endif /* EAP_SERVER_TNC */
01185 
01186         if (parse.eap) {
01187                 eap_ttls_process_phase2_eap(sm, data, parse.eap,
01188                                             parse.eap_len);
01189         } else if (parse.user_password) {
01190                 eap_ttls_process_phase2_pap(sm, data, parse.user_password,
01191                                             parse.user_password_len);
01192         } else if (parse.chap_password) {
01193                 eap_ttls_process_phase2_chap(sm, data,
01194                                              parse.chap_challenge,
01195                                              parse.chap_challenge_len,
01196                                              parse.chap_password,
01197                                              parse.chap_password_len);
01198         } else if (parse.mschap_response) {
01199                 eap_ttls_process_phase2_mschap(sm, data,
01200                                                parse.mschap_challenge,
01201                                                parse.mschap_challenge_len,
01202                                                parse.mschap_response,
01203                                                parse.mschap_response_len);
01204         } else if (parse.mschap2_response) {
01205                 eap_ttls_process_phase2_mschapv2(sm, data,
01206                                                  parse.mschap_challenge,
01207                                                  parse.mschap_challenge_len,
01208                                                  parse.mschap2_response,
01209                                                  parse.mschap2_response_len);
01210         }
01211 
01212 done:
01213         wpabuf_free(in_decrypted);
01214         os_free(parse.eap);
01215 }
01216 
01217 
01218 static void eap_ttls_start_tnc(struct eap_sm *sm, struct eap_ttls_data *data)
01219 {
01220 #ifdef EAP_SERVER_TNC
01221         if (!sm->tnc || data->state != SUCCESS || data->tnc_started)
01222                 return;
01223 
01224         wpa_printf(MSG_DEBUG, "EAP-TTLS: Initialize TNC");
01225         if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_TNC)) {
01226                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize TNC");
01227                 eap_ttls_state(data, FAILURE);
01228                 return;
01229         }
01230 
01231         data->tnc_started = 1;
01232         eap_ttls_state(data, PHASE2_METHOD);
01233 #endif /* EAP_SERVER_TNC */
01234 }
01235 
01236 
01237 static int eap_ttls_process_version(struct eap_sm *sm, void *priv,
01238                                     int peer_version)
01239 {
01240         struct eap_ttls_data *data = priv;
01241         if (peer_version < data->ttls_version) {
01242                 wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; "
01243                            "use version %d",
01244                            peer_version, data->ttls_version, peer_version);
01245                 data->ttls_version = peer_version;
01246         }
01247 
01248         if (data->ttls_version > 0 && !data->tls_ia_configured) {
01249                 if (tls_connection_set_ia(sm->ssl_ctx, data->ssl.conn, 1)) {
01250                         wpa_printf(MSG_INFO, "EAP-TTLS: Failed to enable "
01251                                    "TLS/IA");
01252                         return -1;
01253                 }
01254                 data->tls_ia_configured = 1;
01255         }
01256 
01257         return 0;
01258 }
01259 
01260 
01261 static void eap_ttls_process_msg(struct eap_sm *sm, void *priv,
01262                                  const struct wpabuf *respData)
01263 {
01264         struct eap_ttls_data *data = priv;
01265 
01266         switch (data->state) {
01267         case PHASE1:
01268                 if (eap_server_tls_phase1(sm, &data->ssl) < 0)
01269                         eap_ttls_state(data, FAILURE);
01270                 break;
01271         case PHASE2_START:
01272         case PHASE2_METHOD:
01273         case PHASE_FINISHED:
01274                 eap_ttls_process_phase2(sm, data, data->ssl.tls_in);
01275                 eap_ttls_start_tnc(sm, data);
01276                 break;
01277         case PHASE2_MSCHAPV2_RESP:
01278                 if (data->mschapv2_resp_ok && wpabuf_len(data->ssl.tls_in) ==
01279                     0) {
01280                         wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
01281                                    "acknowledged response");
01282                         eap_ttls_state(data, data->ttls_version > 0 ?
01283                                        PHASE_FINISHED : SUCCESS);
01284                 } else if (!data->mschapv2_resp_ok) {
01285                         wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
01286                                    "acknowledged error");
01287                         eap_ttls_state(data, FAILURE);
01288                 } else {
01289                         wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected "
01290                                    "frame from peer (payload len %lu, "
01291                                    "expected empty frame)",
01292                                    (unsigned long)
01293                                    wpabuf_len(data->ssl.tls_in));
01294                         eap_ttls_state(data, FAILURE);
01295                 }
01296                 eap_ttls_start_tnc(sm, data);
01297                 break;
01298         default:
01299                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s",
01300                            data->state, __func__);
01301                 break;
01302         }
01303 }
01304 
01305 
01306 static void eap_ttls_process(struct eap_sm *sm, void *priv,
01307                              struct wpabuf *respData)
01308 {
01309         struct eap_ttls_data *data = priv;
01310         if (eap_server_tls_process(sm, &data->ssl, respData, data,
01311                                    EAP_TYPE_TTLS, eap_ttls_process_version,
01312                                    eap_ttls_process_msg) < 0)
01313                 eap_ttls_state(data, FAILURE);
01314 }
01315 
01316 
01317 static Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv)
01318 {
01319         struct eap_ttls_data *data = priv;
01320         return data->state == SUCCESS || data->state == FAILURE;
01321 }
01322 
01323 
01324 static u8 * eap_ttls_v1_derive_key(struct eap_sm *sm,
01325                                    struct eap_ttls_data *data)
01326 {
01327         struct tls_keys keys;
01328         u8 *rnd, *key;
01329 
01330         os_memset(&keys, 0, sizeof(keys));
01331         if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
01332             keys.client_random == NULL || keys.server_random == NULL ||
01333             keys.inner_secret == NULL) {
01334                 wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, "
01335                            "client random, or server random to derive keying "
01336                            "material");
01337                 return NULL;
01338         }
01339 
01340         rnd = os_malloc(keys.client_random_len + keys.server_random_len);
01341         key = os_malloc(EAP_TLS_KEY_LEN);
01342         if (rnd == NULL || key == NULL) {
01343                 wpa_printf(MSG_INFO, "EAP-TTLS: No memory for key derivation");
01344                 os_free(rnd);
01345                 os_free(key);
01346                 return NULL;
01347         }
01348         os_memcpy(rnd, keys.client_random, keys.client_random_len);
01349         os_memcpy(rnd + keys.client_random_len, keys.server_random,
01350                   keys.server_random_len);
01351 
01352         if (tls_prf(keys.inner_secret, keys.inner_secret_len,
01353                     "ttls v1 keying material", rnd, keys.client_random_len +
01354                     keys.server_random_len, key, EAP_TLS_KEY_LEN)) {
01355                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
01356                 os_free(rnd);
01357                 os_free(key);
01358                 return NULL;
01359         }
01360 
01361         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: client/server random",
01362                     rnd, keys.client_random_len + keys.server_random_len);
01363         wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: TLS/IA inner secret",
01364                         keys.inner_secret, keys.inner_secret_len);
01365 
01366         os_free(rnd);
01367 
01368         return key;
01369 }
01370 
01371 
01372 static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
01373 {
01374         struct eap_ttls_data *data = priv;
01375         u8 *eapKeyData;
01376 
01377         if (data->state != SUCCESS)
01378                 return NULL;
01379 
01380         if (data->ttls_version == 0) {
01381                 eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
01382                                                        "ttls keying material",
01383                                                        EAP_TLS_KEY_LEN);
01384         } else {
01385                 eapKeyData = eap_ttls_v1_derive_key(sm, data);
01386         }
01387 
01388         if (eapKeyData) {
01389                 *len = EAP_TLS_KEY_LEN;
01390                 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
01391                                 eapKeyData, EAP_TLS_KEY_LEN);
01392         } else {
01393                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
01394         }
01395 
01396         return eapKeyData;
01397 }
01398 
01399 
01400 static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv)
01401 {
01402         struct eap_ttls_data *data = priv;
01403         return data->state == SUCCESS;
01404 }
01405 
01406 
01407 int eap_server_ttls_register(void)
01408 {
01409         struct eap_method *eap;
01410         int ret;
01411 
01412         eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
01413                                       EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
01414         if (eap == NULL)
01415                 return -1;
01416 
01417         eap->init = eap_ttls_init;
01418         eap->reset = eap_ttls_reset;
01419         eap->buildReq = eap_ttls_buildReq;
01420         eap->check = eap_ttls_check;
01421         eap->process = eap_ttls_process;
01422         eap->isDone = eap_ttls_isDone;
01423         eap->getKey = eap_ttls_getKey;
01424         eap->isSuccess = eap_ttls_isSuccess;
01425 
01426         ret = eap_server_method_register(eap);
01427         if (ret)
01428                 eap_server_method_free(eap);
01429         return ret;
01430 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:35