]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-TEAP server: Allow tunneled EAP method sequence to be optimized
authorJouni Malinen <quic_jouni@quicinc.com>
Thu, 1 Dec 2022 15:04:13 +0000 (17:04 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 1 Dec 2022 15:53:05 +0000 (17:53 +0200)
Include the start of the next EAP method in an EAP Payload TLV in the
same message with the Crypto-Binding TLV for the previous EAP method to
get rid of one roundtrip when using more than a single EAP
authentication method within the tunnel. The previous, not optimized,
sequence can still be used with eap_teap_method_sequence=1 for more
complete testing coverage.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.h
src/ap/authsrv.c
src/eap_server/eap.h
src/eap_server/eap_server_teap.c

index 8a3357c26a6aefa041e3f066d0550d03673de2e6..a37d86ad5c0081694ea5ee260dd7cf90963c51dd 100644 (file)
@@ -2585,6 +2585,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->eap_teap_separate_result = atoi(pos);
        } else if (os_strcmp(buf, "eap_teap_id") == 0) {
                bss->eap_teap_id = atoi(pos);
+       } else if (os_strcmp(buf, "eap_teap_method_sequence") == 0) {
+               bss->eap_teap_method_sequence = atoi(pos);
 #endif /* EAP_SERVER_TEAP */
 #ifdef EAP_SERVER_SIM
        } else if (os_strcmp(buf, "eap_sim_db") == 0) {
index 01abd585e614097094f1bf96a673064ea9a1d9e9..427a49e0c174cb3934c235c533ac9c3096c1088b 100644 (file)
@@ -1412,6 +1412,12 @@ eap_server=0
 # 5 = require both user and machine identity
 #eap_teap_id=0
 
+# EAP-TEAP tunneled EAP method behavior
+# 0 = minimize roundtrips by merging start of the next EAP method with the
+#     crypto-binding of the previous one.
+# 1 = complete crypto-binding before starting the next EAP method
+#eap_teap_method_sequence=0
+
 # EAP-SIM and EAP-AKA protected success/failure indication using AT_RESULT_IND
 # (default: 0 = disabled).
 #eap_sim_aka_result_ind=1
index 330c9ed659ee2115c4962d9561ab110f13a66bce..98ed81a9845edb742ad685eda8922a0d29ff1088 100644 (file)
@@ -443,6 +443,7 @@ struct hostapd_bss_config {
        int eap_teap_pac_no_inner;
        int eap_teap_separate_result;
        int eap_teap_id;
+       int eap_teap_method_sequence;
        int eap_sim_aka_result_ind;
        int eap_sim_id;
        char *imsi_privacy_key;
index fd9c96fadc82b2f1ecdda8b63d7c687e4ce6215b..4ab2a4a6019947e965589b2a991ed555f51fc6f2 100644 (file)
@@ -211,6 +211,7 @@ static struct eap_config * authsrv_eap_config(struct hostapd_data *hapd)
        cfg->eap_teap_pac_no_inner = hapd->conf->eap_teap_pac_no_inner;
        cfg->eap_teap_separate_result = hapd->conf->eap_teap_separate_result;
        cfg->eap_teap_id = hapd->conf->eap_teap_id;
+       cfg->eap_teap_method_sequence = hapd->conf->eap_teap_method_sequence;
        cfg->eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind;
        cfg->eap_sim_id = hapd->conf->eap_sim_id;
        cfg->imsi_privacy_key = hapd->imsi_privacy_key;
index 2894cfbfeefbaab6a584e00b6d2b295d1aaeb3a9..3696e1d27cabd25756b61bb287d55bbe4a7fe1a6 100644 (file)
@@ -209,6 +209,7 @@ struct eap_config {
                EAP_TEAP_ID_REQUEST_MACHINE_ACCEPT_USER = 4,
                EAP_TEAP_ID_REQUIRE_USER_AND_MACHINE = 5,
        } eap_teap_id;
+       int eap_teap_method_sequence;
 
        /**
         * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication
index 1e5e9a562e132e998c9cd8af4ec5fc5aec8dca37..e32c6e48c523c9d374f84cf1041ffad780b0916e 100644 (file)
@@ -74,11 +74,15 @@ struct eap_teap_data {
 
        enum teap_error_codes error_code;
        enum teap_identity_types cur_id_type;
+
+       bool check_crypto_binding;
 };
 
 
 static int eap_teap_process_phase2_start(struct eap_sm *sm,
                                         struct eap_teap_data *data);
+static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data,
+                               int vendor, enum eap_type eap_type);
 
 
 static const char * eap_teap_state_txt(int state)
@@ -704,6 +708,8 @@ static struct wpabuf * eap_teap_build_crypto_binding(
        wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
                    cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
 
+       data->check_crypto_binding = true;
+
        return buf;
 }
 
@@ -889,6 +895,7 @@ static struct wpabuf * eap_teap_buildReq(struct eap_sm *sm, void *priv, u8 id)
        struct eap_teap_data *data = priv;
        struct wpabuf *req = NULL;
        int piggyback = 0;
+       bool move_to_method = true;
 
        if (data->ssl.state == FRAG_ACK) {
                return eap_server_tls_build_ack(id, EAP_TYPE_TEAP,
@@ -940,6 +947,21 @@ static struct wpabuf * eap_teap_buildReq(struct eap_sm *sm, void *priv, u8 id)
                break;
        case CRYPTO_BINDING:
                req = eap_teap_build_crypto_binding(sm, data);
+               if (req && sm->cfg->eap_teap_auth == 0 &&
+                   data->inner_eap_not_done &&
+                   !data->phase2_method &&
+                   sm->cfg->eap_teap_method_sequence == 0) {
+                       wpa_printf(MSG_DEBUG,
+                                  "EAP-TEAP: Continue with inner EAP authentication for second credential (optimized)");
+                       eap_teap_state(data, PHASE2_ID);
+                       if (eap_teap_phase2_init(sm, data, EAP_VENDOR_IETF,
+                                                EAP_TYPE_IDENTITY) < 0) {
+                               eap_teap_state(data, FAILURE);
+                               wpabuf_free(req);
+                               return NULL;
+                       }
+                       move_to_method = false;
+               }
                if (data->phase2_method) {
                        /*
                         * Include the start of the next EAP method in the
@@ -950,7 +972,8 @@ static struct wpabuf * eap_teap_buildReq(struct eap_sm *sm, void *priv, u8 id)
 
                        eap = eap_teap_build_phase2_req(sm, data, id);
                        req = wpabuf_concat(req, eap);
-                       eap_teap_state(data, PHASE2_METHOD);
+                       if (move_to_method)
+                               eap_teap_state(data, PHASE2_METHOD);
                }
                break;
        case REQUEST_PAC:
@@ -1510,7 +1533,8 @@ static void eap_teap_process_phase2_tlvs(struct eap_sm *sm,
                                         struct wpabuf *in_data)
 {
        struct eap_teap_tlv_parse tlv;
-       int check_crypto_binding = data->state == CRYPTO_BINDING;
+       bool check_crypto_binding = data->state == CRYPTO_BINDING ||
+               data->check_crypto_binding;
 
        if (eap_teap_parse_tlvs(in_data, &tlv) < 0) {
                wpa_printf(MSG_DEBUG,
@@ -1593,6 +1617,7 @@ static void eap_teap_process_phase2_tlvs(struct eap_sm *sm,
 
                wpa_printf(MSG_DEBUG,
                           "EAP-TEAP: Valid Crypto-Binding TLV received");
+               data->check_crypto_binding = false;
                if (data->final_result) {
                        wpa_printf(MSG_DEBUG,
                                   "EAP-TEAP: Authentication completed successfully");
@@ -1671,7 +1696,8 @@ static void eap_teap_process_phase2_tlvs(struct eap_sm *sm,
                           "EAP-TEAP: Continue with basic password authentication for second credential");
                eap_teap_state(data, PHASE2_BASIC_AUTH);
        } else if (check_crypto_binding && data->state == CRYPTO_BINDING &&
-                  sm->cfg->eap_teap_auth == 0 && data->inner_eap_not_done) {
+                  sm->cfg->eap_teap_auth == 0 && data->inner_eap_not_done &&
+                  sm->cfg->eap_teap_method_sequence == 1) {
                wpa_printf(MSG_DEBUG,
                           "EAP-TEAP: Continue with inner EAP authentication for second credential");
                eap_teap_state(data, PHASE2_ID);