EAP-FAST: Added shared helper functions for building TLVs
authorJouni Malinen <j@w1.fi>
Thu, 28 Feb 2008 01:56:30 +0000 (17:56 -0800)
committerJouni Malinen <j@w1.fi>
Thu, 28 Feb 2008 01:56:30 +0000 (17:56 -0800)
hostapd/Makefile
src/eap_common/eap_fast_common.c [new file with mode: 0644]
src/eap_common/eap_fast_common.h
src/eap_peer/eap_fast.c
src/eap_server/eap_fast.c
wpa_supplicant/Makefile

index 123b098..c0b68e0 100644 (file)
@@ -246,6 +246,7 @@ endif
 ifdef CONFIG_EAP_FAST
 CFLAGS += -DEAP_FAST
 OBJS += ../src/eap_server/eap_fast.o
+OBJS += ../src/eap_common/eap_fast_common.o
 TLS_FUNCS=y
 NEED_T_PRF=y
 endif
diff --git a/src/eap_common/eap_fast_common.c b/src/eap_common/eap_fast_common.c
new file mode 100644 (file)
index 0000000..039c40e
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * EAP-FAST common helper functions (RFC 4851)
+ * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "eap_fast_common.h"
+
+
+void eap_fast_put_tlv_hdr(struct wpabuf *buf, u16 type, u16 len)
+{
+       struct pac_tlv_hdr hdr;
+       hdr.type = host_to_be16(type);
+       hdr.len = host_to_be16(len);
+       wpabuf_put_data(buf, &hdr, sizeof(hdr));
+}
+
+
+void eap_fast_put_tlv(struct wpabuf *buf, u16 type, const void *data,
+                            u16 len)
+{
+       eap_fast_put_tlv_hdr(buf, type, len);
+       wpabuf_put_data(buf, data, len);
+}
+
+
+void eap_fast_put_tlv_buf(struct wpabuf *buf, u16 type,
+                                const struct wpabuf *data)
+{
+       eap_fast_put_tlv_hdr(buf, type, wpabuf_len(data));
+       wpabuf_put_buf(buf, data);
+}
index 5d821da..e69b7a0 100644 (file)
@@ -82,4 +82,13 @@ struct eap_fast_key_block_provisioning {
        u8 client_challenge[16]; /* MSCHAPv2 ClientChallenge */
 };
 
+
+struct wpabuf;
+
+void eap_fast_put_tlv_hdr(struct wpabuf *buf, u16 type, u16 len);
+void eap_fast_put_tlv(struct wpabuf *buf, u16 type, const void *data,
+                     u16 len);
+void eap_fast_put_tlv_buf(struct wpabuf *buf, u16 type,
+                         const struct wpabuf *data);
+
 #endif /* EAP_FAST_H */
index caca89e..0d2e28c 100644 (file)
@@ -599,24 +599,21 @@ static struct wpabuf * eap_fast_tlv_pac_ack(void)
 static struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf)
 {
        struct wpabuf *msg;
-       struct eap_tlv_hdr *tlv;
 
        if (buf == NULL)
                return NULL;
 
        /* Encapsulate EAP packet in EAP Payload TLV */
-       msg = wpabuf_alloc(sizeof(*tlv) + wpabuf_len(buf));
+       msg = wpabuf_alloc(sizeof(struct pac_tlv_hdr) + wpabuf_len(buf));
        if (msg == NULL) {
                wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory "
                           "for TLV encapsulation");
                wpabuf_free(buf);
                return NULL;
        }
-       tlv = wpabuf_put(msg, sizeof(*tlv));
-       tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
-                                    EAP_TLV_EAP_PAYLOAD_TLV);
-       tlv->length = host_to_be16(wpabuf_len(buf));
-       wpabuf_put_buf(msg, buf);
+       eap_fast_put_tlv_buf(msg,
+                            EAP_TLV_TYPE_MANDATORY | EAP_TLV_EAP_PAYLOAD_TLV,
+                            buf);
        wpabuf_free(buf);
        return msg;
 }
index 390637b..7fd41f9 100644 (file)
@@ -546,11 +546,10 @@ static struct wpabuf * eap_fast_build_start(struct eap_sm *sm,
                                            struct eap_fast_data *data, u8 id)
 {
        struct wpabuf *req;
-       struct pac_tlv_hdr *a_id;
        size_t srv_id_len = os_strlen(data->srv_id);
 
        req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_FAST,
-                           1 + sizeof(*a_id) + srv_id_len,
+                           1 + sizeof(struct pac_tlv_hdr) + srv_id_len,
                            EAP_CODE_REQUEST, id);
        if (req == NULL) {
                wpa_printf(MSG_ERROR, "EAP-FAST: Failed to allocate memory for"
@@ -560,10 +559,9 @@ static struct wpabuf * eap_fast_build_start(struct eap_sm *sm,
        }
 
        wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->fast_version);
-       a_id = wpabuf_put(req, sizeof(*a_id));
-       a_id->type = host_to_be16(PAC_TYPE_A_ID);
-       a_id->len = host_to_be16(srv_id_len);
-       wpabuf_put_data(req, data->srv_id, srv_id_len);
+
+       /* RFC 4851, 4.1.1. Authority ID Data */
+       eap_fast_put_tlv(req, PAC_TYPE_A_ID, data->srv_id, srv_id_len);
 
        eap_fast_state(data, PHASE1);
 
@@ -658,25 +656,22 @@ static struct wpabuf * eap_fast_encrypt(struct eap_sm *sm,
 static struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf)
 {
        struct wpabuf *e;
-       struct eap_tlv_hdr *tlv;
 
        if (buf == NULL)
                return NULL;
 
        /* Encapsulate EAP packet in EAP-Payload TLV */
        wpa_printf(MSG_DEBUG, "EAP-FAST: Add EAP-Payload TLV");
-       e = wpabuf_alloc(sizeof(*tlv) + wpabuf_len(buf));
+       e = wpabuf_alloc(sizeof(struct pac_tlv_hdr) + wpabuf_len(buf));
        if (e == NULL) {
                wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory "
                           "for TLV encapsulation");
                wpabuf_free(buf);
                return NULL;
        }
-       tlv = wpabuf_put(e, sizeof(*tlv));
-       tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
-                                    EAP_TLV_EAP_PAYLOAD_TLV);
-       tlv->length = host_to_be16(wpabuf_len(buf));
-       wpabuf_put_buf(e, buf);
+       eap_fast_put_tlv_buf(e,
+                            EAP_TLV_TYPE_MANDATORY | EAP_TLV_EAP_PAYLOAD_TLV,
+                            buf);
        wpabuf_free(buf);
        return e;
 }
@@ -783,7 +778,7 @@ static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm,
        u8 *pos;
        size_t buf_len, srv_id_len, pac_len;
        struct eap_tlv_hdr *pac_tlv;
-       struct pac_tlv_hdr *hdr, *pac_info;
+       struct pac_tlv_hdr *pac_info;
        struct eap_tlv_result_tlv *result;
        struct os_time now;
 
@@ -843,8 +838,8 @@ static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm,
                    pac_opaque, pac_len);
 
        buf_len = sizeof(*pac_tlv) +
-               sizeof(*hdr) + EAP_FAST_PAC_KEY_LEN +
-               sizeof(*hdr) + pac_len +
+               sizeof(struct pac_tlv_hdr) + EAP_FAST_PAC_KEY_LEN +
+               sizeof(struct pac_tlv_hdr) + pac_len +
                2 * srv_id_len + 100 + sizeof(*result);
        buf = wpabuf_alloc(buf_len);
        if (buf == NULL) {
@@ -859,16 +854,10 @@ static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm,
                                         EAP_TLV_PAC_TLV);
 
        /* PAC-Key */
-       hdr = wpabuf_put(buf, sizeof(*hdr));
-       hdr->type = host_to_be16(PAC_TYPE_PAC_KEY);
-       hdr->len = host_to_be16(EAP_FAST_PAC_KEY_LEN);
-       wpabuf_put_data(buf, pac_key, EAP_FAST_PAC_KEY_LEN);
+       eap_fast_put_tlv(buf, PAC_TYPE_PAC_KEY, pac_key, EAP_FAST_PAC_KEY_LEN);
 
        /* PAC-Opaque */
-       hdr = wpabuf_put(buf, sizeof(*hdr));
-       hdr->type = host_to_be16(PAC_TYPE_PAC_OPAQUE);
-       hdr->len = host_to_be16(pac_len);
-       wpabuf_put_data(buf, pac_opaque, pac_len);
+       eap_fast_put_tlv(buf, PAC_TYPE_PAC_OPAQUE, pac_opaque, pac_len);
        os_free(pac_opaque);
 
        /* PAC-Info */
@@ -876,29 +865,19 @@ static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm,
        pac_info->type = host_to_be16(PAC_TYPE_PAC_INFO);
 
        /* PAC-Lifetime (inside PAC-Info) */
-       hdr = wpabuf_put(buf, sizeof(*hdr));
-       hdr->type = host_to_be16(PAC_TYPE_CRED_LIFETIME);
-       hdr->len = host_to_be16(4);
+       eap_fast_put_tlv_hdr(buf, PAC_TYPE_CRED_LIFETIME, 4);
        wpabuf_put_be32(buf, now.sec + PAC_KEY_LIFETIME);
 
        /* A-ID (inside PAC-Info) */
-       hdr = wpabuf_put(buf, sizeof(*hdr));
-       hdr->type = host_to_be16(PAC_TYPE_A_ID);
-       hdr->len = host_to_be16(srv_id_len);
-       wpabuf_put_data(buf, data->srv_id, srv_id_len);
+       eap_fast_put_tlv(buf, PAC_TYPE_A_ID, data->srv_id, srv_id_len);
        
        /* Note: headers may be misaligned after A-ID */
 
        /* A-ID-Info (inside PAC-Info) */
-       hdr = wpabuf_put(buf, sizeof(*hdr));
-       WPA_PUT_BE16((u8 *) &hdr->type, PAC_TYPE_A_ID_INFO);
-       WPA_PUT_BE16((u8 *) &hdr->len, srv_id_len);
-       wpabuf_put_data(buf, data->srv_id, srv_id_len);
+       eap_fast_put_tlv(buf, PAC_TYPE_A_ID_INFO, data->srv_id, srv_id_len);
 
        /* PAC-Type (inside PAC-Info) */
-       hdr = wpabuf_put(buf, sizeof(*hdr));
-       WPA_PUT_BE16((u8 *) &hdr->type, PAC_TYPE_PAC_TYPE);
-       WPA_PUT_BE16((u8 *) &hdr->len, 2);
+       eap_fast_put_tlv_hdr(buf, PAC_TYPE_PAC_TYPE, 2);
        wpabuf_put_be16(buf, PAC_TYPE_TUNNEL_PAC);
 
        /* Update PAC-Info and PAC TLV Length fields */
index de1a56f..41874e0 100644 (file)
@@ -423,9 +423,11 @@ ifdef CONFIG_EAP_FAST
 ifeq ($(CONFIG_EAP_FAST), dyn)
 CFLAGS += -DEAP_FAST_DYNAMIC
 EAPDYN += ../src/eap_peer/eap_fast.so
+EAPDYN += ../src/eap_common/eap_fast_common.o
 else
 CFLAGS += -DEAP_FAST
 OBJS += ../src/eap_peer/eap_fast.o ../src/eap_peer/eap_fast_pac.o
+OBJS += ../src/eap_common/eap_fast_common.o
 OBJS_h += ../src/eap_server/eap_fast.o
 endif
 TLS_FUNCS=y