]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Protocol testing framework
authorJouni Malinen <jouni@qca.qualcomm.com>
Sun, 22 Oct 2017 08:15:21 +0000 (11:15 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 22 Oct 2017 14:21:57 +0000 (17:21 +0300)
Add a generic mechanism for configuring the DPP implementation to behave
in particular different (mostly incorrect) ways for protocol testing
purposes. The new dpp_test parameter can be set to a non-zero integer to
indicate a specific behavior. This is only available in
CONFIG_TESTING_OPTIONS=y builds.

This commit include cases for an extra attribute being added after the
Wrapped Data attribute and Initiator/Responder capabilities having an
unexpected zero capability.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
hostapd/ctrl_iface.c
src/common/dpp.c
src/common/dpp.h
wpa_supplicant/ctrl_iface.c

index b3ef8d34a63970d499803c7407d2450480547f3f..af2a2821bce090d238054609f927076937577455 100644 (file)
@@ -29,6 +29,7 @@
 #include "common/version.h"
 #include "common/ieee802_11_defs.h"
 #include "common/ctrl_iface_common.h"
+#include "common/dpp.h"
 #include "crypto/tls.h"
 #include "drivers/driver.h"
 #include "eapol_auth/eapol_auth_sm.h"
@@ -1301,6 +1302,8 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
        } else if (os_strcasecmp(cmd,
                                 "dpp_ignore_netaccesskey_mismatch") == 0) {
                hapd->dpp_ignore_netaccesskey_mismatch = atoi(value);
+       } else if (os_strcasecmp(cmd, "dpp_test") == 0) {
+               dpp_test = atoi(value);
 #endif /* CONFIG_DPP */
 #endif /* CONFIG_TESTING_OPTIONS */
 #ifdef CONFIG_MBO
@@ -3508,6 +3511,13 @@ static void hostapd_ctrl_iface_flush(struct hapd_interfaces *interfaces)
        wps_testing_dummy_cred = 0;
        wps_corrupt_pkhash = 0;
 #endif /* CONFIG_WPS_TESTING */
+
+#ifdef CONFIG_TESTING_OPTIONS
+#ifdef CONFIG_DPP
+       dpp_test = DPP_TEST_DISABLED;
+#endif /* CONFIG_DPP */
+#endif /* CONFIG_TESTING_OPTIONS */
+
 }
 
 
index 51079506bc594bdd660c7dcd76a8459c93209f2d..fa98db2f38383b233d346248d230470074963c22 100644 (file)
 #include "dpp.h"
 
 
+#ifdef CONFIG_TESTING_OPTIONS
+enum dpp_test_behavior dpp_test = DPP_TEST_DISABLED;
+#endif /* CONFIG_TESTING_OPTIONS */
+
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
 /* Compatibility wrappers for older versions. */
 
@@ -1396,6 +1400,10 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
        /* Build DPP Authentication Request frame attributes */
        attr_len = 2 * (4 + SHA256_MAC_LEN) + 4 + wpabuf_len(pi) +
                4 + sizeof(wrapped_data);
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_REQ)
+               attr_len += 4;
+#endif /* CONFIG_TESTING_OPTIONS */
        msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_REQ, attr_len);
        if (!msg)
                goto fail;
@@ -1440,6 +1448,12 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
        auth->i_capab = configurator ? DPP_CAPAB_CONFIGURATOR :
                DPP_CAPAB_ENROLLEE;
        *pos++ = auth->i_capab;
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_ZERO_I_CAPAB) {
+               wpa_printf(MSG_INFO, "DPP: TESTING - zero I-capabilities");
+               pos[-1] = 0;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
 
        attr_end = wpabuf_put(msg, 0);
 
@@ -1466,6 +1480,14 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
        wpabuf_put_le16(msg, siv_len);
        wpabuf_put_data(msg, wrapped_data, siv_len);
 
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_REQ) {
+               wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
+               wpabuf_put_le16(msg, DPP_ATTR_TESTING);
+               wpabuf_put_le16(msg, 0);
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
        wpa_hexdump_buf(MSG_DEBUG,
                        "DPP: Authentication Request frame attributes", msg);
 
@@ -1485,6 +1507,7 @@ struct wpabuf * dpp_build_conf_req(struct dpp_authentication *auth,
        size_t json_len, clear_len;
        struct wpabuf *clear = NULL, *msg = NULL;
        u8 *wrapped;
+       size_t attr_len;
 
        wpa_printf(MSG_DEBUG, "DPP: Build configuration request");
 
@@ -1500,7 +1523,12 @@ struct wpabuf * dpp_build_conf_req(struct dpp_authentication *auth,
        /* { E-nonce, configAttrib }ke */
        clear_len = 4 + nonce_len + 4 + json_len;
        clear = wpabuf_alloc(clear_len);
-       msg = wpabuf_alloc(4 + clear_len + AES_BLOCK_SIZE);
+       attr_len = 4 + clear_len + AES_BLOCK_SIZE;
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_CONF_REQ)
+               attr_len += 4;
+#endif /* CONFIG_TESTING_OPTIONS */
+       msg = wpabuf_alloc(attr_len);
        if (!clear || !msg)
                goto fail;
 
@@ -1527,6 +1555,14 @@ struct wpabuf * dpp_build_conf_req(struct dpp_authentication *auth,
        wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
                    wrapped, wpabuf_len(clear) + AES_BLOCK_SIZE);
 
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_CONF_REQ) {
+               wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
+               wpabuf_put_le16(msg, DPP_ATTR_TESTING);
+               wpabuf_put_le16(msg, 0);
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
        wpa_hexdump_buf(MSG_DEBUG,
                        "DPP: Configuration Request frame attributes", msg);
        wpabuf_free(clear);
@@ -1940,6 +1976,10 @@ static int dpp_auth_build_resp(struct dpp_authentication *auth)
        /* Build DPP Authentication Response frame attributes */
        attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
                4 + wpabuf_len(pr) + 4 + sizeof(wrapped_data);
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP)
+               attr_len += 4;
+#endif /* CONFIG_TESTING_OPTIONS */
        msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len);
        if (!msg)
                goto fail;
@@ -2000,6 +2040,12 @@ static int dpp_auth_build_resp(struct dpp_authentication *auth)
        auth->r_capab = auth->configurator ? DPP_CAPAB_CONFIGURATOR :
                DPP_CAPAB_ENROLLEE;
        *pos++ = auth->r_capab;
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_ZERO_R_CAPAB) {
+               wpa_printf(MSG_INFO, "DPP: TESTING - zero R-capabilities");
+               pos[-1] = 0;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
        /* {R-auth}ke */
        WPA_PUT_LE16(pos, DPP_ATTR_WRAPPED_DATA);
        pos += 2;
@@ -2031,6 +2077,14 @@ static int dpp_auth_build_resp(struct dpp_authentication *auth)
        wpabuf_put_le16(msg, siv_len);
        wpabuf_put_data(msg, wrapped_data, siv_len);
 
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP) {
+               wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
+               wpabuf_put_le16(msg, DPP_ATTR_TESTING);
+               wpabuf_put_le16(msg, 0);
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
        wpa_hexdump_buf(MSG_DEBUG,
                        "DPP: Authentication Response frame attributes", msg);
 
@@ -2059,6 +2113,10 @@ static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
 
        /* Build DPP Authentication Response frame attributes */
        attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) + 4 + sizeof(wrapped_data);
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP)
+               attr_len += 4;
+#endif /* CONFIG_TESTING_OPTIONS */
        msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len);
        if (!msg)
                goto fail;
@@ -2106,6 +2164,12 @@ static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
        auth->r_capab = auth->configurator ? DPP_CAPAB_CONFIGURATOR :
                DPP_CAPAB_ENROLLEE;
        *pos++ = auth->r_capab;
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_ZERO_R_CAPAB) {
+               wpa_printf(MSG_INFO, "DPP: TESTING - zero R-capabilities");
+               pos[-1] = 0;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
 
        /* OUI, OUI type, Crypto Suite, DPP frame type */
        addr[0] = wpabuf_head_u8(msg) + 2;
@@ -2130,6 +2194,14 @@ static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
        wpabuf_put_le16(msg, siv_len);
        wpabuf_put_data(msg, wrapped_data, siv_len);
 
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP) {
+               wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
+               wpabuf_put_le16(msg, DPP_ATTR_TESTING);
+               wpabuf_put_le16(msg, 0);
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
        wpa_hexdump_buf(MSG_DEBUG,
                        "DPP: Authentication Response frame attributes", msg);
 
@@ -2378,6 +2450,10 @@ static struct wpabuf * dpp_auth_build_conf(struct dpp_authentication *auth)
        /* Build DPP Authentication Confirmation frame attributes */
        attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
                4 + i_auth_len + AES_BLOCK_SIZE;
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF)
+               attr_len += 4;
+#endif /* CONFIG_TESTING_OPTIONS */
        msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, attr_len);
        if (!msg)
                goto fail;
@@ -2428,6 +2504,14 @@ static struct wpabuf * dpp_auth_build_conf(struct dpp_authentication *auth)
        wpa_hexdump(MSG_DEBUG, "DPP: {I-auth}ke",
                    wrapped_i_auth, i_auth_len + AES_BLOCK_SIZE);
 
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF) {
+               wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
+               wpabuf_put_le16(msg, DPP_ATTR_TESTING);
+               wpabuf_put_le16(msg, 0);
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
        wpa_hexdump_buf(MSG_DEBUG,
                        "DPP: Authentication Confirmation frame attributes",
                        msg);
@@ -3319,7 +3403,7 @@ dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
                    u16 e_nonce_len, int ap)
 {
        struct wpabuf *conf;
-       size_t clear_len;
+       size_t clear_len, attr_len;
        struct wpabuf *clear = NULL, *msg = NULL;
        u8 *wrapped;
        const u8 *addr[1];
@@ -3338,7 +3422,12 @@ dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
        if (conf)
                clear_len += 4 + wpabuf_len(conf);
        clear = wpabuf_alloc(clear_len);
-       msg = wpabuf_alloc(4 + 1 + 4 + clear_len + AES_BLOCK_SIZE);
+       attr_len = 4 + 1 + 4 + clear_len + AES_BLOCK_SIZE;
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_CONF_RESP)
+               attr_len += 4;
+#endif /* CONFIG_TESTING_OPTIONS */
+       msg = wpabuf_alloc(attr_len);
        if (!clear || !msg)
                goto fail;
 
@@ -3378,6 +3467,14 @@ dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
        wpabuf_free(clear);
        clear = NULL;
 
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_CONF_RESP) {
+               wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
+               wpabuf_put_le16(msg, DPP_ATTR_TESTING);
+               wpabuf_put_le16(msg, 0);
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
        wpa_hexdump_buf(MSG_DEBUG,
                        "DPP: Configuration Response attributes", msg);
        return msg;
@@ -5406,7 +5503,7 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
        u16 attr_status_len, attr_id_len, attr_key_len;
        const EC_GROUP *group;
        BN_CTX *bnctx = NULL;
-       size_t clear_len;
+       size_t clear_len, attr_len;
        struct wpabuf *clear = NULL;
        u8 *wrapped;
        struct wpabuf *msg = NULL, *A_pub = NULL, *X_pub = NULL, *Y_pub = NULL;
@@ -5559,8 +5656,12 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
        /* {A, u, [bootstrapping info]}z */
        clear_len = 4 + 2 * curve->prime_len + 4 + curve->hash_len;
        clear = wpabuf_alloc(clear_len);
-       msg = dpp_alloc_msg(DPP_PA_PKEX_COMMIT_REVEAL_REQ,
-                           4 + clear_len + AES_BLOCK_SIZE);
+       attr_len = 4 + clear_len + AES_BLOCK_SIZE;
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_REQ)
+               attr_len += 4;
+#endif /* CONFIG_TESTING_OPTIONS */
+       msg = dpp_alloc_msg(DPP_PA_PKEX_COMMIT_REVEAL_REQ, attr_len);
        if (!clear || !msg)
                goto fail;
 
@@ -5594,6 +5695,14 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
        wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
                    wrapped, wpabuf_len(clear) + AES_BLOCK_SIZE);
 
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_REQ) {
+               wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
+               wpabuf_put_le16(msg, DPP_ATTR_TESTING);
+               wpabuf_put_le16(msg, 0);
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
 out:
        wpabuf_free(clear);
        wpabuf_free(A_pub);
@@ -5635,7 +5744,7 @@ struct wpabuf * dpp_pkex_rx_commit_reveal_req(struct dpp_pkex *pkex,
        struct wpabuf *msg = NULL, *A_pub = NULL, *X_pub = NULL, *Y_pub = NULL;
        struct wpabuf *B_pub = NULL;
        u8 u[DPP_MAX_HASH_LEN], v[DPP_MAX_HASH_LEN];
-       size_t clear_len;
+       size_t clear_len, attr_len;
        struct wpabuf *clear = NULL;
        u8 *wrapped;
        int res;
@@ -5803,8 +5912,12 @@ struct wpabuf * dpp_pkex_rx_commit_reveal_req(struct dpp_pkex *pkex,
        /* {B, v [bootstrapping info]}z */
        clear_len = 4 + 2 * curve->prime_len + 4 + curve->hash_len;
        clear = wpabuf_alloc(clear_len);
-       msg = dpp_alloc_msg(DPP_PA_PKEX_COMMIT_REVEAL_RESP,
-                           4 + clear_len + AES_BLOCK_SIZE);
+       attr_len = 4 + clear_len + AES_BLOCK_SIZE;
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_RESP)
+               attr_len += 4;
+#endif /* CONFIG_TESTING_OPTIONS */
+       msg = dpp_alloc_msg(DPP_PA_PKEX_COMMIT_REVEAL_RESP, attr_len);
        if (!clear || !msg)
                goto fail;
 
@@ -5837,6 +5950,14 @@ struct wpabuf * dpp_pkex_rx_commit_reveal_req(struct dpp_pkex *pkex,
                goto fail;
        wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
                    wrapped, wpabuf_len(clear) + AES_BLOCK_SIZE);
+
+#ifdef CONFIG_TESTING_OPTIONS
+       if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_RESP) {
+               wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data");
+               wpabuf_put_le16(msg, DPP_ATTR_TESTING);
+               wpabuf_put_le16(msg, 0);
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
 out:
        EVP_PKEY_CTX_free(ctx);
        os_free(unwrapped);
index dfee49918a75fa34064983a763b04b46b9ed1391..f6bc5af0131573569d37319281a5e4fd6704c89d 100644 (file)
@@ -52,6 +52,7 @@ enum dpp_attribute_id {
        DPP_ATTR_ENROLLEE_NONCE = 0x1014,
        DPP_ATTR_CODE_IDENTIFIER = 0x1015,
        DPP_ATTR_TRANSACTION_ID = 0x1016,
+       DPP_ATTR_TESTING = 0x10ff, /* not defined in the DPP tech spec */
 };
 
 enum dpp_status_error {
@@ -203,6 +204,23 @@ struct dpp_introduction {
        size_t pmk_len;
 };
 
+#ifdef CONFIG_TESTING_OPTIONS
+enum dpp_test_behavior {
+       DPP_TEST_DISABLED = 0,
+       DPP_TEST_AFTER_WRAPPED_DATA_AUTH_REQ = 1,
+       DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP = 2,
+       DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF = 3,
+       DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_REQ = 4,
+       DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_RESP = 5,
+       DPP_TEST_AFTER_WRAPPED_DATA_CONF_REQ = 6,
+       DPP_TEST_AFTER_WRAPPED_DATA_CONF_RESP = 7,
+       DPP_TEST_ZERO_I_CAPAB = 8,
+       DPP_TEST_ZERO_R_CAPAB = 9,
+};
+
+extern enum dpp_test_behavior dpp_test;
+#endif /* CONFIG_TESTING_OPTIONS */
+
 void dpp_bootstrap_info_free(struct dpp_bootstrap_info *info);
 const char * dpp_bootstrap_type_txt(enum dpp_bootstrap_type type);
 int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi);
index c4d8dfe34319b0bb7c9b99e6046c3d731d5505af..dbc654a2a93c7b0608d80a27c8899fc57258b835 100644 (file)
@@ -20,6 +20,7 @@
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
 #include "common/wpa_ctrl.h"
+#include "common/dpp.h"
 #include "crypto/tls.h"
 #include "ap/hostapd.h"
 #include "eap_peer/eap.h"
@@ -655,6 +656,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
        } else if (os_strcasecmp(cmd,
                                 "dpp_ignore_netaccesskey_mismatch") == 0) {
                wpa_s->dpp_ignore_netaccesskey_mismatch = atoi(value);
+       } else if (os_strcasecmp(cmd, "dpp_test") == 0) {
+               dpp_test = atoi(value);
 #endif /* CONFIG_DPP */
 #endif /* CONFIG_TESTING_OPTIONS */
 #ifndef CONFIG_NO_CONFIG_BLOBS
@@ -7778,6 +7781,9 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
        wpa_s->get_pref_freq_list_override = NULL;
        wpabuf_free(wpa_s->sae_commit_override);
        wpa_s->sae_commit_override = NULL;
+#ifdef CONFIG_DPP
+       dpp_test = DPP_TEST_DISABLED;
+#endif /* CONFIG_DPP */
 #endif /* CONFIG_TESTING_OPTIONS */
 
        wpa_s->disconnected = 0;