Key Server support for Group CAs

Greg Goblirsch gregg at thinklogical.com
Wed Apr 20 11:16:13 PDT 2022


Signed-off-by: Greg Goblirsch <gregg at thinklogical.com>

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index a1f8ae934..c9441b394 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -1159,10 +1159,9 @@ static int ieee802_1x_mka_decode_live_peer_body(
                        continue;
 
                peer = ieee802_1x_kay_get_peer(participant, peer_mi->mi);
-               if (peer) {
-                       peer->mn = peer_mn;
-               } else if (!ieee802_1x_kay_create_potential_peer(
-                               participant, peer_mi->mi, peer_mn)) {
+               if (!peer) {
+                       if (!ieee802_1x_kay_create_potential_peer(
+                               participant, peer_mi->mi, peer_mn))
                        return -1;
                }
        }
@@ -1737,6 +1736,12 @@ ieee802_1x_mka_decode_dist_sak_body(
                return -1;
        }
 
+       if (!dl_list_empty(&participant->potential_peers)) {
+               wpa_printf(MSG_ERROR,
+                       "KaY: I can't accept the distributed SAK as potential peer list is not empty");
+               return -1;
+       }
+
        if (body_len == 0) {
                kay->authenticated = true;
                kay->secured = false;
@@ -2142,15 +2147,13 @@ ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
                return -1;
        }
 
-       /* FIXME: A fresh SAK not generated until
+       /* A fresh SAK not generated until
         * the live peer list contains at least one peer and
         * MKA life time has elapsed since the prior SAK was first distributed,
         * or the Key server's potential peer is empty
-        * but I can't understand the second item, so
-        * here only check first item and ingore
-        *   && (!dl_list_empty(&participant->potential_peers))) {
         */
-       if ((time(NULL) - kay->dist_time) < MKA_LIFE_TIME / 1000) {
+       if (((time(NULL) - kay->dist_time) < MKA_LIFE_TIME / 1000) &&
+           (!dl_list_empty(&participant->potential_peers))) {
                wpa_printf(MSG_ERROR,
                           "KaY: Life time has not elapsed since prior SAK distributed");
                return -1;
@@ -2290,9 +2293,6 @@ ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
        /* elect the key server among the peers */
        dl_list_for_each(peer, &participant->live_peers,
                         struct ieee802_1x_kay_peer, list) {
-               if (!peer->is_key_server)
-                       continue;
-
                if (!key_server) {
                        key_server = peer;
                        continue;
@@ -2645,10 +2645,10 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
        }
 
        if (participant->new_sak && participant->is_key_server) {
-               if (!ieee802_1x_kay_generate_new_sak(participant))
+               if (!ieee802_1x_kay_generate_new_sak(participant)) {
                        participant->to_dist_sak = true;
-
-               participant->new_sak = false;
+                       participant->new_sak = false;
+        }
        }
 
        if (participant->retry_count < MAX_RETRY_CNT ||
@@ -3217,8 +3217,6 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
        int i;
        const u8 *pos;
        bool handled[256];
-       bool bad_sak_use = false; /* Error detected while processing SAK Use
-                                  * parameter set */
        bool i_in_peerlist, is_in_live_peer, is_in_potential_peer;
 
        wpa_printf(MSG_DEBUG, "KaY: Decode received MKPDU (ifname=%s)",
@@ -3310,22 +3308,10 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
                        if (mka_body_handler[body_type].body_rx
                                (participant, pos, left_len) != 0) {
                                /* Handle parameter set failure */
-                               if (body_type != MKA_SAK_USE) {
-                                       wpa_printf(MSG_INFO,
-                                                  "KaY: Discarding Rx MKPDU: decode of parameter set type (%d) failed",
-                                                  body_type);
-                                       return -1;
-                               }
-
-                               /* Ideally DIST-SAK should be processed before
-                                * SAK-USE. Unfortunately IEEE Std 802.1X-2010,
-                                * 11.11.3 (Encoding MKPDUs) states SAK-USE(3)
-                                * must always be encoded before DIST-SAK(4).
-                                * Rather than redesigning mka_body_handler so
-                                * that it somehow processes DIST-SAK before
-                                * SAK-USE, just ignore SAK-USE failures if
-                                * DIST-SAK is also present in this MKPDU. */
-                               bad_sak_use = true;
+                               wpa_printf(MSG_INFO,
+                                          "KaY: Discarding Rx MKPDU: decode of parameter set type (%d) failed",
+                                          body_type);
+                               return -1;
                        }
                } else {
                        wpa_printf(MSG_ERROR,
@@ -3334,19 +3320,6 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
                }
        }
 
-       if (bad_sak_use && !handled[MKA_DISTRIBUTED_SAK]) {
-               wpa_printf(MSG_INFO,
-                          "KaY: Discarding Rx MKPDU: decode of parameter set type (%d) failed",
-                          MKA_SAK_USE);
-               if (!reset_participant_mi(participant))
-                       wpa_printf(MSG_DEBUG, "KaY: Could not update mi");
-               else
-                       wpa_printf(MSG_DEBUG,
-                                  "KaY: Selected a new random MI: %s",
-                                  mi_txt(participant->mi));
-               return -1;
-       }
-
        /* Detect missing parameter sets */
        peer = ieee802_1x_kay_get_live_peer(participant,
                                            participant->current_peer_id.mi);
@@ -3773,21 +3746,28 @@ ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay,
 
        dl_list_add(&kay->participant_list, &participant->list);
 
-       usecs = os_random() % (kay->mka_hello_time * 1000);
-       eloop_register_timeout(0, usecs, ieee802_1x_participant_timer,
-                              participant, NULL);
-
        /* Disable MKA lifetime for PSK mode.
         * The peer(s) can take a long time to come up, because we
         * create a "standby" MKA, and we need it to remain live until
         * some peer appears.
         */
        if (mode != PSK) {
+               usecs = os_random() % (kay->mka_hello_time * 1000);
                participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) +
                        usecs / 1000000;
        }
        participant->mode = mode;
 
+       if (participant->retry_count < MAX_RETRY_CNT ||
+           participant->mode == PSK) {
+               ieee802_1x_participant_send_mkpdu(participant);
+               participant->retry_count++;
+       }
+
+       eloop_register_timeout(kay->mka_hello_time / 1000, 0,
+                              ieee802_1x_participant_timer,
+                              participant, NULL);
+
        return participant;
 
 fail:




More information about the Hostap mailing list