tests: EAP-pwd protocol tests for invalid EAP-pwd-Commit
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
faddd025c3
commit
2e3849bcf5
1 changed files with 265 additions and 0 deletions
|
@ -6376,6 +6376,271 @@ def test_eap_proto_pwd(dev, apdev):
|
|||
finally:
|
||||
stop_radius_server(srv)
|
||||
|
||||
def test_eap_proto_pwd_invalid_scalar(dev, apdev):
|
||||
"""EAP-pwd protocol tests - invalid server scalar"""
|
||||
check_eap_capa(dev[0], "PWD")
|
||||
run_eap_proto_pwd_invalid_scalar(dev, apdev, 32*b'\0')
|
||||
run_eap_proto_pwd_invalid_scalar(dev, apdev, 31*b'\0' + b'\x01')
|
||||
# Group Order
|
||||
val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")
|
||||
run_eap_proto_pwd_invalid_scalar(dev, apdev, val)
|
||||
# Group Order - 1
|
||||
val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550")
|
||||
run_eap_proto_pwd_invalid_scalar(dev, apdev, val, valid_scalar=True)
|
||||
|
||||
def run_eap_proto_pwd_invalid_scalar(dev, apdev, scalar, valid_scalar=False):
|
||||
global eap_proto_pwd_invalid_scalar_fail
|
||||
eap_proto_pwd_invalid_scalar_fail = False
|
||||
|
||||
def pwd_handler(ctx, req):
|
||||
logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
|
||||
if 'num' not in ctx:
|
||||
ctx['num'] = 0
|
||||
ctx['num'] = ctx['num'] + 1
|
||||
if 'id' not in ctx:
|
||||
ctx['id'] = 1
|
||||
ctx['id'] = (ctx['id'] + 1) % 256
|
||||
idx = 0
|
||||
|
||||
idx += 1
|
||||
if ctx['num'] == idx:
|
||||
logger.info("Test: Valid id exchange")
|
||||
payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
|
||||
return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
|
||||
4 + 1 + len(payload), EAP_TYPE_PWD) + payload
|
||||
idx += 1
|
||||
if ctx['num'] == idx:
|
||||
logger.info("Test: Commit payload with invalid scalar")
|
||||
payload = struct.pack(">B", 0x02) + binascii.unhexlify("67feb2b46d59e6dd3af3a429ec9c04a949337564615d3a2c19bdf6826eb6f5efa303aed86af3a072ed819d518d620adb2659f0e84c4f8b739629db8c93088cfc") + scalar
|
||||
return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
|
||||
4 + 1 + len(payload), EAP_TYPE_PWD) + payload
|
||||
idx += 1
|
||||
if ctx['num'] == idx:
|
||||
logger.info("Confirm message next - should not get here")
|
||||
global eap_proto_pwd_invalid_scalar_fail
|
||||
eap_proto_pwd_invalid_scalar_fail = True
|
||||
payload = struct.pack(">B", 0x03) + 32*b'\0'
|
||||
return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
|
||||
4 + 1 + len(payload), EAP_TYPE_PWD) + payload
|
||||
|
||||
logger.info("No more test responses available - test case completed")
|
||||
return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
|
||||
|
||||
srv = start_radius_server(pwd_handler)
|
||||
|
||||
try:
|
||||
hapd = start_ap(apdev[0])
|
||||
dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
|
||||
|
||||
dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
|
||||
eap="PWD", identity="pwd user",
|
||||
password="secret password",
|
||||
wait_connect=False)
|
||||
ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
|
||||
if ev is None:
|
||||
raise Exception("EAP failure not reported")
|
||||
dev[0].request("REMOVE_NETWORK all")
|
||||
dev[0].wait_disconnected(timeout=1)
|
||||
dev[0].dump_monitor()
|
||||
finally:
|
||||
stop_radius_server(srv)
|
||||
|
||||
if valid_scalar and not eap_proto_pwd_invalid_scalar_fail:
|
||||
raise Exception("Peer did not accept valid EAP-pwd-Commit scalar")
|
||||
if not valid_scalar and eap_proto_pwd_invalid_scalar_fail:
|
||||
raise Exception("Peer did not stop after invalid EAP-pwd-Commit scalar")
|
||||
|
||||
def test_eap_proto_pwd_invalid_element(dev, apdev):
|
||||
"""EAP-pwd protocol tests - invalid server element"""
|
||||
check_eap_capa(dev[0], "PWD")
|
||||
# Invalid x,y coordinates
|
||||
run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x00')
|
||||
run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x00' + 32*b'\x01')
|
||||
run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\x00')
|
||||
run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\xff' + 32*b'\x01')
|
||||
run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\xff')
|
||||
run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\xff')
|
||||
# Not on curve
|
||||
run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x01')
|
||||
|
||||
def run_eap_proto_pwd_invalid_element(dev, apdev, element):
|
||||
global eap_proto_pwd_invalid_element_fail
|
||||
eap_proto_pwd_invalid_element_fail = False
|
||||
|
||||
def pwd_handler(ctx, req):
|
||||
logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
|
||||
if 'num' not in ctx:
|
||||
ctx['num'] = 0
|
||||
ctx['num'] = ctx['num'] + 1
|
||||
if 'id' not in ctx:
|
||||
ctx['id'] = 1
|
||||
ctx['id'] = (ctx['id'] + 1) % 256
|
||||
idx = 0
|
||||
|
||||
idx += 1
|
||||
if ctx['num'] == idx:
|
||||
logger.info("Test: Valid id exchange")
|
||||
payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
|
||||
return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
|
||||
4 + 1 + len(payload), EAP_TYPE_PWD) + payload
|
||||
idx += 1
|
||||
if ctx['num'] == idx:
|
||||
logger.info("Test: Commit payload with invalid element")
|
||||
payload = struct.pack(">B", 0x02) + element + 31*b'\0' + b'\x02'
|
||||
return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
|
||||
4 + 1 + len(payload), EAP_TYPE_PWD) + payload
|
||||
idx += 1
|
||||
if ctx['num'] == idx:
|
||||
logger.info("Confirm message next - should not get here")
|
||||
global eap_proto_pwd_invalid_element_fail
|
||||
eap_proto_pwd_invalid_element_fail = True
|
||||
payload = struct.pack(">B", 0x03) + 32*b'\0'
|
||||
return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
|
||||
4 + 1 + len(payload), EAP_TYPE_PWD) + payload
|
||||
|
||||
logger.info("No more test responses available - test case completed")
|
||||
return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
|
||||
|
||||
srv = start_radius_server(pwd_handler)
|
||||
|
||||
try:
|
||||
hapd = start_ap(apdev[0])
|
||||
dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
|
||||
|
||||
dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
|
||||
eap="PWD", identity="pwd user",
|
||||
password="secret password",
|
||||
wait_connect=False)
|
||||
ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
|
||||
if ev is None:
|
||||
raise Exception("EAP failure not reported")
|
||||
dev[0].request("REMOVE_NETWORK all")
|
||||
dev[0].wait_disconnected(timeout=1)
|
||||
dev[0].dump_monitor()
|
||||
finally:
|
||||
stop_radius_server(srv)
|
||||
|
||||
if eap_proto_pwd_invalid_element_fail:
|
||||
raise Exception("Peer did not stop after invalid EAP-pwd-Commit element")
|
||||
|
||||
def rx_msg(src):
|
||||
ev = src.wait_event(["EAPOL-TX"], timeout=5)
|
||||
if ev is None:
|
||||
raise Exception("No EAPOL-TX")
|
||||
return ev.split(' ')[2]
|
||||
|
||||
def tx_msg(src, dst, msg):
|
||||
dst.request("EAPOL_RX " + src.own_addr() + " " + msg)
|
||||
|
||||
def proxy_msg(src, dst):
|
||||
msg = rx_msg(src)
|
||||
tx_msg(src, dst, msg)
|
||||
return msg
|
||||
|
||||
def start_pwd_exchange(dev, ap):
|
||||
check_eap_capa(dev, "PWD")
|
||||
params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
|
||||
hapd = hostapd.add_ap(ap, params)
|
||||
hapd.request("SET ext_eapol_frame_io 1")
|
||||
dev.request("SET ext_eapol_frame_io 1")
|
||||
dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP",
|
||||
eap="PWD", identity="pwd user", password="secret password",
|
||||
wait_connect=False, scan_freq="2412")
|
||||
proxy_msg(hapd, dev) # EAP-Identity/Request
|
||||
proxy_msg(dev, hapd) # EAP-Identity/Response
|
||||
proxy_msg(hapd, dev) # EAP-pwd-ID/Request
|
||||
proxy_msg(dev, hapd) # EAP-pwd-ID/Response
|
||||
return hapd
|
||||
|
||||
def test_eap_proto_pwd_reflection_attack(dev, apdev):
|
||||
"""EAP-pwd protocol tests - reflection attack on the server"""
|
||||
hapd = start_pwd_exchange(dev[0], apdev[0])
|
||||
|
||||
# EAP-pwd-Commit/Request
|
||||
req = proxy_msg(hapd, dev[0])
|
||||
if len(req) != 212:
|
||||
raise Exception("Unexpected EAP-pwd-Commit/Response length")
|
||||
|
||||
# EAP-pwd-Commit/Response
|
||||
resp = rx_msg(dev[0])
|
||||
# Reflect same Element/Scalar back to the server
|
||||
msg = resp[0:20] + req[20:]
|
||||
tx_msg(dev[0], hapd, msg)
|
||||
|
||||
# EAP-pwd-Commit/Response or EAP-Failure
|
||||
req = rx_msg(hapd)
|
||||
if req[8:10] != "04":
|
||||
# reflect EAP-pwd-Confirm/Request
|
||||
msg = req[0:8] + "02" + req[10:]
|
||||
tx_msg(dev[0], hapd, msg)
|
||||
req = rx_msg(hapd)
|
||||
if req[8:10] == "03":
|
||||
raise Exception("EAP-Success after reflected Element/Scalar")
|
||||
raise Exception("No EAP-Failure to reject invalid EAP-pwd-Commit/Response")
|
||||
|
||||
def test_eap_proto_pwd_invalid_scalar_peer(dev, apdev):
|
||||
"""EAP-pwd protocol tests - invalid peer scalar"""
|
||||
run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 32*"00")
|
||||
run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 31*"00" + "01")
|
||||
# Group Order
|
||||
run_eap_proto_pwd_invalid_scalar_peer(dev, apdev,
|
||||
"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")
|
||||
# Group Order - 1
|
||||
run_eap_proto_pwd_invalid_scalar_peer(dev, apdev,
|
||||
"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550",
|
||||
valid_scalar=True)
|
||||
|
||||
def run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, scalar,
|
||||
valid_scalar=False):
|
||||
hapd = start_pwd_exchange(dev[0], apdev[0])
|
||||
proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
|
||||
|
||||
# EAP-pwd-Commit/Response
|
||||
resp = rx_msg(dev[0])
|
||||
# Replace scalar with an invalid value
|
||||
msg = resp[0:20] + resp[20:148] + scalar
|
||||
tx_msg(dev[0], hapd, msg)
|
||||
|
||||
# EAP-pwd-Commit/Response or EAP-Failure
|
||||
req = rx_msg(hapd)
|
||||
if valid_scalar and req[8:10] == "04":
|
||||
raise Exception("Unexpected EAP-Failure with valid scalar")
|
||||
if not valid_scalar and req[8:10] != "04":
|
||||
raise Exception("No EAP-Failure to reject invalid scalar")
|
||||
dev[0].request("REMOVE_NETWORK all")
|
||||
dev[0].wait_disconnected(timeout=1)
|
||||
hapd.disable()
|
||||
|
||||
def test_eap_proto_pwd_invalid_element_peer(dev, apdev):
|
||||
"""EAP-pwd protocol tests - invalid peer element"""
|
||||
# Invalid x,y coordinates
|
||||
run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'00')
|
||||
run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'00' + 32*'01')
|
||||
run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'00')
|
||||
run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'ff' + 32*'01')
|
||||
run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'ff')
|
||||
run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'ff')
|
||||
# Not on curve
|
||||
run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'01')
|
||||
|
||||
def run_eap_proto_pwd_invalid_element_peer(dev, apdev, element):
|
||||
hapd = start_pwd_exchange(dev[0], apdev[0])
|
||||
proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
|
||||
|
||||
# EAP-pwd-Commit/Response
|
||||
resp = rx_msg(dev[0])
|
||||
# Replace element with an invalid value
|
||||
msg = resp[0:20] + element + resp[148:]
|
||||
tx_msg(dev[0], hapd, msg)
|
||||
|
||||
# EAP-pwd-Commit/Response or EAP-Failure
|
||||
req = rx_msg(hapd)
|
||||
if req[8:10] != "04":
|
||||
raise Exception("No EAP-Failure to reject invalid element")
|
||||
dev[0].request("REMOVE_NETWORK all")
|
||||
dev[0].wait_disconnected(timeout=1)
|
||||
hapd.disable()
|
||||
|
||||
def test_eap_proto_pwd_errors(dev, apdev):
|
||||
"""EAP-pwd local error cases"""
|
||||
check_eap_capa(dev[0], "PWD")
|
||||
|
|
Loading…
Reference in a new issue