eap_ttls.c

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

Generated on Sat Nov 21 23:16:52 2009 for hostapd by  doxygen 1.6.1