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 1426431149 Lines: 634 795 79.7 %
Date: 2015-03-15 Functions: 42 42 100.0 %

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

Generated by: LCOV version 1.10