]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - tests/hwsim/test_ap_ft.py
tests: Make HS 2.0 test cases more robust
[thirdparty/hostap.git] / tests / hwsim / test_ap_ft.py
index c206bcf108966923e8df4e5f33b4e79eea3b2e6c..b65c4bd39154b6a2c3f531403017b4e5bd111c59 100644 (file)
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-#
 # Fast BSS Transition tests
 # Copyright (c) 2013, Jouni Malinen <j@w1.fi>
 #
@@ -9,11 +7,12 @@
 import time
 import subprocess
 import logging
-logger = logging.getLogger(__name__)
+logger = logging.getLogger()
 
 import hwsim_utils
 import hostapd
 from wlantest import Wlantest
+from test_ap_psk import check_mib
 
 def ft_base_rsn():
     params = { "wpa": "2",
@@ -62,10 +61,45 @@ def ft_params2(rsn=True, ssid=None, passphrase=None):
     params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
     return params
 
-def run_roams(dev, apdev, ssid, passphrase):
+def ft_params1_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
+    params = ft_params(rsn, ssid, passphrase)
+    params['nas_identifier'] = "nas1.w1.fi"
+    params['r1_key_holder'] = "000102030405"
+    params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f",
+                       "12:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f" ]
+    params['r1kh'] = "12:00:00:00:04:00 10:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
+    return params
+
+def ft_params2_incorrect_rrb_key(rsn=True, ssid=None, passphrase=None):
+    params = ft_params(rsn, ssid, passphrase)
+    params['nas_identifier'] = "nas2.w1.fi"
+    params['r1_key_holder'] = "000102030406"
+    params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0ef1",
+                       "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0ef2" ]
+    params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0ef3"
+    return params
+
+def ft_params2_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
+    params = ft_params(rsn, ssid, passphrase)
+    params['nas_identifier'] = "nas2.w1.fi"
+    params['r1_key_holder'] = "000102030406"
+    params['r0kh'] = [ "12:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
+                       "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f" ]
+    params['r1kh'] = "12:00:00:00:03:00 10:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
+    return params
+
+def run_roams(dev, apdev, ssid, passphrase, over_ds=False, sae=False, eap=False, fail_test=False):
     logger.info("Connect to first AP")
-    dev.connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
-                ieee80211w="1")
+    if eap:
+        dev.connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
+                    eap="EKE", identity="eke user", password="hello")
+    else:
+        if sae:
+            key_mgmt="FT-SAE"
+        else:
+            key_mgmt="FT-PSK"
+        dev.connect(ssid, psk=passphrase, key_mgmt=key_mgmt, proto="WPA2",
+                    ieee80211w="1")
     if dev.get_status_field('bssid') == apdev[0]['bssid']:
         ap1 = apdev[0]
         ap2 = apdev[1]
@@ -75,13 +109,21 @@ def run_roams(dev, apdev, ssid, passphrase):
     hwsim_utils.test_connectivity(dev.ifname, ap1['ifname'])
 
     logger.info("Roam to the second AP")
-    dev.roam(ap2['bssid'])
+    if over_ds:
+        dev.roam_over_ds(ap2['bssid'], fail_test=fail_test)
+    else:
+        dev.roam(ap2['bssid'], fail_test=fail_test)
+    if fail_test:
+        return
     if dev.get_status_field('bssid') != ap2['bssid']:
         raise Exception("Did not connect to correct AP")
     hwsim_utils.test_connectivity(dev.ifname, ap2['ifname'])
 
     logger.info("Roam back to the first AP")
-    dev.roam(ap1['bssid'])
+    if over_ds:
+        dev.roam_over_ds(ap1['bssid'])
+    else:
+        dev.roam(ap1['bssid'])
     if dev.get_status_field('bssid') != ap1['bssid']:
         raise Exception("Did not connect to correct AP")
     hwsim_utils.test_connectivity(dev.ifname, ap1['ifname'])
@@ -97,6 +139,8 @@ def test_ap_ft(dev, apdev):
     hostapd.add_ap(apdev[1]['ifname'], params)
 
     run_roams(dev[0], apdev, ssid, passphrase)
+    if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
+        raise Exception("Scan results missing RSN element info")
 
 def test_ap_ft_mixed(dev, apdev):
     """WPA2-PSK-FT mixed-mode AP"""
@@ -104,7 +148,11 @@ def test_ap_ft_mixed(dev, apdev):
     passphrase="12345678"
 
     params = ft_params1(rsn=False, ssid=ssid, passphrase=passphrase)
-    hostapd.add_ap(apdev[0]['ifname'], params)
+    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    key_mgmt = hapd.get_config()['key_mgmt']
+    vals = key_mgmt.split(' ')
+    if vals[0] != "WPA-PSK" or vals[1] != "FT-PSK":
+        raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
     params = ft_params2(rsn=False, ssid=ssid, passphrase=passphrase)
     hostapd.add_ap(apdev[1]['ifname'], params)
 
@@ -123,3 +171,182 @@ def test_ap_ft_pmf(dev, apdev):
     hostapd.add_ap(apdev[1]['ifname'], params)
 
     run_roams(dev[0], apdev, ssid, passphrase)
+
+def test_ap_ft_over_ds(dev, apdev):
+    """WPA2-PSK-FT AP over DS"""
+    ssid = "test-ft"
+    passphrase="12345678"
+
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    hostapd.add_ap(apdev[0]['ifname'], params)
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    hostapd.add_ap(apdev[1]['ifname'], params)
+
+    run_roams(dev[0], apdev, ssid, passphrase, over_ds=True)
+    check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-4"),
+                        ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-4") ])
+
+def test_ap_ft_pmf_over_ds(dev, apdev):
+    """WPA2-PSK-FT AP over DS with PMF"""
+    ssid = "test-ft"
+    passphrase="12345678"
+
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params["ieee80211w"] = "2";
+    hostapd.add_ap(apdev[0]['ifname'], params)
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params["ieee80211w"] = "2";
+    hostapd.add_ap(apdev[1]['ifname'], params)
+
+    run_roams(dev[0], apdev, ssid, passphrase, over_ds=True)
+
+def test_ap_ft_over_ds_pull(dev, apdev):
+    """WPA2-PSK-FT AP over DS (pull PMK)"""
+    ssid = "test-ft"
+    passphrase="12345678"
+
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params["pmk_r1_push"] = "0"
+    hostapd.add_ap(apdev[0]['ifname'], params)
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params["pmk_r1_push"] = "0"
+    hostapd.add_ap(apdev[1]['ifname'], params)
+
+    run_roams(dev[0], apdev, ssid, passphrase, over_ds=True)
+
+def test_ap_ft_sae(dev, apdev):
+    """WPA2-PSK-FT-SAE AP"""
+    ssid = "test-ft"
+    passphrase="12345678"
+
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] = "FT-SAE"
+    hostapd.add_ap(apdev[0]['ifname'], params)
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] = "FT-SAE"
+    hapd = hostapd.add_ap(apdev[1]['ifname'], params)
+    key_mgmt = hapd.get_config()['key_mgmt']
+    if key_mgmt.split(' ')[0] != "FT-SAE":
+        raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
+
+    run_roams(dev[0], apdev, ssid, passphrase, sae=True)
+
+def test_ap_ft_sae_over_ds(dev, apdev):
+    """WPA2-PSK-FT-SAE AP over DS"""
+    ssid = "test-ft"
+    passphrase="12345678"
+
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] = "FT-SAE"
+    hostapd.add_ap(apdev[0]['ifname'], params)
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] = "FT-SAE"
+    hostapd.add_ap(apdev[1]['ifname'], params)
+
+    run_roams(dev[0], apdev, ssid, passphrase, sae=True, over_ds=True)
+
+def test_ap_ft_eap(dev, apdev):
+    """WPA2-EAP-FT AP"""
+    ssid = "test-ft"
+    passphrase="12345678"
+
+    radius = hostapd.radius_params()
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] = "FT-EAP"
+    params["ieee8021x"] = "1"
+    params = dict(radius.items() + params.items())
+    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    key_mgmt = hapd.get_config()['key_mgmt']
+    if key_mgmt.split(' ')[0] != "FT-EAP":
+        raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] = "FT-EAP"
+    params["ieee8021x"] = "1"
+    params = dict(radius.items() + params.items())
+    hostapd.add_ap(apdev[1]['ifname'], params)
+
+    run_roams(dev[0], apdev, ssid, passphrase, eap=True)
+    if "[WPA2-FT/EAP-CCMP]" not in dev[0].request("SCAN_RESULTS"):
+        raise Exception("Scan results missing RSN element info")
+    check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-3"),
+                        ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-3") ])
+
+def test_ap_ft_eap_pull(dev, apdev):
+    """WPA2-EAP-FT AP (pull PMK)"""
+    ssid = "test-ft"
+    passphrase="12345678"
+
+    radius = hostapd.radius_params()
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] = "FT-EAP"
+    params["ieee8021x"] = "1"
+    params["pmk_r1_push"] = "0"
+    params = dict(radius.items() + params.items())
+    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    key_mgmt = hapd.get_config()['key_mgmt']
+    if key_mgmt.split(' ')[0] != "FT-EAP":
+        raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] = "FT-EAP"
+    params["ieee8021x"] = "1"
+    params["pmk_r1_push"] = "0"
+    params = dict(radius.items() + params.items())
+    hostapd.add_ap(apdev[1]['ifname'], params)
+
+    run_roams(dev[0], apdev, ssid, passphrase, eap=True)
+
+def test_ap_ft_mismatching_rrb_key_push(dev, apdev):
+    """WPA2-PSK-FT AP over DS with mismatching RRB key (push)"""
+    ssid = "test-ft"
+    passphrase="12345678"
+
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params["ieee80211w"] = "2";
+    hostapd.add_ap(apdev[0]['ifname'], params)
+    params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
+    params["ieee80211w"] = "2";
+    hostapd.add_ap(apdev[1]['ifname'], params)
+
+    run_roams(dev[0], apdev, ssid, passphrase, over_ds=True, fail_test=True)
+
+def test_ap_ft_mismatching_rrb_key_pull(dev, apdev):
+    """WPA2-PSK-FT AP over DS with mismatching RRB key (pull)"""
+    ssid = "test-ft"
+    passphrase="12345678"
+
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params["pmk_r1_push"] = "0"
+    hostapd.add_ap(apdev[0]['ifname'], params)
+    params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
+    params["pmk_r1_push"] = "0"
+    hostapd.add_ap(apdev[1]['ifname'], params)
+
+    run_roams(dev[0], apdev, ssid, passphrase, over_ds=True, fail_test=True)
+
+def test_ap_ft_mismatching_rrb_r0kh_push(dev, apdev):
+    """WPA2-PSK-FT AP over DS with mismatching R0KH key (push)"""
+    ssid = "test-ft"
+    passphrase="12345678"
+
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params["ieee80211w"] = "2";
+    hostapd.add_ap(apdev[0]['ifname'], params)
+    params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
+    params["ieee80211w"] = "2";
+    hostapd.add_ap(apdev[1]['ifname'], params)
+
+    run_roams(dev[0], apdev, ssid, passphrase, over_ds=True, fail_test=True)
+
+def test_ap_ft_mismatching_rrb_r0kh_pull(dev, apdev):
+    """WPA2-PSK-FT AP over DS with mismatching R0KH key (pull)"""
+    ssid = "test-ft"
+    passphrase="12345678"
+
+    params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
+    params["pmk_r1_push"] = "0"
+    hostapd.add_ap(apdev[0]['ifname'], params)
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params["pmk_r1_push"] = "0"
+    hostapd.add_ap(apdev[1]['ifname'], params)
+
+    run_roams(dev[0], apdev, ssid, passphrase, over_ds=True, fail_test=True)