LCOV - code coverage report
Current view: top level - src/eap_peer - eap_ttls.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1475438200 Lines: 767 851 90.1 %
Date: 2016-10-02 Functions: 42 42 100.0 %

          Line data    Source code
       1             : /*
       2             :  * EAP peer method: EAP-TTLS (RFC 5281)
       3             :  * Copyright (c) 2004-2015, 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_common/chap.h"
      16             : #include "eap_common/eap_ttls.h"
      17             : #include "mschapv2.h"
      18             : #include "eap_i.h"
      19             : #include "eap_tls_common.h"
      20             : #include "eap_config.h"
      21             : 
      22             : 
      23             : #define EAP_TTLS_VERSION 0
      24             : 
      25             : 
      26             : static void eap_ttls_deinit(struct eap_sm *sm, void *priv);
      27             : 
      28             : 
      29             : struct eap_ttls_data {
      30             :         struct eap_ssl_data ssl;
      31             : 
      32             :         int ttls_version;
      33             : 
      34             :         const struct eap_method *phase2_method;
      35             :         void *phase2_priv;
      36             :         int phase2_success;
      37             :         int phase2_start;
      38             :         EapDecision decision_succ;
      39             : 
      40             :         enum phase2_types {
      41             :                 EAP_TTLS_PHASE2_EAP,
      42             :                 EAP_TTLS_PHASE2_MSCHAPV2,
      43             :                 EAP_TTLS_PHASE2_MSCHAP,
      44             :                 EAP_TTLS_PHASE2_PAP,
      45             :                 EAP_TTLS_PHASE2_CHAP
      46             :         } phase2_type;
      47             :         struct eap_method_type phase2_eap_type;
      48             :         struct eap_method_type *phase2_eap_types;
      49             :         size_t num_phase2_eap_types;
      50             : 
      51             :         u8 auth_response[MSCHAPV2_AUTH_RESPONSE_LEN];
      52             :         int auth_response_valid;
      53             :         u8 master_key[MSCHAPV2_MASTER_KEY_LEN]; /* MSCHAPv2 master key */
      54             :         u8 ident;
      55             :         int resuming; /* starting a resumed session */
      56             :         int reauth; /* reauthentication */
      57             :         u8 *key_data;
      58             :         u8 *session_id;
      59             :         size_t id_len;
      60             : 
      61             :         struct wpabuf *pending_phase2_req;
      62             :         struct wpabuf *pending_resp;
      63             : 
      64             : #ifdef EAP_TNC
      65             :         int ready_for_tnc;
      66             :         int tnc_started;
      67             : #endif /* EAP_TNC */
      68             : };
      69             : 
      70             : 
      71         300 : static void * eap_ttls_init(struct eap_sm *sm)
      72             : {
      73             :         struct eap_ttls_data *data;
      74         300 :         struct eap_peer_config *config = eap_get_config(sm);
      75             :         int selected_non_eap;
      76             :         char *selected;
      77             : 
      78         300 :         data = os_zalloc(sizeof(*data));
      79         300 :         if (data == NULL)
      80           1 :                 return NULL;
      81         299 :         data->ttls_version = EAP_TTLS_VERSION;
      82         299 :         selected = "EAP";
      83         299 :         selected_non_eap = 0;
      84         299 :         data->phase2_type = EAP_TTLS_PHASE2_EAP;
      85             : 
      86             :         /*
      87             :          * Either one auth= type or one or more autheap= methods can be
      88             :          * specified.
      89             :          */
      90         299 :         if (config && config->phase2) {
      91         293 :                 const char *token, *last = NULL;
      92             : 
      93         882 :                 while ((token = cstr_token(config->phase2, " \t", &last))) {
      94         298 :                         if (os_strncmp(token, "auth=", 5) != 0)
      95          48 :                                 continue;
      96         250 :                         token += 5;
      97             : 
      98         385 :                         if (last - token == 8 &&
      99         135 :                             os_strncmp(token, "MSCHAPV2", 8) == 0) {
     100         134 :                                 selected = "MSCHAPV2";
     101         134 :                                 data->phase2_type = EAP_TTLS_PHASE2_MSCHAPV2;
     102         136 :                         } else if (last - token == 6 &&
     103          20 :                                    os_strncmp(token, "MSCHAP", 6) == 0) {
     104          20 :                                 selected = "MSCHAP";
     105          20 :                                 data->phase2_type = EAP_TTLS_PHASE2_MSCHAP;
     106         180 :                         } else if (last - token == 3 &&
     107          84 :                                    os_strncmp(token, "PAP", 3) == 0) {
     108          84 :                                 selected = "PAP";
     109          84 :                                 data->phase2_type = EAP_TTLS_PHASE2_PAP;
     110          23 :                         } else if (last - token == 4 &&
     111          11 :                                    os_strncmp(token, "CHAP", 4) == 0) {
     112          11 :                                 selected = "CHAP";
     113          11 :                                 data->phase2_type = EAP_TTLS_PHASE2_CHAP;
     114             :                         } else {
     115           1 :                                 wpa_printf(MSG_ERROR,
     116             :                                            "EAP-TTLS: Unsupported Phase2 type '%s'",
     117             :                                            token);
     118           1 :                                 eap_ttls_deinit(sm, data);
     119           5 :                                 return NULL;
     120             :                         }
     121             : 
     122         249 :                         if (selected_non_eap) {
     123           1 :                                 wpa_printf(MSG_ERROR,
     124             :                                            "EAP-TTLS: Only one Phase2 type can be specified");
     125           1 :                                 eap_ttls_deinit(sm, data);
     126           1 :                                 return NULL;
     127             :                         }
     128             : 
     129         248 :                         selected_non_eap = 1;
     130             :                 }
     131             : 
     132         291 :                 if (os_strstr(config->phase2, "autheap=")) {
     133          46 :                         if (selected_non_eap) {
     134           2 :                                 wpa_printf(MSG_ERROR,
     135             :                                            "EAP-TTLS: Both auth= and autheap= params cannot be specified");
     136           2 :                                 eap_ttls_deinit(sm, data);
     137           2 :                                 return NULL;
     138             :                         }
     139          44 :                         selected = "EAP";
     140          44 :                         data->phase2_type = EAP_TTLS_PHASE2_EAP;
     141             :                 }
     142             :         }
     143             : 
     144         295 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 type: %s", selected);
     145             : 
     146         295 :         if (data->phase2_type == EAP_TTLS_PHASE2_EAP) {
     147          50 :                 if (eap_peer_select_phase2_methods(config, "autheap=",
     148             :                                                    &data->phase2_eap_types,
     149             :                                                    &data->num_phase2_eap_types)
     150             :                     < 0) {
     151           3 :                         eap_ttls_deinit(sm, data);
     152           3 :                         return NULL;
     153             :                 }
     154             : 
     155          47 :                 data->phase2_eap_type.vendor = EAP_VENDOR_IETF;
     156          47 :                 data->phase2_eap_type.method = EAP_TYPE_NONE;
     157             :         }
     158             : 
     159         292 :         if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TTLS)) {
     160           5 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
     161           5 :                 eap_ttls_deinit(sm, data);
     162           5 :                 return NULL;
     163             :         }
     164             : 
     165         287 :         return data;
     166             : }
     167             : 
     168             : 
     169         299 : static void eap_ttls_phase2_eap_deinit(struct eap_sm *sm,
     170             :                                        struct eap_ttls_data *data)
     171             : {
     172         299 :         if (data->phase2_priv && data->phase2_method) {
     173          39 :                 data->phase2_method->deinit(sm, data->phase2_priv);
     174          39 :                 data->phase2_method = NULL;
     175          39 :                 data->phase2_priv = NULL;
     176             :         }
     177         299 : }
     178             : 
     179             : 
     180         600 : static void eap_ttls_free_key(struct eap_ttls_data *data)
     181             : {
     182         600 :         if (data->key_data) {
     183         277 :                 bin_clear_free(data->key_data, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
     184         277 :                 data->key_data = NULL;
     185             :         }
     186         600 : }
     187             : 
     188             : 
     189         299 : static void eap_ttls_deinit(struct eap_sm *sm, void *priv)
     190             : {
     191         299 :         struct eap_ttls_data *data = priv;
     192         299 :         if (data == NULL)
     193         299 :                 return;
     194         299 :         eap_ttls_phase2_eap_deinit(sm, data);
     195         299 :         os_free(data->phase2_eap_types);
     196         299 :         eap_peer_tls_ssl_deinit(sm, &data->ssl);
     197         299 :         eap_ttls_free_key(data);
     198         299 :         os_free(data->session_id);
     199         299 :         wpabuf_free(data->pending_phase2_req);
     200         299 :         wpabuf_free(data->pending_resp);
     201         299 :         os_free(data);
     202             : }
     203             : 
     204             : 
     205         785 : static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
     206             :                              int mandatory, size_t len)
     207             : {
     208             :         struct ttls_avp_vendor *avp;
     209             :         u8 flags;
     210             :         size_t hdrlen;
     211             : 
     212         785 :         avp = (struct ttls_avp_vendor *) avphdr;
     213         785 :         flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
     214         785 :         if (vendor_id) {
     215         270 :                 flags |= AVP_FLAGS_VENDOR;
     216         270 :                 hdrlen = sizeof(*avp);
     217         270 :                 avp->vendor_id = host_to_be32(vendor_id);
     218             :         } else {
     219         515 :                 hdrlen = sizeof(struct ttls_avp);
     220             :         }
     221             : 
     222         785 :         avp->avp_code = host_to_be32(avp_code);
     223         785 :         avp->avp_length = host_to_be32(((u32) flags << 24) |
     224             :                                        (u32) (hdrlen + len));
     225             : 
     226         785 :         return avphdr + hdrlen;
     227             : }
     228             : 
     229             : 
     230         371 : static u8 * eap_ttls_avp_add(u8 *start, u8 *avphdr, u32 avp_code,
     231             :                              u32 vendor_id, int mandatory,
     232             :                              const u8 *data, size_t len)
     233             : {
     234             :         u8 *pos;
     235         371 :         pos = eap_ttls_avp_hdr(avphdr, avp_code, vendor_id, mandatory, len);
     236         371 :         os_memcpy(pos, data, len);
     237         371 :         pos += len;
     238         371 :         AVP_PAD(start, pos);
     239         371 :         return pos;
     240             : }
     241             : 
     242             : 
     243         193 : static int eap_ttls_avp_encapsulate(struct wpabuf **resp, u32 avp_code,
     244             :                                     int mandatory)
     245             : {
     246             :         struct wpabuf *msg;
     247             :         u8 *avp, *pos;
     248             : 
     249         193 :         msg = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(*resp) + 4);
     250         193 :         if (msg == NULL) {
     251           2 :                 wpabuf_free(*resp);
     252           2 :                 *resp = NULL;
     253           2 :                 return -1;
     254             :         }
     255             : 
     256         191 :         avp = wpabuf_mhead(msg);
     257         191 :         pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, wpabuf_len(*resp));
     258         191 :         os_memcpy(pos, wpabuf_head(*resp), wpabuf_len(*resp));
     259         191 :         pos += wpabuf_len(*resp);
     260         191 :         AVP_PAD(avp, pos);
     261         191 :         wpabuf_free(*resp);
     262         191 :         wpabuf_put(msg, pos - avp);
     263         191 :         *resp = msg;
     264         191 :         return 0;
     265             : }
     266             : 
     267             : 
     268         278 : static int eap_ttls_v0_derive_key(struct eap_sm *sm,
     269             :                                   struct eap_ttls_data *data)
     270             : {
     271         278 :         eap_ttls_free_key(data);
     272         278 :         data->key_data = eap_peer_tls_derive_key(sm, &data->ssl,
     273             :                                                  "ttls keying material",
     274             :                                                  EAP_TLS_KEY_LEN +
     275             :                                                  EAP_EMSK_LEN);
     276         278 :         if (!data->key_data) {
     277           1 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to derive key");
     278           1 :                 return -1;
     279             :         }
     280             : 
     281         277 :         wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
     282         277 :                         data->key_data, EAP_TLS_KEY_LEN);
     283         277 :         wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived EMSK",
     284         277 :                         data->key_data + EAP_TLS_KEY_LEN,
     285             :                         EAP_EMSK_LEN);
     286             : 
     287         277 :         os_free(data->session_id);
     288         277 :         data->session_id = eap_peer_tls_derive_session_id(sm, &data->ssl,
     289             :                                                           EAP_TYPE_TTLS,
     290             :                                                           &data->id_len);
     291         277 :         if (data->session_id) {
     292         552 :                 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Derived Session-Id",
     293         276 :                             data->session_id, data->id_len);
     294             :         } else {
     295           1 :                 wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to derive Session-Id");
     296             :         }
     297             : 
     298         277 :         return 0;
     299             : }
     300             : 
     301             : 
     302             : #ifndef CONFIG_FIPS
     303         148 : static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
     304             :                                         struct eap_ttls_data *data, size_t len)
     305             : {
     306         148 :         return eap_peer_tls_derive_key(sm, &data->ssl, "ttls challenge", len);
     307             : }
     308             : #endif /* CONFIG_FIPS */
     309             : 
     310             : 
     311          42 : static void eap_ttls_phase2_select_eap_method(struct eap_ttls_data *data,
     312             :                                               u8 method)
     313             : {
     314             :         size_t i;
     315         118 :         for (i = 0; i < data->num_phase2_eap_types; i++) {
     316          86 :                 if (data->phase2_eap_types[i].vendor != EAP_VENDOR_IETF ||
     317          43 :                     data->phase2_eap_types[i].method != method)
     318          17 :                         continue;
     319             : 
     320          26 :                 data->phase2_eap_type.vendor =
     321          26 :                         data->phase2_eap_types[i].vendor;
     322          26 :                 data->phase2_eap_type.method =
     323          26 :                         data->phase2_eap_types[i].method;
     324          26 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected "
     325             :                            "Phase 2 EAP vendor %d method %d",
     326             :                            data->phase2_eap_type.vendor,
     327             :                            data->phase2_eap_type.method);
     328          26 :                 break;
     329             :         }
     330          42 : }
     331             : 
     332             : 
     333         146 : static int eap_ttls_phase2_eap_process(struct eap_sm *sm,
     334             :                                        struct eap_ttls_data *data,
     335             :                                        struct eap_method_ret *ret,
     336             :                                        struct eap_hdr *hdr, size_t len,
     337             :                                        struct wpabuf **resp)
     338             : {
     339             :         struct wpabuf msg;
     340             :         struct eap_method_ret iret;
     341             : 
     342         146 :         os_memset(&iret, 0, sizeof(iret));
     343         146 :         wpabuf_set(&msg, hdr, len);
     344         146 :         *resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
     345             :                                              &msg);
     346         270 :         if ((iret.methodState == METHOD_DONE ||
     347         207 :              iret.methodState == METHOD_MAY_CONT) &&
     348         150 :             (iret.decision == DECISION_UNCOND_SUCC ||
     349         121 :              iret.decision == DECISION_COND_SUCC ||
     350          54 :              iret.decision == DECISION_FAIL)) {
     351          83 :                 ret->methodState = iret.methodState;
     352          83 :                 ret->decision = iret.decision;
     353             :         }
     354             : 
     355         146 :         return 0;
     356             : }
     357             : 
     358             : 
     359         175 : static int eap_ttls_phase2_request_eap_method(struct eap_sm *sm,
     360             :                                               struct eap_ttls_data *data,
     361             :                                               struct eap_method_ret *ret,
     362             :                                               struct eap_hdr *hdr, size_t len,
     363             :                                               u8 method, struct wpabuf **resp)
     364             : {
     365             : #ifdef EAP_TNC
     366         266 :         if (data->tnc_started && data->phase2_method &&
     367         273 :             data->phase2_priv && method == EAP_TYPE_TNC &&
     368          91 :             data->phase2_eap_type.method == EAP_TYPE_TNC)
     369          91 :                 return eap_ttls_phase2_eap_process(sm, data, ret, hdr, len,
     370             :                                                    resp);
     371             : 
     372          84 :         if (data->ready_for_tnc && !data->tnc_started &&
     373             :             method == EAP_TYPE_TNC) {
     374           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start TNC after completed "
     375             :                            "EAP method");
     376           0 :                 data->tnc_started = 1;
     377             :         }
     378             : 
     379          84 :         if (data->tnc_started) {
     380          48 :                 if (data->phase2_eap_type.vendor != EAP_VENDOR_IETF ||
     381          24 :                     data->phase2_eap_type.method == EAP_TYPE_TNC) {
     382           0 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected EAP "
     383             :                                    "type %d for TNC", method);
     384           0 :                         return -1;
     385             :                 }
     386             : 
     387          24 :                 data->phase2_eap_type.vendor = EAP_VENDOR_IETF;
     388          24 :                 data->phase2_eap_type.method = method;
     389          24 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected "
     390             :                            "Phase 2 EAP vendor %d method %d (TNC)",
     391             :                            data->phase2_eap_type.vendor,
     392             :                            data->phase2_eap_type.method);
     393             : 
     394          24 :                 if (data->phase2_type == EAP_TTLS_PHASE2_EAP)
     395           0 :                         eap_ttls_phase2_eap_deinit(sm, data);
     396             :         }
     397             : #endif /* EAP_TNC */
     398             : 
     399         168 :         if (data->phase2_eap_type.vendor == EAP_VENDOR_IETF &&
     400          84 :             data->phase2_eap_type.method == EAP_TYPE_NONE)
     401          42 :                 eap_ttls_phase2_select_eap_method(data, method);
     402             : 
     403          84 :         if (method != data->phase2_eap_type.method || method == EAP_TYPE_NONE)
     404             :         {
     405          18 :                 if (eap_peer_tls_phase2_nak(data->phase2_eap_types,
     406             :                                             data->num_phase2_eap_types,
     407             :                                             hdr, resp))
     408           1 :                         return -1;
     409          17 :                 return 0;
     410             :         }
     411             : 
     412          66 :         if (data->phase2_priv == NULL) {
     413          50 :                 data->phase2_method = eap_peer_get_eap_method(
     414             :                         EAP_VENDOR_IETF, method);
     415          50 :                 if (data->phase2_method) {
     416          50 :                         sm->init_phase2 = 1;
     417          50 :                         data->phase2_priv = data->phase2_method->init(sm);
     418          50 :                         sm->init_phase2 = 0;
     419             :                 }
     420             :         }
     421          66 :         if (data->phase2_priv == NULL || data->phase2_method == NULL) {
     422          11 :                 wpa_printf(MSG_INFO, "EAP-TTLS: failed to initialize "
     423             :                            "Phase 2 EAP method %d", method);
     424          11 :                 return -1;
     425             :         }
     426             : 
     427          55 :         return eap_ttls_phase2_eap_process(sm, data, ret, hdr, len, resp);
     428             : }
     429             : 
     430             : 
     431         217 : static int eap_ttls_phase2_request_eap(struct eap_sm *sm,
     432             :                                        struct eap_ttls_data *data,
     433             :                                        struct eap_method_ret *ret,
     434             :                                        struct eap_hdr *hdr,
     435             :                                        struct wpabuf **resp)
     436             : {
     437         217 :         size_t len = be_to_host16(hdr->length);
     438             :         u8 *pos;
     439         217 :         struct eap_peer_config *config = eap_get_config(sm);
     440             : 
     441         217 :         if (len <= sizeof(struct eap_hdr)) {
     442           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: too short "
     443             :                            "Phase 2 request (len=%lu)", (unsigned long) len);
     444           0 :                 return -1;
     445             :         }
     446         217 :         pos = (u8 *) (hdr + 1);
     447         217 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP Request: type=%d", *pos);
     448         217 :         switch (*pos) {
     449             :         case EAP_TYPE_IDENTITY:
     450          42 :                 *resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
     451          42 :                 break;
     452             :         default:
     453         175 :                 if (eap_ttls_phase2_request_eap_method(sm, data, ret, hdr, len,
     454         175 :                                                        *pos, resp) < 0)
     455          12 :                         return -1;
     456         163 :                 break;
     457             :         }
     458             : 
     459         217 :         if (*resp == NULL &&
     460          34 :             (config->pending_req_identity || config->pending_req_password ||
     461          10 :              config->pending_req_otp)) {
     462           2 :                 return 0;
     463             :         }
     464             : 
     465         203 :         if (*resp == NULL)
     466          10 :                 return -1;
     467             : 
     468         193 :         wpa_hexdump_buf(MSG_DEBUG, "EAP-TTLS: AVP encapsulate EAP Response",
     469             :                         *resp);
     470         193 :         return eap_ttls_avp_encapsulate(resp, RADIUS_ATTR_EAP_MESSAGE, 1);
     471             : }
     472             : 
     473             : 
     474         121 : static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
     475             :                                             struct eap_ttls_data *data,
     476             :                                             struct eap_method_ret *ret,
     477             :                                             struct wpabuf **resp)
     478             : {
     479             : #ifdef CONFIG_FIPS
     480             :         wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPV2 not supported in FIPS build");
     481             :         return -1;
     482             : #else /* CONFIG_FIPS */
     483             : #ifdef EAP_MSCHAPv2
     484             :         struct wpabuf *msg;
     485             :         u8 *buf, *pos, *challenge, *peer_challenge;
     486             :         const u8 *identity, *password;
     487             :         size_t identity_len, password_len;
     488             :         int pwhash;
     489             : 
     490         121 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAPV2 Request");
     491             : 
     492         121 :         identity = eap_get_config_identity(sm, &identity_len);
     493         121 :         password = eap_get_config_password2(sm, &password_len, &pwhash);
     494         121 :         if (identity == NULL || password == NULL)
     495           0 :                 return -1;
     496             : 
     497         121 :         msg = wpabuf_alloc(identity_len + 1000);
     498         121 :         if (msg == NULL) {
     499           1 :                 wpa_printf(MSG_ERROR,
     500             :                            "EAP-TTLS/MSCHAPV2: Failed to allocate memory");
     501           1 :                 return -1;
     502             :         }
     503         120 :         pos = buf = wpabuf_mhead(msg);
     504             : 
     505             :         /* User-Name */
     506         120 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
     507             :                                identity, identity_len);
     508             : 
     509             :         /* MS-CHAP-Challenge */
     510         120 :         challenge = eap_ttls_implicit_challenge(
     511             :                 sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
     512         120 :         if (challenge == NULL) {
     513           1 :                 wpabuf_free(msg);
     514           1 :                 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
     515             :                            "implicit challenge");
     516           1 :                 return -1;
     517             :         }
     518             : 
     519         119 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
     520             :                                RADIUS_VENDOR_ID_MICROSOFT, 1,
     521             :                                challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
     522             : 
     523             :         /* MS-CHAP2-Response */
     524         119 :         pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_RESPONSE,
     525             :                                RADIUS_VENDOR_ID_MICROSOFT, 1,
     526             :                                EAP_TTLS_MSCHAPV2_RESPONSE_LEN);
     527         119 :         data->ident = challenge[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN];
     528         119 :         *pos++ = data->ident;
     529         119 :         *pos++ = 0; /* Flags */
     530         119 :         if (os_get_random(pos, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) < 0) {
     531           1 :                 os_free(challenge);
     532           1 :                 wpabuf_free(msg);
     533           1 :                 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to get "
     534             :                            "random data for peer challenge");
     535           1 :                 return -1;
     536             :         }
     537         118 :         peer_challenge = pos;
     538         118 :         pos += EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
     539         118 :         os_memset(pos, 0, 8); /* Reserved, must be zero */
     540         118 :         pos += 8;
     541         118 :         if (mschapv2_derive_response(identity, identity_len, password,
     542             :                                      password_len, pwhash, challenge,
     543         118 :                                      peer_challenge, pos, data->auth_response,
     544         118 :                                      data->master_key)) {
     545           4 :                 os_free(challenge);
     546           4 :                 wpabuf_free(msg);
     547           4 :                 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
     548             :                            "response");
     549           4 :                 return -1;
     550             :         }
     551         114 :         data->auth_response_valid = 1;
     552             : 
     553         114 :         pos += 24;
     554         114 :         os_free(challenge);
     555         114 :         AVP_PAD(buf, pos);
     556             : 
     557         114 :         wpabuf_put(msg, pos - buf);
     558         114 :         *resp = msg;
     559             : 
     560         114 :         return 0;
     561             : #else /* EAP_MSCHAPv2 */
     562             :         wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPv2 not included in the build");
     563             :         return -1;
     564             : #endif /* EAP_MSCHAPv2 */
     565             : #endif /* CONFIG_FIPS */
     566             : }
     567             : 
     568             : 
     569          18 : static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
     570             :                                           struct eap_ttls_data *data,
     571             :                                           struct eap_method_ret *ret,
     572             :                                           struct wpabuf **resp)
     573             : {
     574             : #ifdef CONFIG_FIPS
     575             :         wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAP not supported in FIPS build");
     576             :         return -1;
     577             : #else /* CONFIG_FIPS */
     578             :         struct wpabuf *msg;
     579             :         u8 *buf, *pos, *challenge;
     580             :         const u8 *identity, *password;
     581             :         size_t identity_len, password_len;
     582             :         int pwhash;
     583             : 
     584          18 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAP Request");
     585             : 
     586          18 :         identity = eap_get_config_identity(sm, &identity_len);
     587          18 :         password = eap_get_config_password2(sm, &password_len, &pwhash);
     588          18 :         if (identity == NULL || password == NULL)
     589           0 :                 return -1;
     590             : 
     591          18 :         msg = wpabuf_alloc(identity_len + 1000);
     592          18 :         if (msg == NULL) {
     593           1 :                 wpa_printf(MSG_ERROR,
     594             :                            "EAP-TTLS/MSCHAP: Failed to allocate memory");
     595           1 :                 return -1;
     596             :         }
     597          17 :         pos = buf = wpabuf_mhead(msg);
     598             : 
     599             :         /* User-Name */
     600          17 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
     601             :                                identity, identity_len);
     602             : 
     603             :         /* MS-CHAP-Challenge */
     604          17 :         challenge = eap_ttls_implicit_challenge(
     605             :                 sm, data, EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
     606          17 :         if (challenge == NULL) {
     607           1 :                 wpabuf_free(msg);
     608           1 :                 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive "
     609             :                            "implicit challenge");
     610           1 :                 return -1;
     611             :         }
     612             : 
     613          16 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
     614             :                                RADIUS_VENDOR_ID_MICROSOFT, 1,
     615             :                                challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);
     616             : 
     617             :         /* MS-CHAP-Response */
     618          16 :         pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_RESPONSE,
     619             :                                RADIUS_VENDOR_ID_MICROSOFT, 1,
     620             :                                EAP_TTLS_MSCHAP_RESPONSE_LEN);
     621          16 :         data->ident = challenge[EAP_TTLS_MSCHAP_CHALLENGE_LEN];
     622          16 :         *pos++ = data->ident;
     623          16 :         *pos++ = 1; /* Flags: Use NT style passwords */
     624          16 :         os_memset(pos, 0, 24); /* LM-Response */
     625          16 :         pos += 24;
     626          16 :         if (pwhash) {
     627           1 :                 challenge_response(challenge, password, pos); /* NT-Response */
     628           1 :                 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password hash",
     629             :                                 password, 16);
     630             :         } else {
     631          15 :                 nt_challenge_response(challenge, password, password_len,
     632             :                                       pos); /* NT-Response */
     633          15 :                 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password",
     634             :                                       password, password_len);
     635             :         }
     636          16 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP implicit challenge",
     637             :                     challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);
     638          16 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP response", pos, 24);
     639          16 :         pos += 24;
     640          16 :         os_free(challenge);
     641          16 :         AVP_PAD(buf, pos);
     642             : 
     643          16 :         wpabuf_put(msg, pos - buf);
     644          16 :         *resp = msg;
     645             : 
     646             :         /* EAP-TTLS/MSCHAP does not provide tunneled success
     647             :          * notification, so assume that Phase2 succeeds. */
     648          16 :         ret->methodState = METHOD_DONE;
     649          16 :         ret->decision = DECISION_COND_SUCC;
     650             : 
     651          16 :         return 0;
     652             : #endif /* CONFIG_FIPS */
     653             : }
     654             : 
     655             : 
     656          79 : static int eap_ttls_phase2_request_pap(struct eap_sm *sm,
     657             :                                        struct eap_ttls_data *data,
     658             :                                        struct eap_method_ret *ret,
     659             :                                        struct wpabuf **resp)
     660             : {
     661             :         struct wpabuf *msg;
     662             :         u8 *buf, *pos;
     663             :         size_t pad;
     664             :         const u8 *identity, *password;
     665             :         size_t identity_len, password_len;
     666             : 
     667          79 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 PAP Request");
     668             : 
     669          79 :         identity = eap_get_config_identity(sm, &identity_len);
     670          79 :         password = eap_get_config_password(sm, &password_len);
     671          79 :         if (identity == NULL || password == NULL)
     672           0 :                 return -1;
     673             : 
     674          79 :         msg = wpabuf_alloc(identity_len + password_len + 100);
     675          79 :         if (msg == NULL) {
     676           1 :                 wpa_printf(MSG_ERROR,
     677             :                            "EAP-TTLS/PAP: Failed to allocate memory");
     678           1 :                 return -1;
     679             :         }
     680          78 :         pos = buf = wpabuf_mhead(msg);
     681             : 
     682             :         /* User-Name */
     683          78 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
     684             :                                identity, identity_len);
     685             : 
     686             :         /* User-Password; in RADIUS, this is encrypted, but EAP-TTLS encrypts
     687             :          * the data, so no separate encryption is used in the AVP itself.
     688             :          * However, the password is padded to obfuscate its length. */
     689          78 :         pad = password_len == 0 ? 16 : (16 - (password_len & 15)) & 15;
     690          78 :         pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_USER_PASSWORD, 0, 1,
     691             :                                password_len + pad);
     692          78 :         os_memcpy(pos, password, password_len);
     693          78 :         pos += password_len;
     694          78 :         os_memset(pos, 0, pad);
     695          78 :         pos += pad;
     696          78 :         AVP_PAD(buf, pos);
     697             : 
     698          78 :         wpabuf_put(msg, pos - buf);
     699          78 :         *resp = msg;
     700             : 
     701             :         /* EAP-TTLS/PAP does not provide tunneled success notification,
     702             :          * so assume that Phase2 succeeds. */
     703          78 :         ret->methodState = METHOD_DONE;
     704          78 :         ret->decision = DECISION_COND_SUCC;
     705             : 
     706          78 :         return 0;
     707             : }
     708             : 
     709             : 
     710          12 : static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
     711             :                                         struct eap_ttls_data *data,
     712             :                                         struct eap_method_ret *ret,
     713             :                                         struct wpabuf **resp)
     714             : {
     715             : #ifdef CONFIG_FIPS
     716             :         wpa_printf(MSG_ERROR, "EAP-TTLS: CHAP not supported in FIPS build");
     717             :         return -1;
     718             : #else /* CONFIG_FIPS */
     719             :         struct wpabuf *msg;
     720             :         u8 *buf, *pos, *challenge;
     721             :         const u8 *identity, *password;
     722             :         size_t identity_len, password_len;
     723             : 
     724          12 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 CHAP Request");
     725             : 
     726          12 :         identity = eap_get_config_identity(sm, &identity_len);
     727          12 :         password = eap_get_config_password(sm, &password_len);
     728          12 :         if (identity == NULL || password == NULL)
     729           0 :                 return -1;
     730             : 
     731          12 :         msg = wpabuf_alloc(identity_len + 1000);
     732          12 :         if (msg == NULL) {
     733           1 :                 wpa_printf(MSG_ERROR,
     734             :                            "EAP-TTLS/CHAP: Failed to allocate memory");
     735           1 :                 return -1;
     736             :         }
     737          11 :         pos = buf = wpabuf_mhead(msg);
     738             : 
     739             :         /* User-Name */
     740          11 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
     741             :                                identity, identity_len);
     742             : 
     743             :         /* CHAP-Challenge */
     744          11 :         challenge = eap_ttls_implicit_challenge(
     745             :                 sm, data, EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
     746          11 :         if (challenge == NULL) {
     747           1 :                 wpabuf_free(msg);
     748           1 :                 wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive "
     749             :                            "implicit challenge");
     750           1 :                 return -1;
     751             :         }
     752             : 
     753          10 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_CHAP_CHALLENGE, 0, 1,
     754             :                                challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);
     755             : 
     756             :         /* CHAP-Password */
     757          10 :         pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_CHAP_PASSWORD, 0, 1,
     758             :                                1 + EAP_TTLS_CHAP_PASSWORD_LEN);
     759          10 :         data->ident = challenge[EAP_TTLS_CHAP_CHALLENGE_LEN];
     760          10 :         *pos++ = data->ident;
     761             : 
     762             :         /* MD5(Ident + Password + Challenge) */
     763          10 :         chap_md5(data->ident, password, password_len, challenge,
     764             :                  EAP_TTLS_CHAP_CHALLENGE_LEN, pos);
     765             : 
     766          10 :         wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: CHAP username",
     767             :                           identity, identity_len);
     768          10 :         wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: CHAP password",
     769             :                               password, password_len);
     770          10 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP implicit challenge",
     771             :                     challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);
     772          10 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP password",
     773             :                     pos, EAP_TTLS_CHAP_PASSWORD_LEN);
     774          10 :         pos += EAP_TTLS_CHAP_PASSWORD_LEN;
     775          10 :         os_free(challenge);
     776          10 :         AVP_PAD(buf, pos);
     777             : 
     778          10 :         wpabuf_put(msg, pos - buf);
     779          10 :         *resp = msg;
     780             : 
     781             :         /* EAP-TTLS/CHAP does not provide tunneled success
     782             :          * notification, so assume that Phase2 succeeds. */
     783          10 :         ret->methodState = METHOD_DONE;
     784          10 :         ret->decision = DECISION_COND_SUCC;
     785             : 
     786          10 :         return 0;
     787             : #endif /* CONFIG_FIPS */
     788             : }
     789             : 
     790             : 
     791         452 : static int eap_ttls_phase2_request(struct eap_sm *sm,
     792             :                                    struct eap_ttls_data *data,
     793             :                                    struct eap_method_ret *ret,
     794             :                                    struct eap_hdr *hdr,
     795             :                                    struct wpabuf **resp)
     796             : {
     797         452 :         int res = 0;
     798             :         size_t len;
     799         452 :         enum phase2_types phase2_type = data->phase2_type;
     800             : 
     801             : #ifdef EAP_TNC
     802         452 :         if (data->tnc_started) {
     803         115 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Processing TNC");
     804         115 :                 phase2_type = EAP_TTLS_PHASE2_EAP;
     805             :         }
     806             : #endif /* EAP_TNC */
     807             : 
     808         452 :         if (phase2_type == EAP_TTLS_PHASE2_MSCHAPV2 ||
     809         309 :             phase2_type == EAP_TTLS_PHASE2_MSCHAP ||
     810         229 :             phase2_type == EAP_TTLS_PHASE2_PAP ||
     811             :             phase2_type == EAP_TTLS_PHASE2_CHAP) {
     812         235 :                 if (eap_get_config_identity(sm, &len) == NULL) {
     813           2 :                         wpa_printf(MSG_INFO,
     814             :                                    "EAP-TTLS: Identity not configured");
     815           2 :                         eap_sm_request_identity(sm);
     816           2 :                         if (eap_get_config_password(sm, &len) == NULL)
     817           1 :                                 eap_sm_request_password(sm);
     818           2 :                         return 0;
     819             :                 }
     820             : 
     821         233 :                 if (eap_get_config_password(sm, &len) == NULL) {
     822           3 :                         wpa_printf(MSG_INFO,
     823             :                                    "EAP-TTLS: Password not configured");
     824           3 :                         eap_sm_request_password(sm);
     825           3 :                         return 0;
     826             :                 }
     827             :         }
     828             : 
     829         447 :         switch (phase2_type) {
     830             :         case EAP_TTLS_PHASE2_EAP:
     831         217 :                 res = eap_ttls_phase2_request_eap(sm, data, ret, hdr, resp);
     832         217 :                 break;
     833             :         case EAP_TTLS_PHASE2_MSCHAPV2:
     834         121 :                 res = eap_ttls_phase2_request_mschapv2(sm, data, ret, resp);
     835         121 :                 break;
     836             :         case EAP_TTLS_PHASE2_MSCHAP:
     837          18 :                 res = eap_ttls_phase2_request_mschap(sm, data, ret, resp);
     838          18 :                 break;
     839             :         case EAP_TTLS_PHASE2_PAP:
     840          79 :                 res = eap_ttls_phase2_request_pap(sm, data, ret, resp);
     841          79 :                 break;
     842             :         case EAP_TTLS_PHASE2_CHAP:
     843          12 :                 res = eap_ttls_phase2_request_chap(sm, data, ret, resp);
     844          12 :                 break;
     845             :         default:
     846           0 :                 wpa_printf(MSG_ERROR, "EAP-TTLS: Phase 2 - Unknown");
     847           0 :                 res = -1;
     848           0 :                 break;
     849             :         }
     850             : 
     851         447 :         if (res < 0) {
     852          36 :                 ret->methodState = METHOD_DONE;
     853          36 :                 ret->decision = DECISION_FAIL;
     854             :         }
     855             : 
     856         447 :         return res;
     857             : }
     858             : 
     859             : 
     860             : struct ttls_parse_avp {
     861             :         u8 *mschapv2;
     862             :         u8 *eapdata;
     863             :         size_t eap_len;
     864             :         int mschapv2_error;
     865             : };
     866             : 
     867             : 
     868         176 : static int eap_ttls_parse_attr_eap(const u8 *dpos, size_t dlen,
     869             :                                    struct ttls_parse_avp *parse)
     870             : {
     871         176 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
     872         176 :         if (parse->eapdata == NULL) {
     873         176 :                 parse->eapdata = os_malloc(dlen);
     874         176 :                 if (parse->eapdata == NULL) {
     875           1 :                         wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate "
     876             :                                    "memory for Phase 2 EAP data");
     877           1 :                         return -1;
     878             :                 }
     879         175 :                 os_memcpy(parse->eapdata, dpos, dlen);
     880         175 :                 parse->eap_len = dlen;
     881             :         } else {
     882           0 :                 u8 *neweap = os_realloc(parse->eapdata, parse->eap_len + dlen);
     883           0 :                 if (neweap == NULL) {
     884           0 :                         wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate "
     885             :                                    "memory for Phase 2 EAP data");
     886           0 :                         return -1;
     887             :                 }
     888           0 :                 os_memcpy(neweap + parse->eap_len, dpos, dlen);
     889           0 :                 parse->eapdata = neweap;
     890           0 :                 parse->eap_len += dlen;
     891             :         }
     892             : 
     893         175 :         return 0;
     894             : }
     895             : 
     896             : 
     897         285 : static int eap_ttls_parse_avp(u8 *pos, size_t left,
     898             :                               struct ttls_parse_avp *parse)
     899             : {
     900             :         struct ttls_avp *avp;
     901         285 :         u32 avp_code, avp_length, vendor_id = 0;
     902             :         u8 avp_flags, *dpos;
     903             :         size_t dlen;
     904             : 
     905         285 :         avp = (struct ttls_avp *) pos;
     906         285 :         avp_code = be_to_host32(avp->avp_code);
     907         285 :         avp_length = be_to_host32(avp->avp_length);
     908         285 :         avp_flags = (avp_length >> 24) & 0xff;
     909         285 :         avp_length &= 0xffffff;
     910         285 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
     911             :                    "length=%d", (int) avp_code, avp_flags,
     912             :                    (int) avp_length);
     913             : 
     914         285 :         if (avp_length > left) {
     915           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
     916             :                            "(len=%d, left=%lu) - dropped",
     917             :                            (int) avp_length, (unsigned long) left);
     918           0 :                 return -1;
     919             :         }
     920             : 
     921         285 :         if (avp_length < sizeof(*avp)) {
     922           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length %d",
     923             :                            avp_length);
     924           0 :                 return -1;
     925             :         }
     926             : 
     927         285 :         dpos = (u8 *) (avp + 1);
     928         285 :         dlen = avp_length - sizeof(*avp);
     929         285 :         if (avp_flags & AVP_FLAGS_VENDOR) {
     930         109 :                 if (dlen < 4) {
     931           0 :                         wpa_printf(MSG_WARNING, "EAP-TTLS: Vendor AVP "
     932             :                                    "underflow");
     933           0 :                         return -1;
     934             :                 }
     935         109 :                 vendor_id = WPA_GET_BE32(dpos);
     936         109 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
     937             :                            (int) vendor_id);
     938         109 :                 dpos += 4;
     939         109 :                 dlen -= 4;
     940             :         }
     941             : 
     942         285 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
     943             : 
     944         285 :         if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
     945         351 :                 if (eap_ttls_parse_attr_eap(dpos, dlen, parse) < 0)
     946           1 :                         return -1;
     947         109 :         } else if (vendor_id == 0 && avp_code == RADIUS_ATTR_REPLY_MESSAGE) {
     948             :                 /* This is an optional message that can be displayed to
     949             :                  * the user. */
     950           0 :                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: AVP - Reply-Message",
     951             :                                   dpos, dlen);
     952         109 :         } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
     953             :                    avp_code == RADIUS_ATTR_MS_CHAP2_SUCCESS) {
     954         108 :                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP2-Success",
     955             :                                   dpos, dlen);
     956         108 :                 if (dlen != 43) {
     957           0 :                         wpa_printf(MSG_WARNING, "EAP-TTLS: Unexpected "
     958             :                                    "MS-CHAP2-Success length "
     959             :                                    "(len=%lu, expected 43)",
     960             :                                    (unsigned long) dlen);
     961           0 :                         return -1;
     962             :                 }
     963         108 :                 parse->mschapv2 = dpos;
     964           1 :         } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
     965             :                    avp_code == RADIUS_ATTR_MS_CHAP_ERROR) {
     966           1 :                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP-Error",
     967             :                                   dpos, dlen);
     968           1 :                 parse->mschapv2_error = 1;
     969           0 :         } else if (avp_flags & AVP_FLAGS_MANDATORY) {
     970           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported mandatory AVP "
     971             :                            "code %d vendor_id %d - dropped",
     972             :                            (int) avp_code, (int) vendor_id);
     973           0 :                 return -1;
     974             :         } else {
     975           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported AVP "
     976             :                            "code %d vendor_id %d",
     977             :                            (int) avp_code, (int) vendor_id);
     978             :         }
     979             : 
     980         284 :         return avp_length;
     981             : }
     982             : 
     983             : 
     984         285 : static int eap_ttls_parse_avps(struct wpabuf *in_decrypted,
     985             :                                struct ttls_parse_avp *parse)
     986             : {
     987             :         u8 *pos;
     988             :         size_t left, pad;
     989             :         int avp_length;
     990             : 
     991         285 :         pos = wpabuf_mhead(in_decrypted);
     992         285 :         left = wpabuf_len(in_decrypted);
     993         285 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 AVPs", pos, left);
     994         285 :         if (left < sizeof(struct ttls_avp)) {
     995           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 AVP frame"
     996             :                            " len=%lu expected %lu or more - dropped",
     997             :                            (unsigned long) left,
     998             :                            (unsigned long) sizeof(struct ttls_avp));
     999           0 :                 return -1;
    1000             :         }
    1001             : 
    1002             :         /* Parse AVPs */
    1003         285 :         os_memset(parse, 0, sizeof(*parse));
    1004             : 
    1005         854 :         while (left > 0) {
    1006         285 :                 avp_length = eap_ttls_parse_avp(pos, left, parse);
    1007         285 :                 if (avp_length < 0)
    1008           1 :                         return -1;
    1009             : 
    1010         284 :                 pad = (4 - (avp_length & 3)) & 3;
    1011         284 :                 pos += avp_length + pad;
    1012         284 :                 if (left < avp_length + pad)
    1013         108 :                         left = 0;
    1014             :                 else
    1015         176 :                         left -= avp_length + pad;
    1016             :         }
    1017             : 
    1018         284 :         return 0;
    1019             : }
    1020             : 
    1021             : 
    1022         278 : static u8 * eap_ttls_fake_identity_request(void)
    1023             : {
    1024             :         struct eap_hdr *hdr;
    1025             :         u8 *buf;
    1026             : 
    1027         278 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: empty data in beginning of "
    1028             :                    "Phase 2 - use fake EAP-Request Identity");
    1029         278 :         buf = os_malloc(sizeof(*hdr) + 1);
    1030         278 :         if (buf == NULL) {
    1031           1 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate "
    1032             :                            "memory for fake EAP-Identity Request");
    1033           1 :                 return NULL;
    1034             :         }
    1035             : 
    1036         277 :         hdr = (struct eap_hdr *) buf;
    1037         277 :         hdr->code = EAP_CODE_REQUEST;
    1038         277 :         hdr->identifier = 0;
    1039         277 :         hdr->length = host_to_be16(sizeof(*hdr) + 1);
    1040         277 :         buf[sizeof(*hdr)] = EAP_TYPE_IDENTITY;
    1041             : 
    1042         277 :         return buf;
    1043             : }
    1044             : 
    1045             : 
    1046         414 : static int eap_ttls_encrypt_response(struct eap_sm *sm,
    1047             :                                      struct eap_ttls_data *data,
    1048             :                                      struct wpabuf *resp, u8 identifier,
    1049             :                                      struct wpabuf **out_data)
    1050             : {
    1051         414 :         if (resp == NULL)
    1052           5 :                 return 0;
    1053             : 
    1054         409 :         wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Encrypting Phase 2 data",
    1055             :                             resp);
    1056         409 :         if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,
    1057             :                                  data->ttls_version, identifier,
    1058             :                                  resp, out_data)) {
    1059           2 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt a Phase 2 "
    1060             :                            "frame");
    1061           2 :                 wpabuf_free(resp);
    1062           2 :                 return -1;
    1063             :         }
    1064         407 :         wpabuf_free(resp);
    1065             : 
    1066         407 :         return 0;
    1067             : }
    1068             : 
    1069             : 
    1070         175 : static int eap_ttls_process_phase2_eap(struct eap_sm *sm,
    1071             :                                        struct eap_ttls_data *data,
    1072             :                                        struct eap_method_ret *ret,
    1073             :                                        struct ttls_parse_avp *parse,
    1074             :                                        struct wpabuf **resp)
    1075             : {
    1076             :         struct eap_hdr *hdr;
    1077             :         size_t len;
    1078             : 
    1079         175 :         if (parse->eapdata == NULL) {
    1080           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: No EAP Message in the "
    1081             :                            "packet - dropped");
    1082           0 :                 return -1;
    1083             :         }
    1084             : 
    1085         350 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP",
    1086         175 :                     parse->eapdata, parse->eap_len);
    1087         175 :         hdr = (struct eap_hdr *) parse->eapdata;
    1088             : 
    1089         175 :         if (parse->eap_len < sizeof(*hdr)) {
    1090           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 EAP "
    1091             :                            "frame (len=%lu, expected %lu or more) - dropped",
    1092             :                            (unsigned long) parse->eap_len,
    1093             :                            (unsigned long) sizeof(*hdr));
    1094           0 :                 return -1;
    1095             :         }
    1096         175 :         len = be_to_host16(hdr->length);
    1097         175 :         if (len > parse->eap_len) {
    1098           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Length mismatch in Phase 2 "
    1099             :                            "EAP frame (EAP hdr len=%lu, EAP data len in "
    1100             :                            "AVP=%lu)",
    1101             :                            (unsigned long) len,
    1102             :                            (unsigned long) parse->eap_len);
    1103           0 :                 return -1;
    1104             :         }
    1105         350 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: received Phase 2: code=%d "
    1106             :                    "identifier=%d length=%lu",
    1107         350 :                    hdr->code, hdr->identifier, (unsigned long) len);
    1108         175 :         switch (hdr->code) {
    1109             :         case EAP_CODE_REQUEST:
    1110         175 :                 if (eap_ttls_phase2_request(sm, data, ret, hdr, resp)) {
    1111          21 :                         wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "
    1112             :                                    "processing failed");
    1113          21 :                         return -1;
    1114             :                 }
    1115         154 :                 break;
    1116             :         default:
    1117           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Unexpected code=%d in "
    1118           0 :                            "Phase 2 EAP header", hdr->code);
    1119           0 :                 return -1;
    1120             :         }
    1121             : 
    1122         154 :         return 0;
    1123             : }
    1124             : 
    1125             : 
    1126         112 : static int eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
    1127             :                                             struct eap_ttls_data *data,
    1128             :                                             struct eap_method_ret *ret,
    1129             :                                             struct ttls_parse_avp *parse)
    1130             : {
    1131             : #ifdef EAP_MSCHAPv2
    1132         112 :         if (parse->mschapv2_error) {
    1133           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Received "
    1134             :                            "MS-CHAP-Error - failed");
    1135           1 :                 ret->methodState = METHOD_DONE;
    1136           1 :                 ret->decision = DECISION_FAIL;
    1137             :                 /* Reply with empty data to ACK error */
    1138           1 :                 return 1;
    1139             :         }
    1140             : 
    1141         111 :         if (parse->mschapv2 == NULL) {
    1142             : #ifdef EAP_TNC
    1143           3 :                 if (data->phase2_success && parse->eapdata) {
    1144             :                         /*
    1145             :                          * Allow EAP-TNC to be started after successfully
    1146             :                          * completed MSCHAPV2.
    1147             :                          */
    1148           3 :                         return 1;
    1149             :                 }
    1150             : #endif /* EAP_TNC */
    1151           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: no MS-CHAP2-Success AVP "
    1152             :                            "received for Phase2 MSCHAPV2");
    1153           0 :                 return -1;
    1154             :         }
    1155         108 :         if (parse->mschapv2[0] != data->ident) {
    1156           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Ident mismatch for Phase 2 "
    1157             :                            "MSCHAPV2 (received Ident 0x%02x, expected 0x%02x)",
    1158           0 :                            parse->mschapv2[0], data->ident);
    1159           0 :                 return -1;
    1160             :         }
    1161         216 :         if (!data->auth_response_valid ||
    1162         108 :             mschapv2_verify_auth_response(data->auth_response,
    1163         108 :                                           parse->mschapv2 + 1, 42)) {
    1164           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid authenticator "
    1165             :                            "response in Phase 2 MSCHAPV2 success request");
    1166           0 :                 return -1;
    1167             :         }
    1168             : 
    1169         108 :         wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 MSCHAPV2 "
    1170             :                    "authentication succeeded");
    1171         108 :         ret->methodState = METHOD_DONE;
    1172         108 :         ret->decision = DECISION_UNCOND_SUCC;
    1173         108 :         data->phase2_success = 1;
    1174             : 
    1175             :         /*
    1176             :          * Reply with empty data; authentication server will reply
    1177             :          * with EAP-Success after this.
    1178             :          */
    1179         108 :         return 1;
    1180             : #else /* EAP_MSCHAPv2 */
    1181             :         wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPv2 not included in the build");
    1182             :         return -1;
    1183             : #endif /* EAP_MSCHAPv2 */
    1184             : }
    1185             : 
    1186             : 
    1187             : #ifdef EAP_TNC
    1188          24 : static int eap_ttls_process_tnc_start(struct eap_sm *sm,
    1189             :                                       struct eap_ttls_data *data,
    1190             :                                       struct eap_method_ret *ret,
    1191             :                                       struct ttls_parse_avp *parse,
    1192             :                                       struct wpabuf **resp)
    1193             : {
    1194             :         /* TNC uses inner EAP method after non-EAP TTLS phase 2. */
    1195          24 :         if (parse->eapdata == NULL) {
    1196           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received "
    1197             :                            "unexpected tunneled data (no EAP)");
    1198           0 :                 return -1;
    1199             :         }
    1200             : 
    1201          24 :         if (!data->ready_for_tnc) {
    1202           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received "
    1203             :                            "EAP after non-EAP, but not ready for TNC");
    1204           0 :                 return -1;
    1205             :         }
    1206             : 
    1207          24 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Start TNC after completed "
    1208             :                    "non-EAP method");
    1209          24 :         data->tnc_started = 1;
    1210             : 
    1211          24 :         if (eap_ttls_process_phase2_eap(sm, data, ret, parse, resp) < 0)
    1212          13 :                 return -1;
    1213             : 
    1214          11 :         return 0;
    1215             : }
    1216             : #endif /* EAP_TNC */
    1217             : 
    1218             : 
    1219         284 : static int eap_ttls_process_decrypted(struct eap_sm *sm,
    1220             :                                       struct eap_ttls_data *data,
    1221             :                                       struct eap_method_ret *ret,
    1222             :                                       u8 identifier,
    1223             :                                       struct ttls_parse_avp *parse,
    1224             :                                       struct wpabuf *in_decrypted,
    1225             :                                       struct wpabuf **out_data)
    1226             : {
    1227         284 :         struct wpabuf *resp = NULL;
    1228         284 :         struct eap_peer_config *config = eap_get_config(sm);
    1229             :         int res;
    1230         284 :         enum phase2_types phase2_type = data->phase2_type;
    1231             : 
    1232             : #ifdef EAP_TNC
    1233         284 :         if (data->tnc_started)
    1234          91 :                 phase2_type = EAP_TTLS_PHASE2_EAP;
    1235             : #endif /* EAP_TNC */
    1236             : 
    1237         284 :         switch (phase2_type) {
    1238             :         case EAP_TTLS_PHASE2_EAP:
    1239         151 :                 if (eap_ttls_process_phase2_eap(sm, data, ret, parse, &resp) <
    1240             :                     0)
    1241           8 :                         return -1;
    1242         143 :                 break;
    1243             :         case EAP_TTLS_PHASE2_MSCHAPV2:
    1244         112 :                 res = eap_ttls_process_phase2_mschapv2(sm, data, ret, parse);
    1245             : #ifdef EAP_TNC
    1246         112 :                 if (res == 1 && parse->eapdata && data->phase2_success) {
    1247             :                         /*
    1248             :                          * TNC may be required as the next
    1249             :                          * authentication method within the tunnel.
    1250             :                          */
    1251           3 :                         ret->methodState = METHOD_MAY_CONT;
    1252           3 :                         data->ready_for_tnc = 1;
    1253           3 :                         if (eap_ttls_process_tnc_start(sm, data, ret, parse,
    1254             :                                                        &resp) == 0)
    1255           2 :                                 break;
    1256             :                 }
    1257             : #endif /* EAP_TNC */
    1258         110 :                 return res;
    1259             :         case EAP_TTLS_PHASE2_MSCHAP:
    1260             :         case EAP_TTLS_PHASE2_PAP:
    1261             :         case EAP_TTLS_PHASE2_CHAP:
    1262             : #ifdef EAP_TNC
    1263          21 :                 if (eap_ttls_process_tnc_start(sm, data, ret, parse, &resp) <
    1264             :                     0)
    1265          12 :                         return -1;
    1266           9 :                 break;
    1267             : #else /* EAP_TNC */
    1268             :                 /* EAP-TTLS/{MSCHAP,PAP,CHAP} should not send any TLS tunneled
    1269             :                  * requests to the supplicant */
    1270             :                 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received unexpected "
    1271             :                            "tunneled data");
    1272             :                 return -1;
    1273             : #endif /* EAP_TNC */
    1274             :         }
    1275             : 
    1276         154 :         if (resp) {
    1277         152 :                 if (eap_ttls_encrypt_response(sm, data, resp, identifier,
    1278             :                                               out_data) < 0)
    1279           1 :                         return -1;
    1280           4 :         } else if (config->pending_req_identity ||
    1281           2 :                    config->pending_req_password ||
    1282           0 :                    config->pending_req_otp ||
    1283           0 :                    config->pending_req_new_password) {
    1284           2 :                 wpabuf_free(data->pending_phase2_req);
    1285           2 :                 data->pending_phase2_req = wpabuf_dup(in_decrypted);
    1286             :         }
    1287             : 
    1288         153 :         return 0;
    1289             : }
    1290             : 
    1291             : 
    1292         278 : static int eap_ttls_implicit_identity_request(struct eap_sm *sm,
    1293             :                                               struct eap_ttls_data *data,
    1294             :                                               struct eap_method_ret *ret,
    1295             :                                               u8 identifier,
    1296             :                                               struct wpabuf **out_data)
    1297             : {
    1298         278 :         int retval = 0;
    1299             :         struct eap_hdr *hdr;
    1300             :         struct wpabuf *resp;
    1301             : 
    1302         278 :         hdr = (struct eap_hdr *) eap_ttls_fake_identity_request();
    1303         278 :         if (hdr == NULL) {
    1304           1 :                 ret->methodState = METHOD_DONE;
    1305           1 :                 ret->decision = DECISION_FAIL;
    1306           1 :                 return -1;
    1307             :         }
    1308             : 
    1309         277 :         resp = NULL;
    1310         277 :         if (eap_ttls_phase2_request(sm, data, ret, hdr, &resp)) {
    1311          15 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "
    1312             :                            "processing failed");
    1313          15 :                 retval = -1;
    1314             :         } else {
    1315         262 :                 struct eap_peer_config *config = eap_get_config(sm);
    1316         267 :                 if (resp == NULL &&
    1317           8 :                     (config->pending_req_identity ||
    1318           3 :                      config->pending_req_password ||
    1319           0 :                      config->pending_req_otp ||
    1320           0 :                      config->pending_req_new_password)) {
    1321             :                         /*
    1322             :                          * Use empty buffer to force implicit request
    1323             :                          * processing when EAP request is re-processed after
    1324             :                          * user input.
    1325             :                          */
    1326           5 :                         wpabuf_free(data->pending_phase2_req);
    1327           5 :                         data->pending_phase2_req = wpabuf_alloc(0);
    1328             :                 }
    1329             : 
    1330         262 :                 retval = eap_ttls_encrypt_response(sm, data, resp, identifier,
    1331             :                                                    out_data);
    1332             :         }
    1333             : 
    1334         277 :         os_free(hdr);
    1335             : 
    1336         277 :         if (retval < 0) {
    1337          16 :                 ret->methodState = METHOD_DONE;
    1338          16 :                 ret->decision = DECISION_FAIL;
    1339             :         }
    1340             : 
    1341         277 :         return retval;
    1342             : }
    1343             : 
    1344             : 
    1345         273 : static int eap_ttls_phase2_start(struct eap_sm *sm, struct eap_ttls_data *data,
    1346             :                                  struct eap_method_ret *ret, u8 identifier,
    1347             :                                  struct wpabuf **out_data)
    1348             : {
    1349         273 :         data->phase2_start = 0;
    1350             : 
    1351             :         /*
    1352             :          * EAP-TTLS does not use Phase2 on fast re-auth; this must be done only
    1353             :          * if TLS part was indeed resuming a previous session. Most
    1354             :          * Authentication Servers terminate EAP-TTLS before reaching this
    1355             :          * point, but some do not. Make wpa_supplicant stop phase 2 here, if
    1356             :          * needed.
    1357             :          */
    1358         287 :         if (data->reauth &&
    1359          14 :             tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) {
    1360           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Session resumption - "
    1361             :                            "skip phase 2");
    1362           0 :                 *out_data = eap_peer_tls_build_ack(identifier, EAP_TYPE_TTLS,
    1363             :                                                    data->ttls_version);
    1364           0 :                 ret->methodState = METHOD_DONE;
    1365           0 :                 ret->decision = DECISION_UNCOND_SUCC;
    1366           0 :                 data->phase2_success = 1;
    1367           0 :                 return 0;
    1368             :         }
    1369             : 
    1370         273 :         return eap_ttls_implicit_identity_request(sm, data, ret, identifier,
    1371             :                                                   out_data);
    1372             : }
    1373             : 
    1374             : 
    1375         598 : static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,
    1376             :                             struct eap_method_ret *ret, u8 identifier,
    1377             :                             const struct wpabuf *in_data,
    1378             :                             struct wpabuf **out_data)
    1379             : {
    1380         598 :         struct wpabuf *in_decrypted = NULL;
    1381         598 :         int retval = 0;
    1382             :         struct ttls_parse_avp parse;
    1383             : 
    1384         598 :         os_memset(&parse, 0, sizeof(parse));
    1385             : 
    1386         598 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
    1387             :                    " Phase 2",
    1388             :                    in_data ? (unsigned long) wpabuf_len(in_data) : 0);
    1389             : 
    1390         598 :         if (data->pending_phase2_req) {
    1391           7 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 request - "
    1392             :                            "skip decryption and use old data");
    1393             :                 /* Clear TLS reassembly state. */
    1394           7 :                 eap_peer_tls_reset_input(&data->ssl);
    1395             : 
    1396           7 :                 in_decrypted = data->pending_phase2_req;
    1397           7 :                 data->pending_phase2_req = NULL;
    1398           7 :                 if (wpabuf_len(in_decrypted) == 0) {
    1399           5 :                         wpabuf_free(in_decrypted);
    1400           5 :                         return eap_ttls_implicit_identity_request(
    1401             :                                 sm, data, ret, identifier, out_data);
    1402             :                 }
    1403           2 :                 goto continue_req;
    1404             :         }
    1405             : 
    1406         897 :         if ((in_data == NULL || wpabuf_len(in_data) == 0) &&
    1407         306 :             data->phase2_start) {
    1408         273 :                 return eap_ttls_phase2_start(sm, data, ret, identifier,
    1409             :                                              out_data);
    1410             :         }
    1411             : 
    1412         318 :         if (in_data == NULL || wpabuf_len(in_data) == 0) {
    1413             :                 /* Received TLS ACK - requesting more fragments */
    1414          33 :                 return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,
    1415             :                                             data->ttls_version,
    1416             :                                             identifier, NULL, out_data);
    1417             :         }
    1418             : 
    1419         285 :         retval = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
    1420         285 :         if (retval)
    1421           2 :                 goto done;
    1422             : 
    1423             : continue_req:
    1424         285 :         data->phase2_start = 0;
    1425             : 
    1426         285 :         if (eap_ttls_parse_avps(in_decrypted, &parse) < 0) {
    1427           1 :                 retval = -1;
    1428           1 :                 goto done;
    1429             :         }
    1430             : 
    1431         284 :         retval = eap_ttls_process_decrypted(sm, data, ret, identifier,
    1432             :                                             &parse, in_decrypted, out_data);
    1433             : 
    1434             : done:
    1435         287 :         wpabuf_free(in_decrypted);
    1436         287 :         os_free(parse.eapdata);
    1437             : 
    1438         287 :         if (retval < 0) {
    1439          24 :                 ret->methodState = METHOD_DONE;
    1440          24 :                 ret->decision = DECISION_FAIL;
    1441             :         }
    1442             : 
    1443         287 :         return retval;
    1444             : }
    1445             : 
    1446             : 
    1447        1530 : static int eap_ttls_process_handshake(struct eap_sm *sm,
    1448             :                                       struct eap_ttls_data *data,
    1449             :                                       struct eap_method_ret *ret,
    1450             :                                       u8 identifier,
    1451             :                                       const struct wpabuf *in_data,
    1452             :                                       struct wpabuf **out_data)
    1453             : {
    1454             :         int res;
    1455             : 
    1456        1530 :         if (sm->waiting_ext_cert_check && data->pending_resp) {
    1457           2 :                 struct eap_peer_config *config = eap_get_config(sm);
    1458             : 
    1459           2 :                 if (config->pending_ext_cert_check == EXT_CERT_CHECK_GOOD) {
    1460           1 :                         wpa_printf(MSG_DEBUG,
    1461             :                                    "EAP-TTLS: External certificate check succeeded - continue handshake");
    1462           1 :                         *out_data = data->pending_resp;
    1463           1 :                         data->pending_resp = NULL;
    1464           1 :                         sm->waiting_ext_cert_check = 0;
    1465           1 :                         return 0;
    1466             :                 }
    1467             : 
    1468           1 :                 if (config->pending_ext_cert_check == EXT_CERT_CHECK_BAD) {
    1469           1 :                         wpa_printf(MSG_DEBUG,
    1470             :                                    "EAP-TTLS: External certificate check failed - force authentication failure");
    1471           1 :                         ret->methodState = METHOD_DONE;
    1472           1 :                         ret->decision = DECISION_FAIL;
    1473           1 :                         sm->waiting_ext_cert_check = 0;
    1474           1 :                         return 0;
    1475             :                 }
    1476             : 
    1477           0 :                 wpa_printf(MSG_DEBUG,
    1478             :                            "EAP-TTLS: Continuing to wait external server certificate validation");
    1479           0 :                 return 0;
    1480             :         }
    1481             : 
    1482        1528 :         res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS,
    1483             :                                           data->ttls_version, identifier,
    1484             :                                           in_data, out_data);
    1485        1528 :         if (res < 0) {
    1486          21 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS processing failed");
    1487          21 :                 ret->methodState = METHOD_DONE;
    1488          21 :                 ret->decision = DECISION_FAIL;
    1489          21 :                 return -1;
    1490             :         }
    1491             : 
    1492        1507 :         if (sm->waiting_ext_cert_check) {
    1493           2 :                 wpa_printf(MSG_DEBUG,
    1494             :                            "EAP-TTLS: Waiting external server certificate validation");
    1495           2 :                 wpabuf_free(data->pending_resp);
    1496           2 :                 data->pending_resp = *out_data;
    1497           2 :                 *out_data = NULL;
    1498           2 :                 return 0;
    1499             :         }
    1500             : 
    1501        1505 :         if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
    1502         278 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS done, proceed to "
    1503             :                            "Phase 2");
    1504         278 :                 if (data->resuming) {
    1505          19 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: fast reauth - may "
    1506             :                                    "skip Phase 2");
    1507          19 :                         ret->decision = DECISION_COND_SUCC;
    1508          19 :                         ret->methodState = METHOD_MAY_CONT;
    1509             :                 }
    1510         278 :                 data->phase2_start = 1;
    1511         278 :                 eap_ttls_v0_derive_key(sm, data);
    1512             : 
    1513         278 :                 if (*out_data == NULL || wpabuf_len(*out_data) == 0) {
    1514         273 :                         if (eap_ttls_decrypt(sm, data, ret, identifier,
    1515             :                                              NULL, out_data)) {
    1516          17 :                                 wpa_printf(MSG_WARNING, "EAP-TTLS: "
    1517             :                                            "failed to process early "
    1518             :                                            "start for Phase 2");
    1519             :                         }
    1520         273 :                         res = 0;
    1521             :                 }
    1522         278 :                 data->resuming = 0;
    1523             :         }
    1524             : 
    1525        1505 :         if (res == 2) {
    1526             :                 /*
    1527             :                  * Application data included in the handshake message.
    1528             :                  */
    1529           0 :                 wpabuf_free(data->pending_phase2_req);
    1530           0 :                 data->pending_phase2_req = *out_data;
    1531           0 :                 *out_data = NULL;
    1532           0 :                 res = eap_ttls_decrypt(sm, data, ret, identifier, in_data,
    1533             :                                        out_data);
    1534             :         }
    1535             : 
    1536        1505 :         return res;
    1537             : }
    1538             : 
    1539             : 
    1540        1855 : static void eap_ttls_check_auth_status(struct eap_sm *sm, 
    1541             :                                        struct eap_ttls_data *data,
    1542             :                                        struct eap_method_ret *ret)
    1543             : {
    1544        1855 :         if (ret->methodState == METHOD_DONE) {
    1545         298 :                 ret->allowNotifications = FALSE;
    1546         479 :                 if (ret->decision == DECISION_UNCOND_SUCC ||
    1547         181 :                     ret->decision == DECISION_COND_SUCC) {
    1548         232 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
    1549             :                                    "completed successfully");
    1550         232 :                         data->phase2_success = 1;
    1551         232 :                         data->decision_succ = ret->decision;
    1552             : #ifdef EAP_TNC
    1553         232 :                         if (!data->ready_for_tnc && !data->tnc_started) {
    1554             :                                 /*
    1555             :                                  * TNC may be required as the next
    1556             :                                  * authentication method within the tunnel.
    1557             :                                  */
    1558         232 :                                 ret->methodState = METHOD_MAY_CONT;
    1559         232 :                                 data->ready_for_tnc = 1;
    1560             :                         }
    1561             : #endif /* EAP_TNC */
    1562             :                 }
    1563        3114 :         } else if (ret->methodState == METHOD_MAY_CONT &&
    1564        3112 :                    (ret->decision == DECISION_UNCOND_SUCC ||
    1565        1555 :                     ret->decision == DECISION_COND_SUCC)) {
    1566          14 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
    1567             :                                    "completed successfully (MAY_CONT)");
    1568          14 :                         data->phase2_success = 1;
    1569          14 :                         data->decision_succ = ret->decision;
    1570        1675 :         } else if (data->decision_succ != DECISION_FAIL &&
    1571         264 :                    data->phase2_success &&
    1572         132 :                    !data->ssl.tls_out) {
    1573             :                 /*
    1574             :                  * This is needed to cover the case where the final Phase 2
    1575             :                  * message gets fragmented since fragmentation clears
    1576             :                  * decision back to FAIL.
    1577             :                  */
    1578          97 :                 wpa_printf(MSG_DEBUG,
    1579             :                            "EAP-TTLS: Restore success decision after fragmented frame sent completely");
    1580          97 :                 ret->decision = data->decision_succ;
    1581             :         }
    1582        1855 : }
    1583             : 
    1584             : 
    1585        1855 : static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv,
    1586             :                                         struct eap_method_ret *ret,
    1587             :                                         const struct wpabuf *reqData)
    1588             : {
    1589             :         size_t left;
    1590             :         int res;
    1591             :         u8 flags, id;
    1592             :         struct wpabuf *resp;
    1593             :         const u8 *pos;
    1594        1855 :         struct eap_ttls_data *data = priv;
    1595             :         struct wpabuf msg;
    1596             : 
    1597        1855 :         pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TTLS, ret,
    1598             :                                         reqData, &left, &flags);
    1599        1855 :         if (pos == NULL)
    1600           0 :                 return NULL;
    1601        1855 :         id = eap_get_id(reqData);
    1602             : 
    1603        1855 :         if (flags & EAP_TLS_FLAGS_START) {
    1604         310 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start (server ver=%d, own "
    1605             :                            "ver=%d)", flags & EAP_TLS_VERSION_MASK,
    1606             :                            data->ttls_version);
    1607             : 
    1608             :                 /* RFC 5281, Ch. 9.2:
    1609             :                  * "This packet MAY contain additional information in the form
    1610             :                  * of AVPs, which may provide useful hints to the client"
    1611             :                  * For now, ignore any potential extra data.
    1612             :                  */
    1613         310 :                 left = 0;
    1614             :         }
    1615             : 
    1616        1855 :         wpabuf_set(&msg, pos, left);
    1617             : 
    1618        1855 :         resp = NULL;
    1619        2180 :         if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
    1620         325 :             !data->resuming) {
    1621         325 :                 res = eap_ttls_decrypt(sm, data, ret, id, &msg, &resp);
    1622             :         } else {
    1623        1530 :                 res = eap_ttls_process_handshake(sm, data, ret, id,
    1624             :                                                  &msg, &resp);
    1625             :         }
    1626             : 
    1627        1855 :         eap_ttls_check_auth_status(sm, data, ret);
    1628             : 
    1629             :         /* FIX: what about res == -1? Could just move all error processing into
    1630             :          * the other functions and get rid of this res==1 case here. */
    1631        1855 :         if (res == 1) {
    1632         637 :                 wpabuf_free(resp);
    1633         637 :                 return eap_peer_tls_build_ack(id, EAP_TYPE_TTLS,
    1634             :                                               data->ttls_version);
    1635             :         }
    1636        1218 :         return resp;
    1637             : }
    1638             : 
    1639             : 
    1640          76 : static Boolean eap_ttls_has_reauth_data(struct eap_sm *sm, void *priv)
    1641             : {
    1642          76 :         struct eap_ttls_data *data = priv;
    1643         152 :         return tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
    1644          76 :                 data->phase2_success;
    1645             : }
    1646             : 
    1647             : 
    1648          43 : static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv)
    1649             : {
    1650          43 :         struct eap_ttls_data *data = priv;
    1651          43 :         wpabuf_free(data->pending_phase2_req);
    1652          43 :         data->pending_phase2_req = NULL;
    1653          43 :         wpabuf_free(data->pending_resp);
    1654          43 :         data->pending_resp = NULL;
    1655          43 :         data->decision_succ = DECISION_FAIL;
    1656             : #ifdef EAP_TNC
    1657          43 :         data->ready_for_tnc = 0;
    1658          43 :         data->tnc_started = 0;
    1659             : #endif /* EAP_TNC */
    1660          43 : }
    1661             : 
    1662             : 
    1663          23 : static void * eap_ttls_init_for_reauth(struct eap_sm *sm, void *priv)
    1664             : {
    1665          23 :         struct eap_ttls_data *data = priv;
    1666          23 :         eap_ttls_free_key(data);
    1667          23 :         os_free(data->session_id);
    1668          23 :         data->session_id = NULL;
    1669          23 :         if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
    1670           0 :                 os_free(data);
    1671           0 :                 return NULL;
    1672             :         }
    1673          27 :         if (data->phase2_priv && data->phase2_method &&
    1674           4 :             data->phase2_method->init_for_reauth)
    1675           0 :                 data->phase2_method->init_for_reauth(sm, data->phase2_priv);
    1676          23 :         data->phase2_start = 0;
    1677          23 :         data->phase2_success = 0;
    1678          23 :         data->resuming = 1;
    1679          23 :         data->reauth = 1;
    1680          23 :         return priv;
    1681             : }
    1682             : 
    1683             : 
    1684         116 : static int eap_ttls_get_status(struct eap_sm *sm, void *priv, char *buf,
    1685             :                                size_t buflen, int verbose)
    1686             : {
    1687         116 :         struct eap_ttls_data *data = priv;
    1688             :         int len, ret;
    1689             : 
    1690         116 :         len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);
    1691         116 :         ret = os_snprintf(buf + len, buflen - len,
    1692             :                           "EAP-TTLSv%d Phase2 method=",
    1693             :                           data->ttls_version);
    1694         116 :         if (os_snprintf_error(buflen - len, ret))
    1695           0 :                 return len;
    1696         116 :         len += ret;
    1697         116 :         switch (data->phase2_type) {
    1698             :         case EAP_TTLS_PHASE2_EAP:
    1699          32 :                 ret = os_snprintf(buf + len, buflen - len, "EAP-%s\n",
    1700          16 :                                   data->phase2_method ?
    1701          16 :                                   data->phase2_method->name : "?");
    1702          16 :                 break;
    1703             :         case EAP_TTLS_PHASE2_MSCHAPV2:
    1704          55 :                 ret = os_snprintf(buf + len, buflen - len, "MSCHAPV2\n");
    1705          55 :                 break;
    1706             :         case EAP_TTLS_PHASE2_MSCHAP:
    1707           9 :                 ret = os_snprintf(buf + len, buflen - len, "MSCHAP\n");
    1708           9 :                 break;
    1709             :         case EAP_TTLS_PHASE2_PAP:
    1710          27 :                 ret = os_snprintf(buf + len, buflen - len, "PAP\n");
    1711          27 :                 break;
    1712             :         case EAP_TTLS_PHASE2_CHAP:
    1713           9 :                 ret = os_snprintf(buf + len, buflen - len, "CHAP\n");
    1714           9 :                 break;
    1715             :         default:
    1716           0 :                 ret = 0;
    1717           0 :                 break;
    1718             :         }
    1719         116 :         if (os_snprintf_error(buflen - len, ret))
    1720           0 :                 return len;
    1721         116 :         len += ret;
    1722             : 
    1723         116 :         return len;
    1724             : }
    1725             : 
    1726             : 
    1727        1855 : static Boolean eap_ttls_isKeyAvailable(struct eap_sm *sm, void *priv)
    1728             : {
    1729        1855 :         struct eap_ttls_data *data = priv;
    1730        1855 :         return data->key_data != NULL && data->phase2_success;
    1731             : }
    1732             : 
    1733             : 
    1734         395 : static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
    1735             : {
    1736         395 :         struct eap_ttls_data *data = priv;
    1737             :         u8 *key;
    1738             : 
    1739         395 :         if (data->key_data == NULL || !data->phase2_success)
    1740           0 :                 return NULL;
    1741             : 
    1742         395 :         key = os_malloc(EAP_TLS_KEY_LEN);
    1743         395 :         if (key == NULL)
    1744           1 :                 return NULL;
    1745             : 
    1746         394 :         *len = EAP_TLS_KEY_LEN;
    1747         394 :         os_memcpy(key, data->key_data, EAP_TLS_KEY_LEN);
    1748             : 
    1749         394 :         return key;
    1750             : }
    1751             : 
    1752             : 
    1753         395 : static u8 * eap_ttls_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
    1754             : {
    1755         395 :         struct eap_ttls_data *data = priv;
    1756             :         u8 *id;
    1757             : 
    1758         395 :         if (data->session_id == NULL || !data->phase2_success)
    1759           0 :                 return NULL;
    1760             : 
    1761         395 :         id = os_malloc(data->id_len);
    1762         395 :         if (id == NULL)
    1763           1 :                 return NULL;
    1764             : 
    1765         394 :         *len = data->id_len;
    1766         394 :         os_memcpy(id, data->session_id, data->id_len);
    1767             : 
    1768         394 :         return id;
    1769             : }
    1770             : 
    1771             : 
    1772          19 : static u8 * eap_ttls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
    1773             : {
    1774          19 :         struct eap_ttls_data *data = priv;
    1775             :         u8 *key;
    1776             : 
    1777          19 :         if (data->key_data == NULL)
    1778           0 :                 return NULL;
    1779             : 
    1780          19 :         key = os_malloc(EAP_EMSK_LEN);
    1781          19 :         if (key == NULL)
    1782           1 :                 return NULL;
    1783             : 
    1784          18 :         *len = EAP_EMSK_LEN;
    1785          18 :         os_memcpy(key, data->key_data + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
    1786             : 
    1787          18 :         return key;
    1788             : }
    1789             : 
    1790             : 
    1791          49 : int eap_peer_ttls_register(void)
    1792             : {
    1793             :         struct eap_method *eap;
    1794             : 
    1795          49 :         eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
    1796             :                                     EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
    1797          49 :         if (eap == NULL)
    1798           0 :                 return -1;
    1799             : 
    1800          49 :         eap->init = eap_ttls_init;
    1801          49 :         eap->deinit = eap_ttls_deinit;
    1802          49 :         eap->process = eap_ttls_process;
    1803          49 :         eap->isKeyAvailable = eap_ttls_isKeyAvailable;
    1804          49 :         eap->getKey = eap_ttls_getKey;
    1805          49 :         eap->getSessionId = eap_ttls_get_session_id;
    1806          49 :         eap->get_status = eap_ttls_get_status;
    1807          49 :         eap->has_reauth_data = eap_ttls_has_reauth_data;
    1808          49 :         eap->deinit_for_reauth = eap_ttls_deinit_for_reauth;
    1809          49 :         eap->init_for_reauth = eap_ttls_init_for_reauth;
    1810          49 :         eap->get_emsk = eap_ttls_get_emsk;
    1811             : 
    1812          49 :         return eap_peer_method_register(eap);
    1813             : }

Generated by: LCOV version 1.10