]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
ERP: Drop ERP keys on failure on the peer
authorJouni Malinen <j@w1.fi>
Sun, 14 Dec 2014 11:51:55 +0000 (13:51 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 14 Dec 2014 13:47:04 +0000 (15:47 +0200)
This allows recovery through fallback to full EAP authentication if the
server rejects us, e.g., due to having dropped ERP state.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/eap_peer/eap.c

index 4b6b1eb5137837093bb5223fe11ba446bba529be..31c1a29c679a95023383f766ae04bd63ccda4c87 100644 (file)
@@ -1569,6 +1569,7 @@ static void eap_peer_finish(struct eap_sm *sm, const struct eap_hdr *hdr,
        int max_len;
        char nai[254];
        u8 seed[4];
+       int auth_tag_ok = 0;
 
        if (len < sizeof(*hdr) + 1) {
                wpa_printf(MSG_DEBUG, "EAP: Ignored too short EAP-Finish");
@@ -1638,10 +1639,14 @@ static void eap_peer_finish(struct eap_sm *sm, const struct eap_hdr *hdr,
        if (max_len < 1 + (int) hash_len) {
                wpa_printf(MSG_DEBUG,
                           "EAP: Not enough room for Authentication Tag");
+               if (flags & 0x80)
+                       goto no_auth_tag;
                return;
        }
        if (end[-17] != EAP_ERP_CS_HMAC_SHA256_128) {
                wpa_printf(MSG_DEBUG, "EAP: Different Cryptosuite used");
+               if (flags & 0x80)
+                       goto no_auth_tag;
                return;
        }
 
@@ -1653,8 +1658,10 @@ static void eap_peer_finish(struct eap_sm *sm, const struct eap_hdr *hdr,
                           "EAP: Authentication Tag mismatch");
                return;
        }
+       auth_tag_ok = 1;
        end -= 1 + hash_len;
 
+no_auth_tag:
        /*
         * Parse TVs/TLVs again now that we know the exact part of the buffer
         * that contains them.
@@ -1664,7 +1671,7 @@ static void eap_peer_finish(struct eap_sm *sm, const struct eap_hdr *hdr,
        if (erp_parse_tlvs(pos, end, &parse, 0) < 0)
                return;
 
-       if (flags & 0x80) {
+       if (flags & 0x80 || !auth_tag_ok) {
                wpa_printf(MSG_DEBUG,
                           "EAP: EAP-Finish/Re-auth indicated failure");
                eapol_set_bool(sm, EAPOL_eapFail, TRUE);
@@ -1673,6 +1680,9 @@ static void eap_peer_finish(struct eap_sm *sm, const struct eap_hdr *hdr,
                wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
                        "EAP authentication failed");
                sm->prev_failure = 1;
+               wpa_printf(MSG_DEBUG,
+                          "EAP: Drop ERP key to try full authentication on next attempt");
+               eap_peer_erp_free_key(erp);
                return;
        }