]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE-PK: Testing functionality to allow behavior overrides
authorJouni Malinen <jouni@codeaurora.org>
Mon, 8 Jun 2020 11:00:28 +0000 (14:00 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 8 Jun 2020 12:21:18 +0000 (15:21 +0300)
The new sae_commit_status and sae_pk_omit configuration parameters and
an extra key at the end of sae_password pk argument can be used to
override SAE-PK behavior for testing purposes.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
hostapd/config_file.c
src/ap/ap_config.c
src/ap/ap_config.h
src/ap/ieee802_11.c
src/common/sae.h
src/common/sae_pk.c

index 49894c5ba85acff5ab77777900a37465389491e4..dac0e8054de17a95afeeb0d1570cfc9d3baf8f9a 100644 (file)
@@ -4231,6 +4231,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->own_ie_override = tmp;
        } else if (os_strcmp(buf, "sae_reflection_attack") == 0) {
                bss->sae_reflection_attack = atoi(pos);
+       } else if (os_strcmp(buf, "sae_commit_status") == 0) {
+               bss->sae_commit_status = atoi(pos);
+       } else if (os_strcmp(buf, "sae_pk_omit") == 0) {
+               bss->sae_pk_omit = atoi(pos);
        } else if (os_strcmp(buf, "sae_commit_override") == 0) {
                wpabuf_free(bss->sae_commit_override);
                bss->sae_commit_override = wpabuf_parse_bin(pos);
index a4e1bbb3d6455c6ce7efd88f7a56fc32f8c81a8e..1c6b4a00ec26e32d35e894303fc778a2b24aa2b8 100644 (file)
@@ -160,6 +160,10 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
 
        /* Default to strict CRL checking. */
        bss->check_crl_strict = 1;
+
+#ifdef CONFIG_TESTING_OPTIONS
+       bss->sae_commit_status = -1;
+#endif /* CONFIG_TESTING_OPTIONS */
 }
 
 
index cafc44edd9a872dede038e00ed968ec3786446d4..4c2e600951750673a909bca7252ed0281c839ca6 100644 (file)
@@ -678,6 +678,8 @@ struct hostapd_bss_config {
        u8 bss_load_test_set;
        struct wpabuf *own_ie_override;
        int sae_reflection_attack;
+       int sae_commit_status;
+       int sae_pk_omit;
        struct wpabuf *sae_commit_override;
        struct wpabuf *rsne_override_eapol;
        struct wpabuf *rsnxe_override_eapol;
index eca8b19ad1690195bf98e3e63c0658eeda773fdc..8b994d6a59041e6ca74e36e4fabcc1a2115806eb 100644 (file)
@@ -567,6 +567,13 @@ static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
        if (buf == NULL)
                return NULL;
 
+#ifdef CONFIG_SAE_PK
+#ifdef CONFIG_TESTING_OPTIONS
+       if (sta->sae->tmp)
+               sta->sae->tmp->omit_pk_elem = hapd->conf->sae_pk_omit;
+#endif /* CONFIG_TESTING_OPTIONS */
+#endif /* CONFIG_SAE_PK */
+
        if (sae_write_confirm(sta->sae, buf) < 0) {
                wpabuf_free(buf);
                return NULL;
@@ -600,6 +607,15 @@ static int auth_sae_send_commit(struct hostapd_data *hapd,
                status = WLAN_STATUS_SAE_HASH_TO_ELEMENT;
        else
                status = WLAN_STATUS_SUCCESS;
+#ifdef CONFIG_TESTING_OPTIONS
+       if (hapd->conf->sae_commit_status >= 0 &&
+           hapd->conf->sae_commit_status != status) {
+               wpa_printf(MSG_INFO,
+                          "TESTING: Override SAE commit status code %u --> %d",
+                          status, hapd->conf->sae_commit_status);
+               status = hapd->conf->sae_commit_status;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
        reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
                                    WLAN_AUTH_SAE, 1,
                                    status, wpabuf_head(data),
index 887cd4e9ac9a26c1afe2f235685d69d59df55023..261935fdbe6a95c7edd93f27679a6f958ef14e2d 100644 (file)
@@ -31,6 +31,9 @@ struct sae_pk {
        struct crypto_ec_key *key;
        int group;
        struct wpabuf *pubkey; /* DER encoded subjectPublicKey */
+#ifdef CONFIG_TESTING_OPTIONS
+       struct crypto_ec_key *sign_key_override;
+#endif /* CONFIG_TESTING_OPTIONS */
 };
 
 
@@ -73,6 +76,9 @@ struct sae_temporary_data {
        u8 ssid[32];
        size_t ssid_len;
        bool reject_group;
+#ifdef CONFIG_TESTING_OPTIONS
+       bool omit_pk_elem;
+#endif /* CONFIG_TESTING_OPTIONS */
 #endif /* CONFIG_SAE_PK */
 };
 
index 806498c3870a180d424aa1587ee4caac8aad78f6..bb9c979a146b8818b7b03b4b97e63e6216a61458 100644 (file)
@@ -203,6 +203,9 @@ void sae_deinit_pk(struct sae_pk *pk)
        if (pk) {
                wpabuf_free(pk->m);
                crypto_ec_key_deinit(pk->key);
+#ifdef CONFIG_TESTING_OPTIONS
+               crypto_ec_key_deinit(pk->sign_key_override);
+#endif /* CONFIG_TESTING_OPTIONS */
                wpabuf_free(pk->pubkey);
                os_free(pk);
        }
@@ -213,9 +216,12 @@ struct sae_pk * sae_parse_pk(const char *val)
 {
        struct sae_pk *pk;
        const char *pos;
+#ifdef CONFIG_TESTING_OPTIONS
+       const char *pos2;
+#endif /* CONFIG_TESTING_OPTIONS */
        size_t len;
        unsigned char *der;
-       size_t der_len;
+       size_t der_len, b_len;
 
        /* <m-as-hexdump>:<base64-encoded-DER-encoded-key> */
 
@@ -239,7 +245,15 @@ struct sae_pk * sae_parse_pk(const char *val)
        }
 
        pos++;
-       der = base64_decode(pos, os_strlen(pos), &der_len);
+       b_len = os_strlen(pos);
+#ifdef CONFIG_TESTING_OPTIONS
+       pos2 = os_strchr(pos, ':');
+       if (pos2) {
+               b_len = pos2 - pos;
+               pos2++;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+       der = base64_decode(pos, b_len, &der_len);
        if (!der) {
                wpa_printf(MSG_INFO, "SAE: Failed to base64 decode PK key");
                goto fail;
@@ -254,6 +268,22 @@ struct sae_pk * sae_parse_pk(const char *val)
        if (!pk->pubkey)
                goto fail;
 
+#ifdef CONFIG_TESTING_OPTIONS
+       if (pos2) {
+               der = base64_decode(pos2, os_strlen(pos2), &der_len);
+               if (!der) {
+                       wpa_printf(MSG_INFO,
+                                  "SAE: Failed to base64 decode PK key");
+                       goto fail;
+               }
+
+               pk->sign_key_override = crypto_ec_key_parse_priv(der, der_len);
+               bin_clear_free(der, der_len);
+               if (!pk->sign_key_override)
+                       goto fail;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
        return pk;
 fail:
        sae_deinit_pk(pk);
@@ -342,6 +372,7 @@ int sae_write_confirm_pk(struct sae_data *sae, struct wpabuf *buf)
        const struct sae_pk *pk;
        u8 hash[SAE_MAX_HASH_LEN];
        size_t hash_len;
+       struct crypto_ec_key *key;
 
        if (!tmp)
                return -1;
@@ -350,6 +381,16 @@ int sae_write_confirm_pk(struct sae_data *sae, struct wpabuf *buf)
        if (!pk)
                return 0;
 
+       key = pk->key;
+#ifdef CONFIG_TESTING_OPTIONS
+       if (tmp->omit_pk_elem)
+               return 0;
+       if (pk->sign_key_override) {
+               wpa_printf(MSG_INFO, "TESTING: Override SAE-PK signing key");
+               key = pk->sign_key_override;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
        if (tmp->kek_len != 32 && tmp->kek_len != 48 && tmp->kek_len != 64) {
                wpa_printf(MSG_INFO, "SAE-PK: No KEK available for confirm");
                return -1;
@@ -368,7 +409,7 @@ int sae_write_confirm_pk(struct sae_data *sae, struct wpabuf *buf)
                                 wpabuf_len(pk->m), wpabuf_head(pk->pubkey),
                                 wpabuf_len(pk->pubkey), hash) < 0)
                goto fail;
-       sig = crypto_ec_key_sign(pk->key, hash, hash_len);
+       sig = crypto_ec_key_sign(key, hash, hash_len);
        if (!sig)
                goto fail;
        wpa_hexdump_buf(MSG_DEBUG, "SAE-PK: KeyAuth = Sig_AP()", sig);