]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
RADIUS: Allow Message-Authenticator attribute as the first attribute
authorJouni Malinen <j@w1.fi>
Sat, 16 Mar 2024 09:11:44 +0000 (11:11 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 9 Jul 2024 11:58:39 +0000 (14:58 +0300)
If a Message-Authenticator attribute was already added to a RADIUS
message, use that attribute instead of adding a new one when finishing
message building. This allows the Message-Authenticator attribute to be
placed as the first attribute in the message.

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

index be59a94a941edf2dacc9d23ad2e243956dcd5c33..a7a137a98b9f2d71419f6c338203526dacc8251d 100644 (file)
@@ -423,25 +423,54 @@ void radius_msg_dump(struct radius_msg *msg)
 }
 
 
+u8 * radius_msg_add_msg_auth(struct radius_msg *msg)
+{
+       u8 auth[MD5_MAC_LEN];
+       struct radius_attr_hdr *attr;
+
+       os_memset(auth, 0, MD5_MAC_LEN);
+       attr = radius_msg_add_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
+                                  auth, MD5_MAC_LEN);
+       if (!attr) {
+               wpa_printf(MSG_ERROR,
+                          "WARNING: Could not add Message-Authenticator");
+               return NULL;
+       }
+
+       return (u8 *) (attr + 1);
+}
+
+
+static u8 * radius_msg_auth_pos(struct radius_msg *msg)
+{
+       u8 *pos;
+       size_t alen;
+
+       if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
+                                   &pos, &alen, NULL) == 0 &&
+           alen == MD5_MAC_LEN) {
+               /* Use already added Message-Authenticator attribute */
+               return pos;
+       }
+
+       /* Add a Message-Authenticator attribute */
+       return radius_msg_add_msg_auth(msg);
+}
+
+
 int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
                      size_t secret_len)
 {
        if (secret) {
-               u8 auth[MD5_MAC_LEN];
-               struct radius_attr_hdr *attr;
-
-               os_memset(auth, 0, MD5_MAC_LEN);
-               attr = radius_msg_add_attr(msg,
-                                          RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
-                                          auth, MD5_MAC_LEN);
-               if (attr == NULL) {
-                       wpa_printf(MSG_WARNING, "RADIUS: Could not add "
-                                  "Message-Authenticator");
+               u8 *pos;
+
+               pos = radius_msg_auth_pos(msg);
+               if (!pos)
                        return -1;
-               }
                msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
-               hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
-                        wpabuf_len(msg->buf), (u8 *) (attr + 1));
+               if (hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
+                            wpabuf_len(msg->buf), pos) < 0)
+                       return -1;
        } else
                msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
 
@@ -457,23 +486,19 @@ int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
 int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
                          size_t secret_len, const u8 *req_authenticator)
 {
-       u8 auth[MD5_MAC_LEN];
-       struct radius_attr_hdr *attr;
        const u8 *addr[4];
        size_t len[4];
+       u8 *pos;
 
-       os_memset(auth, 0, MD5_MAC_LEN);
-       attr = radius_msg_add_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
-                                  auth, MD5_MAC_LEN);
-       if (attr == NULL) {
-               wpa_printf(MSG_ERROR, "WARNING: Could not add Message-Authenticator");
+       pos = radius_msg_auth_pos(msg);
+       if (!pos)
                return -1;
-       }
        msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
        os_memcpy(msg->hdr->authenticator, req_authenticator,
                  sizeof(msg->hdr->authenticator));
-       hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
-                wpabuf_len(msg->buf), (u8 *) (attr + 1));
+       if (hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
+                    wpabuf_len(msg->buf), pos) < 0)
+               return -1;
 
        /* ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret) */
        addr[0] = (u8 *) msg->hdr;
@@ -501,21 +526,17 @@ int radius_msg_finish_das_resp(struct radius_msg *msg, const u8 *secret,
 {
        const u8 *addr[2];
        size_t len[2];
-       u8 auth[MD5_MAC_LEN];
-       struct radius_attr_hdr *attr;
+       u8 *pos;
 
-       os_memset(auth, 0, MD5_MAC_LEN);
-       attr = radius_msg_add_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
-                                  auth, MD5_MAC_LEN);
-       if (attr == NULL) {
-               wpa_printf(MSG_WARNING, "Could not add Message-Authenticator");
+       pos = radius_msg_auth_pos(msg);
+       if (!pos)
                return -1;
-       }
 
        msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
        os_memcpy(msg->hdr->authenticator, req_hdr->authenticator, 16);
-       hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
-                wpabuf_len(msg->buf), (u8 *) (attr + 1));
+       if (hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
+                    wpabuf_len(msg->buf), pos) < 0)
+               return -1;
 
        /* ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret) */
        addr[0] = wpabuf_head_u8(msg->buf);
index 571c15923d29fa2fe111fe77710e9a309913886a..05fddbaf25bf4cbd3e974c97ba1b64cc415c3b6e 100644 (file)
@@ -268,6 +268,7 @@ struct wpabuf * radius_msg_get_buf(struct radius_msg *msg);
 struct radius_msg * radius_msg_new(u8 code, u8 identifier);
 void radius_msg_free(struct radius_msg *msg);
 void radius_msg_dump(struct radius_msg *msg);
+u8 * radius_msg_add_msg_auth(struct radius_msg *msg);
 int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
                      size_t secret_len);
 int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,