SAE-PK: Testing functionality to allow behavior overrides
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>
This commit is contained in:
parent
3a6e674adf
commit
4ff0df39eb
6 changed files with 76 additions and 3 deletions
|
@ -4231,6 +4231,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
bss->own_ie_override = tmp;
|
bss->own_ie_override = tmp;
|
||||||
} else if (os_strcmp(buf, "sae_reflection_attack") == 0) {
|
} else if (os_strcmp(buf, "sae_reflection_attack") == 0) {
|
||||||
bss->sae_reflection_attack = atoi(pos);
|
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) {
|
} else if (os_strcmp(buf, "sae_commit_override") == 0) {
|
||||||
wpabuf_free(bss->sae_commit_override);
|
wpabuf_free(bss->sae_commit_override);
|
||||||
bss->sae_commit_override = wpabuf_parse_bin(pos);
|
bss->sae_commit_override = wpabuf_parse_bin(pos);
|
||||||
|
|
|
@ -160,6 +160,10 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
|
||||||
|
|
||||||
/* Default to strict CRL checking. */
|
/* Default to strict CRL checking. */
|
||||||
bss->check_crl_strict = 1;
|
bss->check_crl_strict = 1;
|
||||||
|
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
bss->sae_commit_status = -1;
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -678,6 +678,8 @@ struct hostapd_bss_config {
|
||||||
u8 bss_load_test_set;
|
u8 bss_load_test_set;
|
||||||
struct wpabuf *own_ie_override;
|
struct wpabuf *own_ie_override;
|
||||||
int sae_reflection_attack;
|
int sae_reflection_attack;
|
||||||
|
int sae_commit_status;
|
||||||
|
int sae_pk_omit;
|
||||||
struct wpabuf *sae_commit_override;
|
struct wpabuf *sae_commit_override;
|
||||||
struct wpabuf *rsne_override_eapol;
|
struct wpabuf *rsne_override_eapol;
|
||||||
struct wpabuf *rsnxe_override_eapol;
|
struct wpabuf *rsnxe_override_eapol;
|
||||||
|
|
|
@ -567,6 +567,13 @@ static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return 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) {
|
if (sae_write_confirm(sta->sae, buf) < 0) {
|
||||||
wpabuf_free(buf);
|
wpabuf_free(buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -600,6 +607,15 @@ static int auth_sae_send_commit(struct hostapd_data *hapd,
|
||||||
status = WLAN_STATUS_SAE_HASH_TO_ELEMENT;
|
status = WLAN_STATUS_SAE_HASH_TO_ELEMENT;
|
||||||
else
|
else
|
||||||
status = WLAN_STATUS_SUCCESS;
|
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,
|
reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
|
||||||
WLAN_AUTH_SAE, 1,
|
WLAN_AUTH_SAE, 1,
|
||||||
status, wpabuf_head(data),
|
status, wpabuf_head(data),
|
||||||
|
|
|
@ -31,6 +31,9 @@ struct sae_pk {
|
||||||
struct crypto_ec_key *key;
|
struct crypto_ec_key *key;
|
||||||
int group;
|
int group;
|
||||||
struct wpabuf *pubkey; /* DER encoded subjectPublicKey */
|
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];
|
u8 ssid[32];
|
||||||
size_t ssid_len;
|
size_t ssid_len;
|
||||||
bool reject_group;
|
bool reject_group;
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
bool omit_pk_elem;
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
#endif /* CONFIG_SAE_PK */
|
#endif /* CONFIG_SAE_PK */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,9 @@ void sae_deinit_pk(struct sae_pk *pk)
|
||||||
if (pk) {
|
if (pk) {
|
||||||
wpabuf_free(pk->m);
|
wpabuf_free(pk->m);
|
||||||
crypto_ec_key_deinit(pk->key);
|
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);
|
wpabuf_free(pk->pubkey);
|
||||||
os_free(pk);
|
os_free(pk);
|
||||||
}
|
}
|
||||||
|
@ -213,9 +216,12 @@ struct sae_pk * sae_parse_pk(const char *val)
|
||||||
{
|
{
|
||||||
struct sae_pk *pk;
|
struct sae_pk *pk;
|
||||||
const char *pos;
|
const char *pos;
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
const char *pos2;
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
size_t len;
|
size_t len;
|
||||||
unsigned char *der;
|
unsigned char *der;
|
||||||
size_t der_len;
|
size_t der_len, b_len;
|
||||||
|
|
||||||
/* <m-as-hexdump>:<base64-encoded-DER-encoded-key> */
|
/* <m-as-hexdump>:<base64-encoded-DER-encoded-key> */
|
||||||
|
|
||||||
|
@ -239,7 +245,15 @@ struct sae_pk * sae_parse_pk(const char *val)
|
||||||
}
|
}
|
||||||
|
|
||||||
pos++;
|
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) {
|
if (!der) {
|
||||||
wpa_printf(MSG_INFO, "SAE: Failed to base64 decode PK key");
|
wpa_printf(MSG_INFO, "SAE: Failed to base64 decode PK key");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -254,6 +268,22 @@ struct sae_pk * sae_parse_pk(const char *val)
|
||||||
if (!pk->pubkey)
|
if (!pk->pubkey)
|
||||||
goto fail;
|
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;
|
return pk;
|
||||||
fail:
|
fail:
|
||||||
sae_deinit_pk(pk);
|
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;
|
const struct sae_pk *pk;
|
||||||
u8 hash[SAE_MAX_HASH_LEN];
|
u8 hash[SAE_MAX_HASH_LEN];
|
||||||
size_t hash_len;
|
size_t hash_len;
|
||||||
|
struct crypto_ec_key *key;
|
||||||
|
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -350,6 +381,16 @@ int sae_write_confirm_pk(struct sae_data *sae, struct wpabuf *buf)
|
||||||
if (!pk)
|
if (!pk)
|
||||||
return 0;
|
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) {
|
if (tmp->kek_len != 32 && tmp->kek_len != 48 && tmp->kek_len != 64) {
|
||||||
wpa_printf(MSG_INFO, "SAE-PK: No KEK available for confirm");
|
wpa_printf(MSG_INFO, "SAE-PK: No KEK available for confirm");
|
||||||
return -1;
|
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->m), wpabuf_head(pk->pubkey),
|
||||||
wpabuf_len(pk->pubkey), hash) < 0)
|
wpabuf_len(pk->pubkey), hash) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
sig = crypto_ec_key_sign(pk->key, hash, hash_len);
|
sig = crypto_ec_key_sign(key, hash, hash_len);
|
||||||
if (!sig)
|
if (!sig)
|
||||||
goto fail;
|
goto fail;
|
||||||
wpa_hexdump_buf(MSG_DEBUG, "SAE-PK: KeyAuth = Sig_AP()", sig);
|
wpa_hexdump_buf(MSG_DEBUG, "SAE-PK: KeyAuth = Sig_AP()", sig);
|
||||||
|
|
Loading…
Reference in a new issue