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

Generated by: LCOV version 1.10