[PATCHv2 2/2] test: SAE password with Tunnel-Password
michael-dev at fami-braun.de
michael-dev at fami-braun.de
Fri Apr 16 12:03:23 BST 2021
From: Michael Braun <michael-dev at fami-braun.de>
Signed-off-by: Michael Braun <michael-dev at fami-braun.de>
---
tests/hwsim/dictionary.radius | 1 +
tests/hwsim/test_radius.py | 190 ++++++++++++++++++++++++++++++++--
2 files changed, 185 insertions(+), 6 deletions(-)
diff --git a/tests/hwsim/dictionary.radius b/tests/hwsim/dictionary.radius
index d2112dad3..923c1220e 100644
--- a/tests/hwsim/dictionary.radius
+++ b/tests/hwsim/dictionary.radius
@@ -17,4 +17,5 @@ ATTRIBUTE Message-Authenticator 80 octets
ATTRIBUTE Tunnel-Private-Group-ID 81 string
ATTRIBUTE Acct-Interim-Interval 85 integer
ATTRIBUTE Chargeable-User-Identity 89 string
+ATTRIBUTE Tunnel-Client-Auth-ID 90 octets
ATTRIBUTE Error-Cause 101 integer
diff --git a/tests/hwsim/test_radius.py b/tests/hwsim/test_radius.py
index ca96c979e..29820fe67 100644
--- a/tests/hwsim/test_radius.py
+++ b/tests/hwsim/test_radius.py
@@ -1148,7 +1148,7 @@ def test_radius_protocol(dev, apdev):
t_events['stop'].set()
t.join()
-def build_tunnel_password(secret, authenticator, psk):
+def build_tunnel_password(secret, authenticator, psk, tag=b'\x00'):
a = b"\xab\xcd"
psk = psk.encode()
padlen = 16 - (1 + len(psk)) % 16
@@ -1164,11 +1164,14 @@ def build_tunnel_password(secret, authenticator, psk):
cc = bytearray(pp[i] ^ bb[i] for i in range(len(bb)))
cc_all += cc
b = hashlib.md5(secret + cc).digest()
- data = b'\x00' + a + bytes(cc_all)
+ data = tag + a + bytes(cc_all)
return data
+def build_tunnel_identity(id, tag=b'\x00'):
+ return tag + id.encode()
+
def start_radius_psk_server(psk, invalid_code=False, acct_interim_interval=0,
- session_timeout=0, reject=False):
+ session_timeout=0, reject=False, sae_identity=[]):
try:
import pyrad.server
import pyrad.packet
@@ -1186,15 +1189,24 @@ def start_radius_psk_server(psk, invalid_code=False, acct_interim_interval=0,
reply.code = pyrad.packet.AccessRequest
if self.t_events['reject']:
reply.code = pyrad.packet.AccessReject
- data = build_tunnel_password(reply.secret, pkt.authenticator,
- self.t_events['psk'])
- reply.AddAttribute("Tunnel-Password", data)
+ psk = self.t_events['psk']
+ if not isinstance(psk, list):
+ psk=[psk]
+ for i in range(len(psk)):
+ data = build_tunnel_password(reply.secret, pkt.authenticator,
+ psk[i], bytes([i]))
+ reply.AddAttribute("Tunnel-Password", data)
+ for i in range(len(self.t_events['sae_identity'])):
+ for sae_identity in self.t_events['sae_identity'][i]:
+ data = build_tunnel_identity(sae_identity, bytes([i]))
+ reply.AddAttribute("Tunnel-Client-Auth-ID", data)
if self.t_events['acct_interim_interval']:
reply.AddAttribute("Acct-Interim-Interval",
self.t_events['acct_interim_interval'])
if self.t_events['session_timeout']:
reply.AddAttribute("Session-Timeout",
self.t_events['session_timeout'])
+
self.SendReplyPacket(pkt.fd, reply)
def RunWithStop(self, t_events):
@@ -1225,9 +1237,11 @@ def start_radius_psk_server(psk, invalid_code=False, acct_interim_interval=0,
b"radius",
"localhost")
srv.BindToAddress("")
+
t_events = {}
t_events['stop'] = threading.Event()
t_events['psk'] = psk
+ t_events['sae_identity'] = sae_identity
t_events['invalid_code'] = invalid_code
t_events['acct_interim_interval'] = acct_interim_interval
t_events['session_timeout'] = session_timeout
@@ -1247,6 +1261,28 @@ def hostapd_radius_psk_test_params():
params['auth_server_port'] = "18138"
return params
+def hostapd_radius_sae_test_params():
+ params = hostapd.radius_params()
+ params['ssid'] = "test-wpa3-sae"
+ params["wpa"] = "2"
+ params["wpa_key_mgmt"] = "SAE"
+ params["rsn_pairwise"] = "CCMP"
+ params['macaddr_acl'] = '2'
+ params['wpa_psk_radius'] = '2'
+ params['auth_server_port'] = "18138"
+ return params
+
+def hostapd_radius_sae_ft_test_params():
+ params = hostapd.radius_params()
+ params['ssid'] = "test-wpa3-sae-ft"
+ params["wpa"] = "2"
+ params["wpa_key_mgmt"] = "FT-SAE"
+ params["rsn_pairwise"] = "CCMP"
+ params['macaddr_acl'] = '2'
+ params['wpa_psk_radius'] = '2'
+ params['auth_server_port'] = "18138"
+ return params
+
def test_radius_psk(dev, apdev):
"""WPA2 with PSK from RADIUS"""
t, t_events = start_radius_psk_server("12345678")
@@ -1262,6 +1298,35 @@ def test_radius_psk(dev, apdev):
t_events['stop'].set()
t.join()
+def test_radius_psk_multi(dev, apdev):
+ """WPA2 with PSK from RADIUS"""
+ t, t_events = start_radius_psk_server(psk=["12345678","abcdefgh"])
+
+ try:
+ params = hostapd_radius_psk_test_params()
+ hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412")
+ dev[1].connect("test-wpa2-psk", psk="abcdefgh", scan_freq="2412")
+ finally:
+ t_events['stop'].set()
+ t.join()
+
+
+def test_radius_psk_duplicate(dev, apdev):
+ """WPA2 with PSK from RADIUS with duplicate psk"""
+ t, t_events = start_radius_psk_server(psk=["12345678","12345678","abcdefgh", "abcdefgh"])
+
+ try:
+ params = hostapd_radius_psk_test_params()
+ hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412",
+ key_mgmt="WPA-PSK")
+ dev[1].connect("test-wpa2-psk", psk="abcdefgh", scan_freq="2412",
+ key_mgmt="WPA-PSK")
+ finally:
+ t_events['stop'].set()
+ t.join()
+
def test_radius_psk_invalid(dev, apdev):
"""WPA2 with invalid PSK from RADIUS"""
t, t_events = start_radius_psk_server("1234567")
@@ -1303,6 +1368,20 @@ def test_radius_psk_hex_psk(dev, apdev):
t_events['stop'].set()
t.join()
+def test_radius_psk_hex_psk_multi(dev, apdev):
+ """WPA2 with PSK hexstring from RADIUS (multiple values)"""
+ t, t_events = start_radius_psk_server(psk=[64*'2', 64*'a'], acct_interim_interval=19,
+ session_timeout=123)
+
+ try:
+ params = hostapd_radius_psk_test_params()
+ hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].connect("test-wpa2-psk", raw_psk=64*'2', scan_freq="2412")
+ dev[1].connect("test-wpa2-psk", raw_psk=64*'a', scan_freq="2412")
+ finally:
+ t_events['stop'].set()
+ t.join()
+
def test_radius_psk_unknown_code(dev, apdev):
"""WPA2 with PSK from RADIUS and unknown code"""
t, t_events = start_radius_psk_server(64*'2', invalid_code=True)
@@ -1708,3 +1787,102 @@ def test_radius_acct_failure_sta_data(dev, apdev):
dev[0].request("DISCONNECT")
dev[0].wait_disconnected()
hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=1)
+
+def test_radius_sae(dev, apdev):
+ """WPA3 with SAE from RADIUS"""
+ t, t_events = start_radius_psk_server("12345678")
+
+ try:
+ params = hostapd_radius_sae_test_params()
+ hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].connect("test-wpa3-sae", sae_password="12345678", key_mgmt="SAE",
+ scan_freq="2412")
+ t_events['psk'] = "0123456789abcdef"
+ dev[1].connect("test-wpa3-sae", sae_password="0123456789abcdef", key_mgmt="SAE",
+ scan_freq="2412")
+ finally:
+ t_events['stop'].set()
+ t.join()
+
+def test_radius_sae_ft(dev, apdev):
+ """WPA3 with FT-SAE from RADIUS"""
+ t, t_events = start_radius_psk_server("12345678")
+
+ try:
+ params = hostapd_radius_sae_ft_test_params()
+ hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].connect("test-wpa3-sae-ft", sae_password="12345678", key_mgmt="FT-SAE",
+ scan_freq="2412")
+ t_events['psk'] = "0123456789abcdef"
+ dev[1].connect("test-wpa3-sae-ft", sae_password="0123456789abcdef", key_mgmt="FT-SAE",
+ scan_freq="2412")
+ finally:
+ t_events['stop'].set()
+ t.join()
+
+def test_radius_sae_id(dev, apdev):
+ """WPA3 with SAE from RADIUS with SAE password identity"""
+ t, t_events = start_radius_psk_server(psk=["12345678"], sae_identity=[["user0"]])
+
+ try:
+ params = hostapd_radius_sae_test_params()
+ hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].connect("test-wpa3-sae", key_mgmt="SAE", scan_freq="2412",
+ sae_password="12345678", sae_password_id="user0")
+ t_events['psk'] = ["0123456789abcdef"]
+ t_events['sae_identity'] = [["user1"]]
+ dev[1].connect("test-wpa3-sae", key_mgmt="SAE", scan_freq="2412",
+ sae_password="0123456789abcdef", sae_password_id="user1")
+ finally:
+ t_events['stop'].set()
+ t.join()
+
+def test_radius_sae_id_ft(dev, apdev):
+ """WPA3 with FT-SAE from RADIUS with SAE password identity"""
+ t, t_events = start_radius_psk_server(psk=["12345678"], sae_identity=[["user0"]])
+
+ try:
+ params = hostapd_radius_sae_ft_test_params()
+ hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].connect("test-wpa3-sae-ft", key_mgmt="FT-SAE", scan_freq="2412",
+ sae_password="12345678", sae_password_id="user0")
+ t_events['psk'] = ["0123456789abcdef"]
+ t_events['sae_identity'] = [["user1"]]
+ dev[1].connect("test-wpa3-sae-ft", key_mgmt="FT-SAE", scan_freq="2412",
+ sae_password="0123456789abcdef", sae_password_id="user1")
+ finally:
+ t_events['stop'].set()
+ t.join()
+
+def test_radius_sae_multi_id(dev, apdev):
+ """WPA3 with SAE from RADIUS with multiple SAE password identity for one password"""
+ t, t_events = start_radius_psk_server(psk=["12345678"],
+ sae_identity=[["user0","user1"]])
+
+ try:
+ params = hostapd_radius_sae_test_params()
+ hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].connect("test-wpa3-sae", key_mgmt="SAE", scan_freq="2412",
+ sae_password="12345678", sae_password_id="user0")
+ dev[0].connect("test-wpa3-sae", key_mgmt="SAE", scan_freq="2412",
+ sae_password="12345678", sae_password_id="user1")
+ finally:
+ t_events['stop'].set()
+ t.join()
+
+def test_radius_sae_multi_user(dev, apdev):
+ """WPA3 with SAE from RADIUS with multiple SAE password identity for multiple passwords"""
+ t, t_events = start_radius_psk_server(psk=["12345678","abcdefgh"],
+ sae_identity=[["user0"],["user1"]])
+
+ try:
+ params = hostapd_radius_sae_test_params()
+ hapd = hostapd.add_ap(apdev[0], params)
+ dev[0].connect("test-wpa3-sae", key_mgmt="SAE", scan_freq="2412",
+ sae_password="12345678", sae_password_id="user0")
+ dev[0].connect("test-wpa3-sae", key_mgmt="SAE", scan_freq="2412",
+ sae_password="abcdefgh", sae_password_id="user1")
+ finally:
+ t_events['stop'].set()
+ t.join()
+
--
2.20.1
More information about the Hostap
mailing list