mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-25 17:59:25 +01:00
unit: Test a EAP-WSC-R setup with WPA2 credentials
This commit is contained in:
parent
6f9b087304
commit
3cf8af2431
275
unit/test-wsc.c
275
unit/test-wsc.c
@ -2261,6 +2261,278 @@ static void wsc_test_pin_generate(const void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct test_ap_sta_data {
|
||||||
|
struct handshake_state *ap_hs;
|
||||||
|
struct handshake_state *sta_hs;
|
||||||
|
const uint8_t ap_address[6];
|
||||||
|
const uint8_t sta_address[6];
|
||||||
|
|
||||||
|
uint8_t to_sta_data[1024];
|
||||||
|
int to_sta_data_len;
|
||||||
|
int to_sta_msg_cnt;
|
||||||
|
int to_ap_msg_cnt;
|
||||||
|
struct eapol_sm *ap_sm;
|
||||||
|
struct eapol_sm *sta_sm;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int test_ap_sta_eapol_tx(uint32_t ifindex,
|
||||||
|
const uint8_t *dest, uint16_t proto,
|
||||||
|
const struct eapol_frame *ef,
|
||||||
|
bool noencrypt, void *user_data)
|
||||||
|
{
|
||||||
|
struct test_ap_sta_data *s = user_data;
|
||||||
|
size_t len = sizeof(struct eapol_header) +
|
||||||
|
L_BE16_TO_CPU(ef->header.packet_len);
|
||||||
|
|
||||||
|
assert(ifindex == s->ap_hs->ifindex || ifindex == s->sta_hs->ifindex);
|
||||||
|
assert(proto == ETH_P_PAE && !noencrypt);
|
||||||
|
|
||||||
|
if (ifindex == s->ap_hs->ifindex) { /* From AP to STA */
|
||||||
|
assert(!memcmp(dest, s->sta_address, 6));
|
||||||
|
assert(len < sizeof(s->to_sta_data));
|
||||||
|
memcpy(s->to_sta_data, ef, len);
|
||||||
|
s->to_sta_data_len = len;
|
||||||
|
s->to_sta_msg_cnt++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* From STA to AP */
|
||||||
|
assert(!memcmp(dest, s->ap_address, 6));
|
||||||
|
s->to_ap_msg_cnt++;
|
||||||
|
__eapol_rx_packet(1, s->sta_address, proto, (const void *) ef, len,
|
||||||
|
noencrypt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ap_sta_run(struct test_ap_sta_data *s)
|
||||||
|
{
|
||||||
|
eap_init();
|
||||||
|
eapol_init();
|
||||||
|
__eapol_set_tx_packet_func(test_ap_sta_eapol_tx);
|
||||||
|
__eapol_set_tx_user_data(s);
|
||||||
|
|
||||||
|
s->to_sta_msg_cnt = 0;
|
||||||
|
s->to_ap_msg_cnt = 0;
|
||||||
|
s->to_sta_data_len = 0;
|
||||||
|
|
||||||
|
s->ap_sm = eapol_sm_new(s->ap_hs);
|
||||||
|
eapol_register(s->ap_sm);
|
||||||
|
|
||||||
|
s->sta_sm = eapol_sm_new(s->sta_hs);
|
||||||
|
eapol_register(s->sta_sm);
|
||||||
|
|
||||||
|
eapol_start(s->sta_sm);
|
||||||
|
eapol_start(s->ap_sm);
|
||||||
|
|
||||||
|
while (s->to_sta_data_len) {
|
||||||
|
int len = s->to_sta_data_len;
|
||||||
|
s->to_sta_data_len = 0;
|
||||||
|
__eapol_rx_packet(s->sta_hs->ifindex, s->ap_address, ETH_P_PAE,
|
||||||
|
s->to_sta_data, len, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->ap_sm)
|
||||||
|
eapol_sm_free(s->ap_sm);
|
||||||
|
|
||||||
|
if (s->sta_sm)
|
||||||
|
eapol_sm_free(s->sta_sm);
|
||||||
|
|
||||||
|
eapol_exit();
|
||||||
|
eap_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct test_ap_sta_hs {
|
||||||
|
struct handshake_state super;
|
||||||
|
struct test_ap_sta_data *s;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct handshake_state *test_ap_sta_hs_new(struct test_ap_sta_data *s,
|
||||||
|
uint32_t ifindex)
|
||||||
|
{
|
||||||
|
struct test_ap_sta_hs *ths = l_new(struct test_ap_sta_hs, 1);
|
||||||
|
|
||||||
|
ths->super.ifindex = ifindex;
|
||||||
|
ths->super.free = (void (*)(struct handshake_state *s)) l_free;
|
||||||
|
ths->s = s;
|
||||||
|
|
||||||
|
return &ths->super;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool random_nonce(uint8_t nonce[])
|
||||||
|
{
|
||||||
|
return l_getrandom(nonce, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ap_sta_install_tk(struct handshake_state *hs,
|
||||||
|
const uint8_t *tk, uint32_t cipher)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wsc_r_test_success_data {
|
||||||
|
bool credentials_obtained;
|
||||||
|
bool credentials_sent;
|
||||||
|
bool ap_eap_failed;
|
||||||
|
bool sta_eap_failed;
|
||||||
|
struct test_ap_sta_data *s;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_ap_sta_hs_event_ap(struct handshake_state *hs,
|
||||||
|
enum handshake_event event,
|
||||||
|
void *user_data, ...)
|
||||||
|
{
|
||||||
|
struct wsc_r_test_success_data *data = user_data;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, user_data);
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case HANDSHAKE_EVENT_EAP_NOTIFY:
|
||||||
|
assert(va_arg(args, unsigned int) ==
|
||||||
|
EAP_WSC_EVENT_CREDENTIAL_SENT);
|
||||||
|
assert(!data->credentials_sent);
|
||||||
|
assert(!data->ap_eap_failed);
|
||||||
|
data->credentials_sent = true;
|
||||||
|
break;
|
||||||
|
case HANDSHAKE_EVENT_FAILED:
|
||||||
|
assert(va_arg(args, int) ==
|
||||||
|
MMPDU_REASON_CODE_IEEE8021X_FAILED);
|
||||||
|
assert(!data->ap_eap_failed);
|
||||||
|
data->ap_eap_failed = true;
|
||||||
|
data->s->ap_sm = NULL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ap_sta_hs_event_sta(struct handshake_state *hs,
|
||||||
|
enum handshake_event event,
|
||||||
|
void *user_data, ...)
|
||||||
|
{
|
||||||
|
struct wsc_r_test_success_data *data = user_data;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, user_data);
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case HANDSHAKE_EVENT_EAP_NOTIFY:
|
||||||
|
{
|
||||||
|
unsigned int eap_event = va_arg(args, unsigned int);
|
||||||
|
const struct wsc_credential *cred;
|
||||||
|
|
||||||
|
assert(eap_event == EAP_WSC_EVENT_CREDENTIAL_OBTAINED);
|
||||||
|
cred = va_arg(args, const struct wsc_credential *);
|
||||||
|
assert(cred->ssid_len == 7 &&
|
||||||
|
!memcmp(cred->ssid, "thessid", 7));
|
||||||
|
assert(cred->auth_type ==
|
||||||
|
WSC_AUTHENTICATION_TYPE_WPA2_PERSONAL);
|
||||||
|
assert(cred->encryption_type == WSC_ENCRYPTION_TYPE_AES_TKIP);
|
||||||
|
assert(cred->network_key_len == 12 &&
|
||||||
|
!memcmp(cred->network_key, "secretsecret", 12));
|
||||||
|
assert(!memcmp(cred->addr, data->s->sta_address, 6));
|
||||||
|
assert(!data->credentials_obtained);
|
||||||
|
assert(!data->sta_eap_failed);
|
||||||
|
data->credentials_obtained = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case HANDSHAKE_EVENT_FAILED:
|
||||||
|
assert(va_arg(args, int) ==
|
||||||
|
MMPDU_REASON_CODE_IEEE8021X_FAILED);
|
||||||
|
assert(!data->sta_eap_failed);
|
||||||
|
data->sta_eap_failed = true;
|
||||||
|
data->s->sta_sm = NULL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wsc_r_test_pbc_handshake_wpa2(const void *data)
|
||||||
|
{
|
||||||
|
static const unsigned char ap_rsne[] = {
|
||||||
|
0x30, 0x12, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
|
||||||
|
0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00,
|
||||||
|
0x00, 0x0f, 0xac, 0x02 };
|
||||||
|
static const char *ssid = "TestWPA2EAP";
|
||||||
|
static const char *ap_8021x_str = "[Security]\n"
|
||||||
|
"EAP-Method=WSC-R\n"
|
||||||
|
"[WSC]\n"
|
||||||
|
"UUID-R=00112233445566778899aabbccddeeff\n"
|
||||||
|
"WPA2-SSID=thessid\n"
|
||||||
|
"WPA2-Passphrase=secretsecret\n"
|
||||||
|
"RFBand=1\n"
|
||||||
|
"ConfigurationMethods=0x680\n";
|
||||||
|
static const char *sta_8021x_str = "[Security]\n"
|
||||||
|
"EAP-Identity=WFA-SimpleConfig-Enrollee-1-0\n"
|
||||||
|
"EAP-Method=WSC\n"
|
||||||
|
"[WSC]\n"
|
||||||
|
"RFBand=1\n"
|
||||||
|
"ConfigurationMethods=0x680\n";
|
||||||
|
struct l_settings *ap_8021x_settings = l_settings_new();
|
||||||
|
struct l_settings *sta_8021x_settings = l_settings_new();
|
||||||
|
struct test_ap_sta_data s = {
|
||||||
|
.ap_hs = test_ap_sta_hs_new(&s, 1),
|
||||||
|
.sta_hs = test_ap_sta_hs_new(&s, 2),
|
||||||
|
.ap_address = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
|
||||||
|
.sta_address = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x08 },
|
||||||
|
};
|
||||||
|
struct wsc_r_test_success_data wsc_data = {
|
||||||
|
.s = &s,
|
||||||
|
};
|
||||||
|
uint8_t uuid_e[16];
|
||||||
|
L_AUTO_FREE_VAR(char *, uuid_e_str) = NULL;
|
||||||
|
|
||||||
|
wsc_uuid_from_addr(s.sta_address, uuid_e);
|
||||||
|
uuid_e_str = l_util_hexstring(uuid_e, 16);
|
||||||
|
|
||||||
|
__handshake_set_get_nonce_func(random_nonce);
|
||||||
|
__handshake_set_install_tk_func(test_ap_sta_install_tk);
|
||||||
|
__handshake_set_install_gtk_func(NULL);
|
||||||
|
|
||||||
|
handshake_state_set_authenticator(s.ap_hs, true);
|
||||||
|
handshake_state_set_event_func(s.ap_hs, test_ap_sta_hs_event_ap,
|
||||||
|
&wsc_data);
|
||||||
|
handshake_state_set_authenticator_address(s.ap_hs, s.ap_address);
|
||||||
|
handshake_state_set_supplicant_address(s.ap_hs, s.sta_address);
|
||||||
|
handshake_state_set_authenticator_ie(s.ap_hs, ap_rsne);
|
||||||
|
handshake_state_set_ssid(s.ap_hs, (void *) ssid, strlen(ssid));
|
||||||
|
l_settings_load_from_data(ap_8021x_settings, ap_8021x_str,
|
||||||
|
strlen(ap_8021x_str));
|
||||||
|
l_settings_set_string(ap_8021x_settings, "WSC", "EnrolleeMAC",
|
||||||
|
util_address_to_string(s.sta_address));
|
||||||
|
l_settings_set_string(ap_8021x_settings, "WSC", "UUID-E", uuid_e_str);
|
||||||
|
handshake_state_set_8021x_config(s.ap_hs, ap_8021x_settings);
|
||||||
|
|
||||||
|
handshake_state_set_authenticator(s.sta_hs, false);
|
||||||
|
handshake_state_set_event_func(s.sta_hs, test_ap_sta_hs_event_sta,
|
||||||
|
&wsc_data);
|
||||||
|
handshake_state_set_authenticator_address(s.sta_hs, s.ap_address);
|
||||||
|
handshake_state_set_supplicant_address(s.sta_hs, s.sta_address);
|
||||||
|
handshake_state_set_authenticator_ie(s.sta_hs, ap_rsne);
|
||||||
|
handshake_state_set_ssid(s.sta_hs, (void *) ssid, strlen(ssid));
|
||||||
|
l_settings_load_from_data(sta_8021x_settings, sta_8021x_str,
|
||||||
|
strlen(sta_8021x_str));
|
||||||
|
l_settings_set_string(sta_8021x_settings, "WSC", "EnrolleeMAC",
|
||||||
|
util_address_to_string(s.sta_address));
|
||||||
|
handshake_state_set_8021x_config(s.sta_hs, sta_8021x_settings);
|
||||||
|
|
||||||
|
test_ap_sta_run(&s);
|
||||||
|
|
||||||
|
handshake_state_free(s.ap_hs);
|
||||||
|
handshake_state_free(s.sta_hs);
|
||||||
|
__handshake_set_install_tk_func(NULL);
|
||||||
|
l_settings_free(ap_8021x_settings);
|
||||||
|
l_settings_free(sta_8021x_settings);
|
||||||
|
|
||||||
|
assert(wsc_data.sta_eap_failed && wsc_data.credentials_obtained);
|
||||||
|
assert(wsc_data.ap_eap_failed && wsc_data.credentials_sent);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
l_test_init(&argc, &argv);
|
l_test_init(&argc, &argv);
|
||||||
@ -2374,6 +2646,9 @@ int main(int argc, char *argv[])
|
|||||||
l_test_add("/wsc/retransmission/no fragmentation",
|
l_test_add("/wsc/retransmission/no fragmentation",
|
||||||
wsc_test_retransmission_no_fragmentation, NULL);
|
wsc_test_retransmission_no_fragmentation, NULL);
|
||||||
|
|
||||||
|
l_test_add("/wsc-r/handshake/PBC Handshake WPA2 Test",
|
||||||
|
wsc_r_test_pbc_handshake_wpa2, NULL);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return l_test_run();
|
return l_test_run();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user