LCOV - code coverage report
Current view: top level - src/eap_server - eap_server_ttls.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1443382998 Lines: 533 675 79.0 %
Date: 2015-09-27 Functions: 32 32 100.0 %

          Line data    Source code
       1             : /*
       2             :  * hostapd / EAP-TTLS (RFC 5281)
       3             :  * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "includes.h"
      10             : 
      11             : #include "common.h"
      12             : #include "crypto/ms_funcs.h"
      13             : #include "crypto/sha1.h"
      14             : #include "crypto/tls.h"
      15             : #include "eap_server/eap_i.h"
      16             : #include "eap_server/eap_tls_common.h"
      17             : #include "eap_common/chap.h"
      18             : #include "eap_common/eap_ttls.h"
      19             : 
      20             : 
      21             : #define EAP_TTLS_VERSION 0
      22             : 
      23             : 
      24             : static void eap_ttls_reset(struct eap_sm *sm, void *priv);
      25             : 
      26             : 
      27             : struct eap_ttls_data {
      28             :         struct eap_ssl_data ssl;
      29             :         enum {
      30             :                 START, PHASE1, PHASE2_START, PHASE2_METHOD,
      31             :                 PHASE2_MSCHAPV2_RESP, SUCCESS, FAILURE
      32             :         } state;
      33             : 
      34             :         int ttls_version;
      35             :         const struct eap_method *phase2_method;
      36             :         void *phase2_priv;
      37             :         int mschapv2_resp_ok;
      38             :         u8 mschapv2_auth_response[20];
      39             :         u8 mschapv2_ident;
      40             :         struct wpabuf *pending_phase2_eap_resp;
      41             :         int tnc_started;
      42             : };
      43             : 
      44             : 
      45        1632 : static const char * eap_ttls_state_txt(int state)
      46             : {
      47        1632 :         switch (state) {
      48             :         case START:
      49         327 :                 return "START";
      50             :         case PHASE1:
      51         529 :                 return "PHASE1";
      52             :         case PHASE2_START:
      53         349 :                 return "PHASE2_START";
      54             :         case PHASE2_METHOD:
      55          55 :                 return "PHASE2_METHOD";
      56             :         case PHASE2_MSCHAPV2_RESP:
      57         172 :                 return "PHASE2_MSCHAPV2_RESP";
      58             :         case SUCCESS:
      59         159 :                 return "SUCCESS";
      60             :         case FAILURE:
      61          41 :                 return "FAILURE";
      62             :         default:
      63           0 :                 return "Unknown?!";
      64             :         }
      65             : }
      66             : 
      67             : 
      68         816 : static void eap_ttls_state(struct eap_ttls_data *data, int state)
      69             : {
      70        1632 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s",
      71         816 :                    eap_ttls_state_txt(data->state),
      72             :                    eap_ttls_state_txt(state));
      73         816 :         data->state = state;
      74         816 :         if (state == FAILURE)
      75          41 :                 tls_connection_remove_session(data->ssl.conn);
      76         816 : }
      77             : 
      78             : 
      79         152 : static void eap_ttls_valid_session(struct eap_sm *sm,
      80             :                                    struct eap_ttls_data *data)
      81             : {
      82             :         struct wpabuf *buf;
      83             : 
      84         152 :         if (!sm->tls_session_lifetime)
      85         147 :                 return;
      86             : 
      87           5 :         buf = wpabuf_alloc(1 + 1 + sm->identity_len);
      88           5 :         if (!buf)
      89           0 :                 return;
      90           5 :         wpabuf_put_u8(buf, EAP_TYPE_TTLS);
      91           5 :         if (sm->identity) {
      92             :                 u8 id_len;
      93             : 
      94           5 :                 if (sm->identity_len <= 255)
      95           5 :                         id_len = sm->identity_len;
      96             :                 else
      97           0 :                         id_len = 255;
      98           5 :                 wpabuf_put_u8(buf, id_len);
      99           5 :                 wpabuf_put_data(buf, sm->identity, id_len);
     100             :         } else {
     101           0 :                 wpabuf_put_u8(buf, 0);
     102             :         }
     103           5 :         tls_connection_set_success_data(data->ssl.conn, buf);
     104             : }
     105             : 
     106             : 
     107         154 : static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
     108             :                              int mandatory, size_t len)
     109             : {
     110             :         struct ttls_avp_vendor *avp;
     111             :         u8 flags;
     112             :         size_t hdrlen;
     113             : 
     114         154 :         avp = (struct ttls_avp_vendor *) avphdr;
     115         154 :         flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
     116         154 :         if (vendor_id) {
     117          86 :                 flags |= AVP_FLAGS_VENDOR;
     118          86 :                 hdrlen = sizeof(*avp);
     119          86 :                 avp->vendor_id = host_to_be32(vendor_id);
     120             :         } else {
     121          68 :                 hdrlen = sizeof(struct ttls_avp);
     122             :         }
     123             : 
     124         154 :         avp->avp_code = host_to_be32(avp_code);
     125         154 :         avp->avp_length = host_to_be32(((u32) flags << 24) |
     126             :                                        ((u32) (hdrlen + len)));
     127             : 
     128         154 :         return avphdr + hdrlen;
     129             : }
     130             : 
     131             : 
     132          68 : static struct wpabuf * eap_ttls_avp_encapsulate(struct wpabuf *resp,
     133             :                                                 u32 avp_code, int mandatory)
     134             : {
     135             :         struct wpabuf *avp;
     136             :         u8 *pos;
     137             : 
     138          68 :         avp = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(resp) + 4);
     139          68 :         if (avp == NULL) {
     140           0 :                 wpabuf_free(resp);
     141           0 :                 return NULL;
     142             :         }
     143             : 
     144          68 :         pos = eap_ttls_avp_hdr(wpabuf_mhead(avp), avp_code, 0, mandatory,
     145             :                                wpabuf_len(resp));
     146          68 :         os_memcpy(pos, wpabuf_head(resp), wpabuf_len(resp));
     147          68 :         pos += wpabuf_len(resp);
     148          68 :         AVP_PAD((const u8 *) wpabuf_head(avp), pos);
     149          68 :         wpabuf_free(resp);
     150          68 :         wpabuf_put(avp, pos - (u8 *) wpabuf_head(avp));
     151          68 :         return avp;
     152             : }
     153             : 
     154             : 
     155             : struct eap_ttls_avp {
     156             :          /* Note: eap is allocated memory; caller is responsible for freeing
     157             :           * it. All the other pointers are pointing to the packet data, i.e.,
     158             :           * they must not be freed separately. */
     159             :         u8 *eap;
     160             :         size_t eap_len;
     161             :         u8 *user_name;
     162             :         size_t user_name_len;
     163             :         u8 *user_password;
     164             :         size_t user_password_len;
     165             :         u8 *chap_challenge;
     166             :         size_t chap_challenge_len;
     167             :         u8 *chap_password;
     168             :         size_t chap_password_len;
     169             :         u8 *mschap_challenge;
     170             :         size_t mschap_challenge_len;
     171             :         u8 *mschap_response;
     172             :         size_t mschap_response_len;
     173             :         u8 *mschap2_response;
     174             :         size_t mschap2_response_len;
     175             : };
     176             : 
     177             : 
     178         242 : static int eap_ttls_avp_parse(struct wpabuf *buf, struct eap_ttls_avp *parse)
     179             : {
     180             :         struct ttls_avp *avp;
     181             :         u8 *pos;
     182             :         int left;
     183             : 
     184         242 :         pos = wpabuf_mhead(buf);
     185         242 :         left = wpabuf_len(buf);
     186         242 :         os_memset(parse, 0, sizeof(*parse));
     187             : 
     188         980 :         while (left > 0) {
     189         496 :                 u32 avp_code, avp_length, vendor_id = 0;
     190             :                 u8 avp_flags, *dpos;
     191             :                 size_t pad, dlen;
     192         496 :                 avp = (struct ttls_avp *) pos;
     193         496 :                 avp_code = be_to_host32(avp->avp_code);
     194         496 :                 avp_length = be_to_host32(avp->avp_length);
     195         496 :                 avp_flags = (avp_length >> 24) & 0xff;
     196         496 :                 avp_length &= 0xffffff;
     197         496 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
     198             :                            "length=%d", (int) avp_code, avp_flags,
     199             :                            (int) avp_length);
     200         496 :                 if ((int) avp_length > left) {
     201           0 :                         wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
     202             :                                    "(len=%d, left=%d) - dropped",
     203             :                                    (int) avp_length, left);
     204           0 :                         goto fail;
     205             :                 }
     206         496 :                 if (avp_length < sizeof(*avp)) {
     207           0 :                         wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length "
     208             :                                    "%d", avp_length);
     209           0 :                         goto fail;
     210             :                 }
     211         496 :                 dpos = (u8 *) (avp + 1);
     212         496 :                 dlen = avp_length - sizeof(*avp);
     213         496 :                 if (avp_flags & AVP_FLAGS_VENDOR) {
     214         200 :                         if (dlen < 4) {
     215           0 :                                 wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP "
     216             :                                            "underflow");
     217           0 :                                 goto fail;
     218             :                         }
     219         200 :                         vendor_id = be_to_host32(* (be32 *) dpos);
     220         200 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
     221             :                                    (int) vendor_id);
     222         200 :                         dpos += 4;
     223         200 :                         dlen -= 4;
     224             :                 }
     225             : 
     226         496 :                 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
     227             : 
     228         496 :                 if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
     229          97 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
     230         194 :                         if (parse->eap == NULL) {
     231          97 :                                 parse->eap = os_malloc(dlen);
     232          97 :                                 if (parse->eap == NULL) {
     233           0 :                                         wpa_printf(MSG_WARNING, "EAP-TTLS: "
     234             :                                                    "failed to allocate memory "
     235             :                                                    "for Phase 2 EAP data");
     236           0 :                                         goto fail;
     237             :                                 }
     238          97 :                                 os_memcpy(parse->eap, dpos, dlen);
     239          97 :                                 parse->eap_len = dlen;
     240             :                         } else {
     241           0 :                                 u8 *neweap = os_realloc(parse->eap,
     242           0 :                                                         parse->eap_len + dlen);
     243           0 :                                 if (neweap == NULL) {
     244           0 :                                         wpa_printf(MSG_WARNING, "EAP-TTLS: "
     245             :                                                    "failed to allocate memory "
     246             :                                                    "for Phase 2 EAP data");
     247           0 :                                         goto fail;
     248             :                                 }
     249           0 :                                 os_memcpy(neweap + parse->eap_len, dpos, dlen);
     250           0 :                                 parse->eap = neweap;
     251           0 :                                 parse->eap_len += dlen;
     252             :                         }
     253         399 :                 } else if (vendor_id == 0 &&
     254             :                            avp_code == RADIUS_ATTR_USER_NAME) {
     255         145 :                         wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name",
     256             :                                           dpos, dlen);
     257         145 :                         parse->user_name = dpos;
     258         145 :                         parse->user_name_len = dlen;
     259         254 :                 } else if (vendor_id == 0 &&
     260          36 :                            avp_code == RADIUS_ATTR_USER_PASSWORD) {
     261          36 :                         u8 *password = dpos;
     262          36 :                         size_t password_len = dlen;
     263         658 :                         while (password_len > 0 &&
     264         311 :                                password[password_len - 1] == '\0') {
     265         275 :                                 password_len--;
     266             :                         }
     267          36 :                         wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: "
     268             :                                               "User-Password (PAP)",
     269             :                                               password, password_len);
     270          36 :                         parse->user_password = password;
     271          36 :                         parse->user_password_len = password_len;
     272         218 :                 } else if (vendor_id == 0 &&
     273             :                            avp_code == RADIUS_ATTR_CHAP_CHALLENGE) {
     274           9 :                         wpa_hexdump(MSG_DEBUG,
     275             :                                     "EAP-TTLS: CHAP-Challenge (CHAP)",
     276             :                                     dpos, dlen);
     277           9 :                         parse->chap_challenge = dpos;
     278           9 :                         parse->chap_challenge_len = dlen;
     279         209 :                 } else if (vendor_id == 0 &&
     280             :                            avp_code == RADIUS_ATTR_CHAP_PASSWORD) {
     281           9 :                         wpa_hexdump(MSG_DEBUG,
     282             :                                     "EAP-TTLS: CHAP-Password (CHAP)",
     283             :                                     dpos, dlen);
     284           9 :                         parse->chap_password = dpos;
     285           9 :                         parse->chap_password_len = dlen;
     286         200 :                 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
     287             :                            avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) {
     288         100 :                         wpa_hexdump(MSG_DEBUG,
     289             :                                     "EAP-TTLS: MS-CHAP-Challenge",
     290             :                                     dpos, dlen);
     291         100 :                         parse->mschap_challenge = dpos;
     292         100 :                         parse->mschap_challenge_len = dlen;
     293         100 :                 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
     294             :                            avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) {
     295          13 :                         wpa_hexdump(MSG_DEBUG,
     296             :                                     "EAP-TTLS: MS-CHAP-Response (MSCHAP)",
     297             :                                     dpos, dlen);
     298          13 :                         parse->mschap_response = dpos;
     299          13 :                         parse->mschap_response_len = dlen;
     300          87 :                 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
     301             :                            avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) {
     302          87 :                         wpa_hexdump(MSG_DEBUG,
     303             :                                     "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)",
     304             :                                     dpos, dlen);
     305          87 :                         parse->mschap2_response = dpos;
     306          87 :                         parse->mschap2_response_len = dlen;
     307           0 :                 } else if (avp_flags & AVP_FLAGS_MANDATORY) {
     308           0 :                         wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported "
     309             :                                    "mandatory AVP code %d vendor_id %d - "
     310             :                                    "dropped", (int) avp_code, (int) vendor_id);
     311           0 :                         goto fail;
     312             :                 } else {
     313           0 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported "
     314             :                                    "AVP code %d vendor_id %d",
     315             :                                    (int) avp_code, (int) vendor_id);
     316             :                 }
     317             : 
     318         496 :                 pad = (4 - (avp_length & 3)) & 3;
     319         496 :                 pos += avp_length + pad;
     320         496 :                 left -= avp_length + pad;
     321             :         }
     322             : 
     323         242 :         return 0;
     324             : 
     325             : fail:
     326           0 :         os_free(parse->eap);
     327           0 :         parse->eap = NULL;
     328           0 :         return -1;
     329             : }
     330             : 
     331             : 
     332         105 : static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
     333             :                                         struct eap_ttls_data *data, size_t len)
     334             : {
     335         105 :         return eap_server_tls_derive_key(sm, &data->ssl, "ttls challenge",
     336             :                                          len);
     337             : }
     338             : 
     339             : 
     340         327 : static void * eap_ttls_init(struct eap_sm *sm)
     341             : {
     342             :         struct eap_ttls_data *data;
     343             : 
     344         327 :         data = os_zalloc(sizeof(*data));
     345         327 :         if (data == NULL)
     346           0 :                 return NULL;
     347         327 :         data->ttls_version = EAP_TTLS_VERSION;
     348         327 :         data->state = START;
     349             : 
     350         327 :         if (eap_server_tls_ssl_init(sm, &data->ssl, 0, EAP_TYPE_TTLS)) {
     351           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
     352           0 :                 eap_ttls_reset(sm, data);
     353           0 :                 return NULL;
     354             :         }
     355             : 
     356         327 :         return data;
     357             : }
     358             : 
     359             : 
     360         327 : static void eap_ttls_reset(struct eap_sm *sm, void *priv)
     361             : {
     362         327 :         struct eap_ttls_data *data = priv;
     363         327 :         if (data == NULL)
     364         327 :                 return;
     365         327 :         if (data->phase2_priv && data->phase2_method)
     366          28 :                 data->phase2_method->reset(sm, data->phase2_priv);
     367         327 :         eap_server_tls_ssl_deinit(sm, &data->ssl);
     368         327 :         wpabuf_free(data->pending_phase2_eap_resp);
     369         327 :         bin_clear_free(data, sizeof(*data));
     370             : }
     371             : 
     372             : 
     373         327 : static struct wpabuf * eap_ttls_build_start(struct eap_sm *sm,
     374             :                                             struct eap_ttls_data *data, u8 id)
     375             : {       
     376             :         struct wpabuf *req;
     377             : 
     378         327 :         req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1,
     379             :                             EAP_CODE_REQUEST, id);
     380         327 :         if (req == NULL) {
     381           0 :                 wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for"
     382             :                            " request");
     383           0 :                 eap_ttls_state(data, FAILURE);
     384           0 :                 return NULL;
     385             :         }
     386             : 
     387         327 :         wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->ttls_version);
     388             : 
     389         327 :         eap_ttls_state(data, PHASE1);
     390             : 
     391         327 :         return req;
     392             : }
     393             : 
     394             : 
     395          73 : static struct wpabuf * eap_ttls_build_phase2_eap_req(
     396             :         struct eap_sm *sm, struct eap_ttls_data *data, u8 id)
     397             : {
     398             :         struct wpabuf *buf, *encr_req;
     399             : 
     400             : 
     401          73 :         buf = data->phase2_method->buildReq(sm, data->phase2_priv, id);
     402          73 :         if (buf == NULL)
     403           5 :                 return NULL;
     404             : 
     405          68 :         wpa_hexdump_buf_key(MSG_DEBUG,
     406             :                             "EAP-TTLS/EAP: Encapsulate Phase 2 data", buf);
     407             : 
     408          68 :         buf = eap_ttls_avp_encapsulate(buf, RADIUS_ATTR_EAP_MESSAGE, 1);
     409          68 :         if (buf == NULL) {
     410           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "
     411             :                            "packet");
     412           0 :                 return NULL;
     413             :         }
     414             : 
     415          68 :         wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated "
     416             :                             "Phase 2 data", buf);
     417             : 
     418          68 :         encr_req = eap_server_tls_encrypt(sm, &data->ssl, buf);
     419          68 :         wpabuf_free(buf);
     420             : 
     421          68 :         return encr_req;
     422             : }
     423             : 
     424             : 
     425          86 : static struct wpabuf * eap_ttls_build_phase2_mschapv2(
     426             :         struct eap_sm *sm, struct eap_ttls_data *data)
     427             : {
     428             :         struct wpabuf *encr_req, msgbuf;
     429             :         u8 *req, *pos, *end;
     430             :         int ret;
     431             : 
     432          86 :         pos = req = os_malloc(100);
     433          86 :         if (req == NULL)
     434           0 :                 return NULL;
     435          86 :         end = req + 100;
     436             : 
     437          86 :         if (data->mschapv2_resp_ok) {
     438          85 :                 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS,
     439             :                                        RADIUS_VENDOR_ID_MICROSOFT, 1, 43);
     440          85 :                 *pos++ = data->mschapv2_ident;
     441          85 :                 ret = os_snprintf((char *) pos, end - pos, "S=");
     442          85 :                 if (!os_snprintf_error(end - pos, ret))
     443          85 :                         pos += ret;
     444          85 :                 pos += wpa_snprintf_hex_uppercase(
     445          85 :                         (char *) pos, end - pos, data->mschapv2_auth_response,
     446             :                         sizeof(data->mschapv2_auth_response));
     447             :         } else {
     448           1 :                 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR,
     449             :                                        RADIUS_VENDOR_ID_MICROSOFT, 1, 6);
     450           1 :                 os_memcpy(pos, "Failed", 6);
     451           1 :                 pos += 6;
     452           1 :                 AVP_PAD(req, pos);
     453             :         }
     454             : 
     455          86 :         wpabuf_set(&msgbuf, req, pos - req);
     456          86 :         wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 "
     457             :                             "data", &msgbuf);
     458             : 
     459          86 :         encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf);
     460          86 :         os_free(req);
     461             : 
     462          86 :         return encr_req;
     463             : }
     464             : 
     465             : 
     466        1095 : static struct wpabuf * eap_ttls_buildReq(struct eap_sm *sm, void *priv, u8 id)
     467             : {
     468        1095 :         struct eap_ttls_data *data = priv;
     469             : 
     470        1095 :         if (data->ssl.state == FRAG_ACK) {
     471          57 :                 return eap_server_tls_build_ack(id, EAP_TYPE_TTLS,
     472             :                                                 data->ttls_version);
     473             :         }
     474             : 
     475        1038 :         if (data->ssl.state == WAIT_FRAG_ACK) {
     476         174 :                 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,
     477             :                                                 data->ttls_version, id);
     478             :         }
     479             : 
     480         864 :         switch (data->state) {
     481             :         case START:
     482         327 :                 return eap_ttls_build_start(sm, data, id);
     483             :         case PHASE1:
     484         378 :                 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
     485         175 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, "
     486             :                                    "starting Phase2");
     487         175 :                         eap_ttls_state(data, PHASE2_START);
     488             :                 }
     489         378 :                 break;
     490             :         case PHASE2_METHOD:
     491          73 :                 wpabuf_free(data->ssl.tls_out);
     492          73 :                 data->ssl.tls_out_pos = 0;
     493          73 :                 data->ssl.tls_out = eap_ttls_build_phase2_eap_req(sm, data,
     494             :                                                                   id);
     495          73 :                 break;
     496             :         case PHASE2_MSCHAPV2_RESP:
     497          86 :                 wpabuf_free(data->ssl.tls_out);
     498          86 :                 data->ssl.tls_out_pos = 0;
     499          86 :                 data->ssl.tls_out = eap_ttls_build_phase2_mschapv2(sm, data);
     500          86 :                 break;
     501             :         default:
     502           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
     503           0 :                            __func__, data->state);
     504           0 :                 return NULL;
     505             :         }
     506             : 
     507         537 :         return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,
     508             :                                         data->ttls_version, id);
     509             : }
     510             : 
     511             : 
     512         964 : static Boolean eap_ttls_check(struct eap_sm *sm, void *priv,
     513             :                               struct wpabuf *respData)
     514             : {
     515             :         const u8 *pos;
     516             :         size_t len;
     517             : 
     518         964 :         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TTLS, respData, &len);
     519         964 :         if (pos == NULL || len < 1) {
     520           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame");
     521           0 :                 return TRUE;
     522             :         }
     523             : 
     524         964 :         return FALSE;
     525             : }
     526             : 
     527             : 
     528          36 : static void eap_ttls_process_phase2_pap(struct eap_sm *sm,
     529             :                                         struct eap_ttls_data *data,
     530             :                                         const u8 *user_password,
     531             :                                         size_t user_password_len)
     532             : {
     533          72 :         if (!sm->user || !sm->user->password || sm->user->password_hash ||
     534          36 :             !(sm->user->ttls_auth & EAP_TTLS_AUTH_PAP)) {
     535           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No plaintext user "
     536             :                            "password configured");
     537           1 :                 eap_ttls_state(data, FAILURE);
     538           1 :                 return;
     539             :         }
     540             : 
     541          69 :         if (sm->user->password_len != user_password_len ||
     542          34 :             os_memcmp_const(sm->user->password, user_password,
     543             :                             user_password_len) != 0) {
     544           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");
     545           1 :                 eap_ttls_state(data, FAILURE);
     546           1 :                 return;
     547             :         }
     548             : 
     549          34 :         wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password");
     550          34 :         eap_ttls_state(data, SUCCESS);
     551          34 :         eap_ttls_valid_session(sm, data);
     552             : }
     553             : 
     554             : 
     555           9 : static void eap_ttls_process_phase2_chap(struct eap_sm *sm,
     556             :                                          struct eap_ttls_data *data,
     557             :                                          const u8 *challenge,
     558             :                                          size_t challenge_len,
     559             :                                          const u8 *password,
     560             :                                          size_t password_len)
     561             : {
     562             :         u8 *chal, hash[CHAP_MD5_LEN];
     563             : 
     564           9 :         if (challenge == NULL || password == NULL ||
     565           9 :             challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN ||
     566             :             password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) {
     567           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes "
     568             :                            "(challenge len %lu password len %lu)",
     569             :                            (unsigned long) challenge_len,
     570             :                            (unsigned long) password_len);
     571           0 :                 eap_ttls_state(data, FAILURE);
     572           0 :                 return;
     573             :         }
     574             : 
     575          18 :         if (!sm->user || !sm->user->password || sm->user->password_hash ||
     576           9 :             !(sm->user->ttls_auth & EAP_TTLS_AUTH_CHAP)) {
     577           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No plaintext user "
     578             :                            "password configured");
     579           1 :                 eap_ttls_state(data, FAILURE);
     580           1 :                 return;
     581             :         }
     582             : 
     583           8 :         chal = eap_ttls_implicit_challenge(sm, data,
     584             :                                            EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
     585           8 :         if (chal == NULL) {
     586           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate "
     587             :                            "challenge from TLS data");
     588           0 :                 eap_ttls_state(data, FAILURE);
     589           0 :                 return;
     590             :         }
     591             : 
     592           8 :         if (os_memcmp_const(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN)
     593           8 :             != 0 ||
     594           8 :             password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) {
     595           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch");
     596           0 :                 os_free(chal);
     597           0 :                 eap_ttls_state(data, FAILURE);
     598           0 :                 return;
     599             :         }
     600           8 :         os_free(chal);
     601             : 
     602             :         /* MD5(Ident + Password + Challenge) */
     603           8 :         chap_md5(password[0], sm->user->password, sm->user->password_len,
     604             :                  challenge, challenge_len, hash);
     605             : 
     606           8 :         if (os_memcmp_const(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) ==
     607             :             0) {
     608           7 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
     609           7 :                 eap_ttls_state(data, SUCCESS);
     610           7 :                 eap_ttls_valid_session(sm, data);
     611             :         } else {
     612           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password");
     613           1 :                 eap_ttls_state(data, FAILURE);
     614             :         }
     615             : }
     616             : 
     617             : 
     618          12 : static void eap_ttls_process_phase2_mschap(struct eap_sm *sm,
     619             :                                            struct eap_ttls_data *data,
     620             :                                            u8 *challenge, size_t challenge_len,
     621             :                                            u8 *response, size_t response_len)
     622             : {
     623             :         u8 *chal, nt_response[24];
     624             : 
     625          12 :         if (challenge == NULL || response == NULL ||
     626          12 :             challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN ||
     627             :             response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) {
     628           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP "
     629             :                            "attributes (challenge len %lu response len %lu)",
     630             :                            (unsigned long) challenge_len,
     631             :                            (unsigned long) response_len);
     632           0 :                 eap_ttls_state(data, FAILURE);
     633           0 :                 return;
     634             :         }
     635             : 
     636          24 :         if (!sm->user || !sm->user->password ||
     637          12 :             !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAP)) {
     638           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password "
     639             :                            "configured");
     640           1 :                 eap_ttls_state(data, FAILURE);
     641           1 :                 return;
     642             :         }
     643             : 
     644          11 :         chal = eap_ttls_implicit_challenge(sm, data,
     645             :                                            EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
     646          11 :         if (chal == NULL) {
     647           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate "
     648             :                            "challenge from TLS data");
     649           0 :                 eap_ttls_state(data, FAILURE);
     650           0 :                 return;
     651             :         }
     652             : 
     653             : #ifdef CONFIG_TESTING_OPTIONS
     654          22 :         eap_server_mschap_rx_callback(sm, "TTLS-MSCHAP",
     655          11 :                                       sm->identity, sm->identity_len,
     656             :                                       challenge, response + 2 + 24);
     657             : #endif /* CONFIG_TESTING_OPTIONS */
     658             : 
     659          11 :         if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN)
     660          11 :             != 0 ||
     661          11 :             response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {
     662           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch");
     663           0 :                 os_free(chal);
     664           0 :                 eap_ttls_state(data, FAILURE);
     665           0 :                 return;
     666             :         }
     667          11 :         os_free(chal);
     668             : 
     669          11 :         if (sm->user->password_hash)
     670           0 :                 challenge_response(challenge, sm->user->password, nt_response);
     671             :         else
     672          11 :                 nt_challenge_response(challenge, sm->user->password,
     673          11 :                                       sm->user->password_len, nt_response);
     674             : 
     675          11 :         if (os_memcmp_const(nt_response, response + 2 + 24, 24) == 0) {
     676          10 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
     677          10 :                 eap_ttls_state(data, SUCCESS);
     678          10 :                 eap_ttls_valid_session(sm, data);
     679             :         } else {
     680           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response");
     681           1 :                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received",
     682             :                             response + 2 + 24, 24);
     683           1 :                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected",
     684             :                             nt_response, 24);
     685           1 :                 eap_ttls_state(data, FAILURE);
     686             :         }
     687             : }
     688             : 
     689             : 
     690          87 : static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
     691             :                                              struct eap_ttls_data *data,
     692             :                                              u8 *challenge,
     693             :                                              size_t challenge_len,
     694             :                                              u8 *response, size_t response_len)
     695             : {
     696             :         u8 *chal, *username, nt_response[24], *rx_resp, *peer_challenge,
     697             :                 *auth_challenge;
     698             :         size_t username_len, i;
     699             : 
     700          87 :         if (challenge == NULL || response == NULL ||
     701          87 :             challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN ||
     702             :             response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) {
     703           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 "
     704             :                            "attributes (challenge len %lu response len %lu)",
     705             :                            (unsigned long) challenge_len,
     706             :                            (unsigned long) response_len);
     707           0 :                 eap_ttls_state(data, FAILURE);
     708           0 :                 return;
     709             :         }
     710             : 
     711         174 :         if (!sm->user || !sm->user->password ||
     712          87 :             !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAPV2)) {
     713           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password "
     714             :                            "configured");
     715           1 :                 eap_ttls_state(data, FAILURE);
     716           1 :                 return;
     717             :         }
     718             : 
     719          86 :         if (sm->identity == NULL) {
     720           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user identity "
     721             :                            "known");
     722           0 :                 eap_ttls_state(data, FAILURE);
     723           0 :                 return;
     724             :         }
     725             : 
     726             :         /* MSCHAPv2 does not include optional domain name in the
     727             :          * challenge-response calculation, so remove domain prefix
     728             :          * (if present). */
     729          86 :         username = sm->identity;
     730          86 :         username_len = sm->identity_len;
     731         852 :         for (i = 0; i < username_len; i++) {
     732         782 :                 if (username[i] == '\\') {
     733          16 :                         username_len -= i + 1;
     734          16 :                         username += i + 1;
     735          16 :                         break;
     736             :                 }
     737             :         }
     738             : 
     739          86 :         chal = eap_ttls_implicit_challenge(
     740             :                 sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
     741          86 :         if (chal == NULL) {
     742           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate "
     743             :                            "challenge from TLS data");
     744           0 :                 eap_ttls_state(data, FAILURE);
     745           0 :                 return;
     746             :         }
     747             : 
     748          86 :         if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN)
     749          86 :             != 0 ||
     750          86 :             response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) {
     751           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch");
     752           0 :                 os_free(chal);
     753           0 :                 eap_ttls_state(data, FAILURE);
     754           0 :                 return;
     755             :         }
     756          86 :         os_free(chal);
     757             : 
     758          86 :         auth_challenge = challenge;
     759          86 :         peer_challenge = response + 2;
     760             : 
     761          86 :         wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User",
     762             :                           username, username_len);
     763          86 :         wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge",
     764             :                     auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
     765          86 :         wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge",
     766             :                     peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
     767             : 
     768          86 :         if (sm->user->password_hash) {
     769          17 :                 generate_nt_response_pwhash(auth_challenge, peer_challenge,
     770             :                                             username, username_len,
     771          17 :                                             sm->user->password,
     772             :                                             nt_response);
     773             :         } else {
     774         138 :                 generate_nt_response(auth_challenge, peer_challenge,
     775             :                                      username, username_len,
     776          69 :                                      sm->user->password,
     777          69 :                                      sm->user->password_len,
     778             :                                      nt_response);
     779             :         }
     780             : 
     781          86 :         rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
     782             : #ifdef CONFIG_TESTING_OPTIONS
     783             :         {
     784             :                 u8 challenge2[8];
     785             : 
     786          86 :                 if (challenge_hash(peer_challenge, auth_challenge,
     787             :                                    username, username_len, challenge2) == 0) {
     788          86 :                         eap_server_mschap_rx_callback(sm, "TTLS-MSCHAPV2",
     789             :                                                       username, username_len,
     790             :                                                       challenge2, rx_resp);
     791             :                 }
     792             :         }
     793             : #endif /* CONFIG_TESTING_OPTIONS */
     794          86 :         if (os_memcmp_const(nt_response, rx_resp, 24) == 0) {
     795          85 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
     796             :                            "NT-Response");
     797          85 :                 data->mschapv2_resp_ok = 1;
     798             : 
     799          85 :                 if (sm->user->password_hash) {
     800          16 :                         generate_authenticator_response_pwhash(
     801          16 :                                 sm->user->password,
     802             :                                 peer_challenge, auth_challenge,
     803             :                                 username, username_len, nt_response,
     804          16 :                                 data->mschapv2_auth_response);
     805             :                 } else {
     806         138 :                         generate_authenticator_response(
     807         138 :                                 sm->user->password, sm->user->password_len,
     808             :                                 peer_challenge, auth_challenge,
     809             :                                 username, username_len, nt_response,
     810          69 :                                 data->mschapv2_auth_response);
     811             :                 }
     812             :         } else {
     813           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid "
     814             :                            "NT-Response");
     815           1 :                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received",
     816             :                             rx_resp, 24);
     817           1 :                 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected",
     818             :                             nt_response, 24);
     819           1 :                 data->mschapv2_resp_ok = 0;
     820             :         }
     821          86 :         eap_ttls_state(data, PHASE2_MSCHAPV2_RESP);
     822          86 :         data->mschapv2_ident = response[0];
     823             : }
     824             : 
     825             : 
     826          73 : static int eap_ttls_phase2_eap_init(struct eap_sm *sm,
     827             :                                     struct eap_ttls_data *data,
     828             :                                     EapType eap_type)
     829             : {
     830          73 :         if (data->phase2_priv && data->phase2_method) {
     831          42 :                 data->phase2_method->reset(sm, data->phase2_priv);
     832          42 :                 data->phase2_method = NULL;
     833          42 :                 data->phase2_priv = NULL;
     834             :         }
     835          73 :         data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
     836             :                                                         eap_type);
     837          73 :         if (!data->phase2_method)
     838           0 :                 return -1;
     839             : 
     840          73 :         sm->init_phase2 = 1;
     841          73 :         data->phase2_priv = data->phase2_method->init(sm);
     842          73 :         sm->init_phase2 = 0;
     843          73 :         return data->phase2_priv == NULL ? -1 : 0;
     844             : }
     845             : 
     846             : 
     847          98 : static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm,
     848             :                                                  struct eap_ttls_data *data,
     849             :                                                  u8 *in_data, size_t in_len)
     850             : {
     851          98 :         u8 next_type = EAP_TYPE_NONE;
     852             :         struct eap_hdr *hdr;
     853             :         u8 *pos;
     854             :         size_t left;
     855             :         struct wpabuf buf;
     856          98 :         const struct eap_method *m = data->phase2_method;
     857          98 :         void *priv = data->phase2_priv;
     858             : 
     859          98 :         if (priv == NULL) {
     860           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not "
     861             :                            "initialized?!", __func__);
     862           0 :                 return;
     863             :         }
     864             : 
     865          98 :         hdr = (struct eap_hdr *) in_data;
     866          98 :         pos = (u8 *) (hdr + 1);
     867             : 
     868          98 :         if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
     869          14 :                 left = in_len - sizeof(*hdr);
     870          14 :                 wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; "
     871             :                             "allowed types", pos + 1, left - 1);
     872          14 :                 eap_sm_process_nak(sm, pos + 1, left - 1);
     873          28 :                 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
     874          14 :                     sm->user->methods[sm->user_eap_method_index].method !=
     875             :                     EAP_TYPE_NONE) {
     876          28 :                         next_type = sm->user->methods[
     877          14 :                                 sm->user_eap_method_index++].method;
     878          14 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d",
     879             :                                    next_type);
     880          26 :                         if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
     881           2 :                                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to "
     882             :                                            "initialize EAP type %d",
     883             :                                            next_type);
     884           2 :                                 eap_ttls_state(data, FAILURE);
     885           2 :                                 return;
     886             :                         }
     887             :                 } else {
     888           0 :                         eap_ttls_state(data, FAILURE);
     889             :                 }
     890          12 :                 return;
     891             :         }
     892             : 
     893          84 :         wpabuf_set(&buf, in_data, in_len);
     894             : 
     895          84 :         if (m->check(sm, priv, &buf)) {
     896           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to "
     897             :                            "ignore the packet");
     898           0 :                 return;
     899             :         }
     900             : 
     901          84 :         m->process(sm, priv, &buf);
     902             : 
     903          84 :         if (sm->method_pending == METHOD_PENDING_WAIT) {
     904           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method is in "
     905             :                            "pending wait state - save decrypted response");
     906           1 :                 wpabuf_free(data->pending_phase2_eap_resp);
     907           1 :                 data->pending_phase2_eap_resp = wpabuf_dup(&buf);
     908             :         }
     909             : 
     910          84 :         if (!m->isDone(sm, priv))
     911          33 :                 return;
     912             : 
     913          51 :         if (!m->isSuccess(sm, priv)) {
     914           6 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed");
     915           6 :                 eap_ttls_state(data, FAILURE);
     916           6 :                 return;
     917             :         }
     918             : 
     919          45 :         switch (data->state) {
     920             :         case PHASE2_START:
     921          29 :                 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
     922           2 :                         wpa_hexdump_ascii(MSG_DEBUG, "EAP_TTLS: Phase2 "
     923             :                                           "Identity not found in the user "
     924             :                                           "database",
     925           1 :                                           sm->identity, sm->identity_len);
     926           1 :                         eap_ttls_state(data, FAILURE);
     927           1 :                         break;
     928             :                 }
     929             : 
     930          28 :                 eap_ttls_state(data, PHASE2_METHOD);
     931          28 :                 next_type = sm->user->methods[0].method;
     932          28 :                 sm->user_eap_method_index = 1;
     933          28 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type);
     934          28 :                 if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
     935           1 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize "
     936             :                                    "EAP type %d", next_type);
     937           1 :                         eap_ttls_state(data, FAILURE);
     938             :                 }
     939          28 :                 break;
     940             :         case PHASE2_METHOD:
     941          16 :                 eap_ttls_state(data, SUCCESS);
     942          16 :                 eap_ttls_valid_session(sm, data);
     943          16 :                 break;
     944             :         case FAILURE:
     945           0 :                 break;
     946             :         default:
     947           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
     948           0 :                            __func__, data->state);
     949           0 :                 break;
     950             :         }
     951             : }
     952             : 
     953             : 
     954          98 : static void eap_ttls_process_phase2_eap(struct eap_sm *sm,
     955             :                                         struct eap_ttls_data *data,
     956             :                                         const u8 *eap, size_t eap_len)
     957             : {
     958             :         struct eap_hdr *hdr;
     959             :         size_t len;
     960             : 
     961          98 :         if (data->state == PHASE2_START) {
     962          29 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2");
     963          29 :                 if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_IDENTITY) < 0)
     964             :                 {
     965           0 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: failed to "
     966             :                                    "initialize EAP-Identity");
     967           0 :                         return;
     968             :                 }
     969             :         }
     970             : 
     971          98 :         if (eap_len < sizeof(*hdr)) {
     972           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: too short Phase 2 EAP "
     973             :                            "packet (len=%lu)", (unsigned long) eap_len);
     974           0 :                 return;
     975             :         }
     976             : 
     977          98 :         hdr = (struct eap_hdr *) eap;
     978          98 :         len = be_to_host16(hdr->length);
     979         196 :         wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d "
     980         196 :                    "identifier=%d length=%lu", hdr->code, hdr->identifier,
     981             :                    (unsigned long) len);
     982          98 :         if (len > eap_len) {
     983           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Length mismatch in Phase 2"
     984             :                            " EAP frame (hdr len=%lu, data len in AVP=%lu)",
     985             :                            (unsigned long) len, (unsigned long) eap_len);
     986           0 :                 return;
     987             :         }
     988             : 
     989          98 :         switch (hdr->code) {
     990             :         case EAP_CODE_RESPONSE:
     991          98 :                 eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr,
     992             :                                                      len);
     993          98 :                 break;
     994             :         default:
     995           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in "
     996           0 :                            "Phase 2 EAP header", hdr->code);
     997           0 :                 break;
     998             :         }
     999             : }
    1000             : 
    1001             : 
    1002         243 : static void eap_ttls_process_phase2(struct eap_sm *sm,
    1003             :                                     struct eap_ttls_data *data,
    1004             :                                     struct wpabuf *in_buf)
    1005             : {
    1006             :         struct wpabuf *in_decrypted;
    1007             :         struct eap_ttls_avp parse;
    1008             : 
    1009         243 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
    1010             :                    " Phase 2", (unsigned long) wpabuf_len(in_buf));
    1011             : 
    1012         243 :         if (data->pending_phase2_eap_resp) {
    1013           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 EAP response "
    1014             :                            "- skip decryption and use old data");
    1015           2 :                 eap_ttls_process_phase2_eap(
    1016           1 :                         sm, data, wpabuf_head(data->pending_phase2_eap_resp),
    1017           1 :                         wpabuf_len(data->pending_phase2_eap_resp));
    1018           1 :                 wpabuf_free(data->pending_phase2_eap_resp);
    1019           1 :                 data->pending_phase2_eap_resp = NULL;
    1020           2 :                 return;
    1021             :         }
    1022             : 
    1023         242 :         in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
    1024             :                                               in_buf);
    1025         242 :         if (in_decrypted == NULL) {
    1026           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "
    1027             :                            "data");
    1028           0 :                 eap_ttls_state(data, FAILURE);
    1029           0 :                 return;
    1030             :         }
    1031             : 
    1032         242 :         wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP",
    1033             :                             in_decrypted);
    1034             : 
    1035         242 :         if (eap_ttls_avp_parse(in_decrypted, &parse) < 0) {
    1036           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs");
    1037           0 :                 wpabuf_free(in_decrypted);
    1038           0 :                 eap_ttls_state(data, FAILURE);
    1039           0 :                 return;
    1040             :         }
    1041             : 
    1042         242 :         if (parse.user_name) {
    1043             :                 char *nbuf;
    1044         145 :                 nbuf = os_malloc(parse.user_name_len * 4 + 1);
    1045         145 :                 if (nbuf) {
    1046         290 :                         printf_encode(nbuf, parse.user_name_len * 4 + 1,
    1047         145 :                                       parse.user_name,
    1048             :                                       parse.user_name_len);
    1049         145 :                         eap_log_msg(sm, "TTLS-User-Name '%s'", nbuf);
    1050         145 :                         os_free(nbuf);
    1051             :                 }
    1052             : 
    1053         145 :                 os_free(sm->identity);
    1054         145 :                 sm->identity = os_malloc(parse.user_name_len);
    1055         145 :                 if (sm->identity == NULL) {
    1056           0 :                         eap_ttls_state(data, FAILURE);
    1057           0 :                         goto done;
    1058             :                 }
    1059         145 :                 os_memcpy(sm->identity, parse.user_name, parse.user_name_len);
    1060         145 :                 sm->identity_len = parse.user_name_len;
    1061         145 :                 if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1)
    1062             :                     != 0) {
    1063           1 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not "
    1064             :                                    "found in the user database");
    1065           1 :                         eap_ttls_state(data, FAILURE);
    1066           1 :                         goto done;
    1067             :                 }
    1068             :         }
    1069             : 
    1070             : #ifdef EAP_SERVER_TNC
    1071         241 :         if (data->tnc_started && parse.eap == NULL) {
    1072           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: TNC started but no EAP "
    1073             :                            "response from peer");
    1074           0 :                 eap_ttls_state(data, FAILURE);
    1075           0 :                 goto done;
    1076             :         }
    1077             : #endif /* EAP_SERVER_TNC */
    1078             : 
    1079         241 :         if (parse.eap) {
    1080          97 :                 eap_ttls_process_phase2_eap(sm, data, parse.eap,
    1081             :                                             parse.eap_len);
    1082         144 :         } else if (parse.user_password) {
    1083          36 :                 eap_ttls_process_phase2_pap(sm, data, parse.user_password,
    1084             :                                             parse.user_password_len);
    1085         108 :         } else if (parse.chap_password) {
    1086          27 :                 eap_ttls_process_phase2_chap(sm, data,
    1087           9 :                                              parse.chap_challenge,
    1088             :                                              parse.chap_challenge_len,
    1089           9 :                                              parse.chap_password,
    1090             :                                              parse.chap_password_len);
    1091          99 :         } else if (parse.mschap_response) {
    1092          12 :                 eap_ttls_process_phase2_mschap(sm, data,
    1093             :                                                parse.mschap_challenge,
    1094             :                                                parse.mschap_challenge_len,
    1095             :                                                parse.mschap_response,
    1096             :                                                parse.mschap_response_len);
    1097          87 :         } else if (parse.mschap2_response) {
    1098          87 :                 eap_ttls_process_phase2_mschapv2(sm, data,
    1099             :                                                  parse.mschap_challenge,
    1100             :                                                  parse.mschap_challenge_len,
    1101             :                                                  parse.mschap2_response,
    1102             :                                                  parse.mschap2_response_len);
    1103             :         }
    1104             : 
    1105             : done:
    1106         242 :         wpabuf_free(in_decrypted);
    1107         242 :         os_free(parse.eap);
    1108             : }
    1109             : 
    1110             : 
    1111         329 : static void eap_ttls_start_tnc(struct eap_sm *sm, struct eap_ttls_data *data)
    1112             : {
    1113             : #ifdef EAP_SERVER_TNC
    1114         329 :         if (!sm->tnc || data->state != SUCCESS || data->tnc_started)
    1115         327 :                 return;
    1116             : 
    1117           2 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Initialize TNC");
    1118           2 :         if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_TNC)) {
    1119           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize TNC");
    1120           0 :                 eap_ttls_state(data, FAILURE);
    1121           0 :                 return;
    1122             :         }
    1123             : 
    1124           2 :         data->tnc_started = 1;
    1125           2 :         eap_ttls_state(data, PHASE2_METHOD);
    1126             : #endif /* EAP_SERVER_TNC */
    1127             : }
    1128             : 
    1129             : 
    1130         965 : static int eap_ttls_process_version(struct eap_sm *sm, void *priv,
    1131             :                                     int peer_version)
    1132             : {
    1133         965 :         struct eap_ttls_data *data = priv;
    1134         965 :         if (peer_version < data->ttls_version) {
    1135           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; "
    1136             :                            "use version %d",
    1137             :                            peer_version, data->ttls_version, peer_version);
    1138           0 :                 data->ttls_version = peer_version;
    1139             :         }
    1140             : 
    1141         965 :         return 0;
    1142             : }
    1143             : 
    1144             : 
    1145         734 : static void eap_ttls_process_msg(struct eap_sm *sm, void *priv,
    1146             :                                  const struct wpabuf *respData)
    1147             : {
    1148         734 :         struct eap_ttls_data *data = priv;
    1149             : 
    1150         734 :         switch (data->state) {
    1151             :         case PHASE1:
    1152         405 :                 if (eap_server_tls_phase1(sm, &data->ssl) < 0)
    1153          22 :                         eap_ttls_state(data, FAILURE);
    1154         405 :                 break;
    1155             :         case PHASE2_START:
    1156             :         case PHASE2_METHOD:
    1157         243 :                 eap_ttls_process_phase2(sm, data, data->ssl.tls_in);
    1158         243 :                 eap_ttls_start_tnc(sm, data);
    1159         243 :                 break;
    1160             :         case PHASE2_MSCHAPV2_RESP:
    1161          86 :                 if (data->mschapv2_resp_ok && wpabuf_len(data->ssl.tls_in) ==
    1162             :                     0) {
    1163          85 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
    1164             :                                    "acknowledged response");
    1165          85 :                         eap_ttls_state(data, SUCCESS);
    1166          85 :                         eap_ttls_valid_session(sm, data);
    1167           1 :                 } else if (!data->mschapv2_resp_ok) {
    1168           1 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
    1169             :                                    "acknowledged error");
    1170           1 :                         eap_ttls_state(data, FAILURE);
    1171             :                 } else {
    1172           0 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected "
    1173             :                                    "frame from peer (payload len %lu, "
    1174             :                                    "expected empty frame)",
    1175             :                                    (unsigned long)
    1176           0 :                                    wpabuf_len(data->ssl.tls_in));
    1177           0 :                         eap_ttls_state(data, FAILURE);
    1178             :                 }
    1179          86 :                 eap_ttls_start_tnc(sm, data);
    1180          86 :                 break;
    1181             :         default:
    1182           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s",
    1183           0 :                            data->state, __func__);
    1184           0 :                 break;
    1185             :         }
    1186         734 : }
    1187             : 
    1188             : 
    1189         965 : static void eap_ttls_process(struct eap_sm *sm, void *priv,
    1190             :                              struct wpabuf *respData)
    1191             : {
    1192         965 :         struct eap_ttls_data *data = priv;
    1193             :         const struct wpabuf *buf;
    1194             :         const u8 *pos;
    1195             :         u8 id_len;
    1196             : 
    1197         965 :         if (eap_server_tls_process(sm, &data->ssl, respData, data,
    1198             :                                    EAP_TYPE_TTLS, eap_ttls_process_version,
    1199             :                                    eap_ttls_process_msg) < 0) {
    1200           0 :                 eap_ttls_state(data, FAILURE);
    1201           0 :                 return;
    1202             :         }
    1203             : 
    1204        1480 :         if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) ||
    1205         515 :             !tls_connection_resumed(sm->ssl_ctx, data->ssl.conn))
    1206         960 :                 return;
    1207             : 
    1208           5 :         buf = tls_connection_get_success_data(data->ssl.conn);
    1209           5 :         if (!buf || wpabuf_len(buf) < 1) {
    1210           0 :                 wpa_printf(MSG_DEBUG,
    1211             :                            "EAP-TTLS: No success data in resumed session - reject attempt");
    1212           0 :                 eap_ttls_state(data, FAILURE);
    1213           0 :                 return;
    1214             :         }
    1215             : 
    1216           5 :         pos = wpabuf_head(buf);
    1217           5 :         if (*pos != EAP_TYPE_TTLS) {
    1218           0 :                 wpa_printf(MSG_DEBUG,
    1219             :                            "EAP-TTLS: Resumed session for another EAP type (%u) - reject attempt",
    1220           0 :                            *pos);
    1221           0 :                 eap_ttls_state(data, FAILURE);
    1222           0 :                 return;
    1223             :         }
    1224             : 
    1225           5 :         pos++;
    1226           5 :         id_len = *pos++;
    1227           5 :         wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: Identity from cached session",
    1228             :                           pos, id_len);
    1229           5 :         os_free(sm->identity);
    1230           5 :         sm->identity = os_malloc(id_len ? id_len : 1);
    1231           5 :         if (!sm->identity) {
    1232           0 :                 sm->identity_len = 0;
    1233           0 :                 eap_ttls_state(data, FAILURE);
    1234           0 :                 return;
    1235             :         }
    1236             : 
    1237           5 :         os_memcpy(sm->identity, pos, id_len);
    1238           5 :         sm->identity_len = id_len;
    1239             : 
    1240           5 :         if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
    1241           0 :                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not found in the user database",
    1242           0 :                                   sm->identity, sm->identity_len);
    1243           0 :                 eap_ttls_state(data, FAILURE);
    1244           0 :                 return;
    1245             :         }
    1246             : 
    1247           5 :         wpa_printf(MSG_DEBUG,
    1248             :                    "EAP-TTLS: Resuming previous session - skip Phase2");
    1249           5 :         eap_ttls_state(data, SUCCESS);
    1250           5 :         tls_connection_set_success_data_resumed(data->ssl.conn);
    1251             : }
    1252             : 
    1253             : 
    1254        1006 : static Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv)
    1255             : {
    1256        1006 :         struct eap_ttls_data *data = priv;
    1257        1006 :         return data->state == SUCCESS || data->state == FAILURE;
    1258             : }
    1259             : 
    1260             : 
    1261         196 : static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
    1262             : {
    1263         196 :         struct eap_ttls_data *data = priv;
    1264             :         u8 *eapKeyData;
    1265             : 
    1266         196 :         if (data->state != SUCCESS)
    1267          41 :                 return NULL;
    1268             : 
    1269         155 :         eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
    1270             :                                                "ttls keying material",
    1271             :                                                EAP_TLS_KEY_LEN);
    1272         155 :         if (eapKeyData) {
    1273         155 :                 *len = EAP_TLS_KEY_LEN;
    1274         155 :                 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
    1275             :                                 eapKeyData, EAP_TLS_KEY_LEN);
    1276             :         } else {
    1277           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
    1278             :         }
    1279             : 
    1280         155 :         return eapKeyData;
    1281             : }
    1282             : 
    1283             : 
    1284         237 : static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv)
    1285             : {
    1286         237 :         struct eap_ttls_data *data = priv;
    1287         237 :         return data->state == SUCCESS;
    1288             : }
    1289             : 
    1290             : 
    1291         196 : static u8 * eap_ttls_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
    1292             : {
    1293         196 :         struct eap_ttls_data *data = priv;
    1294             : 
    1295         196 :         if (data->state != SUCCESS)
    1296          41 :                 return NULL;
    1297             : 
    1298         155 :         return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_TTLS,
    1299             :                                                 len);
    1300             : }
    1301             : 
    1302             : 
    1303           2 : static u8 * eap_ttls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
    1304             : {
    1305           2 :         struct eap_ttls_data *data = priv;
    1306             :         u8 *eapKeyData, *emsk;
    1307             : 
    1308           2 :         if (data->state != SUCCESS)
    1309           0 :                 return NULL;
    1310             : 
    1311           2 :         eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
    1312             :                                                "ttls keying material",
    1313             :                                                EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
    1314           2 :         if (eapKeyData) {
    1315           2 :                 emsk = os_malloc(EAP_EMSK_LEN);
    1316           2 :                 if (emsk)
    1317           2 :                         os_memcpy(emsk, eapKeyData + EAP_TLS_KEY_LEN,
    1318             :                                   EAP_EMSK_LEN);
    1319           2 :                 bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
    1320             :         } else
    1321           0 :                 emsk = NULL;
    1322             : 
    1323           2 :         if (emsk) {
    1324           2 :                 *len = EAP_EMSK_LEN;
    1325           2 :                 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Derived EMSK",
    1326             :                             emsk, EAP_EMSK_LEN);
    1327             :         } else {
    1328           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive EMSK");
    1329             :         }
    1330             : 
    1331           2 :         return emsk;
    1332             : }
    1333             : 
    1334             : 
    1335          25 : int eap_server_ttls_register(void)
    1336             : {
    1337             :         struct eap_method *eap;
    1338             :         int ret;
    1339             : 
    1340          25 :         eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
    1341             :                                       EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
    1342          25 :         if (eap == NULL)
    1343           0 :                 return -1;
    1344             : 
    1345          25 :         eap->init = eap_ttls_init;
    1346          25 :         eap->reset = eap_ttls_reset;
    1347          25 :         eap->buildReq = eap_ttls_buildReq;
    1348          25 :         eap->check = eap_ttls_check;
    1349          25 :         eap->process = eap_ttls_process;
    1350          25 :         eap->isDone = eap_ttls_isDone;
    1351          25 :         eap->getKey = eap_ttls_getKey;
    1352          25 :         eap->isSuccess = eap_ttls_isSuccess;
    1353          25 :         eap->getSessionId = eap_ttls_get_session_id;
    1354          25 :         eap->get_emsk = eap_ttls_get_emsk;
    1355             : 
    1356          25 :         ret = eap_server_method_register(eap);
    1357          25 :         if (ret)
    1358           0 :                 eap_server_method_free(eap);
    1359          25 :         return ret;
    1360             : }

Generated by: LCOV version 1.10