]>
git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_erp.py
1 # EAP Re-authentication Protocol (ERP) tests
2 # Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
9 logger
= logging
.getLogger()
14 from utils
import HwsimSkip
15 from test_ap_eap
import int_eap_server_params
16 from test_ap_psk
import find_wpas_process
, read_process_memory
, verify_not_present
, get_key_locations
18 def check_erp_capa(dev
):
19 capab
= dev
.get_capability("erp")
20 if not capab
or 'ERP' not in capab
:
21 raise HwsimSkip("ERP not supported in the build")
23 def test_erp_initiate_reauth_start(dev
, apdev
):
24 """Authenticator sending EAP-Initiate/Re-auth-Start, but ERP disabled on peer"""
25 params
= hostapd
.wpa2_eap_params(ssid
="test-wpa2-eap")
26 params
['erp_send_reauth_start'] = '1'
27 params
['erp_domain'] = 'example.com'
28 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
30 dev
[0].request("ERP_FLUSH")
31 dev
[0].connect("test-wpa2-eap", key_mgmt
="WPA-EAP",
32 eap
="PAX", identity
="pax.user@example.com",
33 password_hex
="0123456789abcdef0123456789abcdef",
36 def test_erp_enabled_on_server(dev
, apdev
):
37 """ERP enabled on internal EAP server, but disabled on peer"""
38 params
= int_eap_server_params()
39 params
['erp_send_reauth_start'] = '1'
40 params
['erp_domain'] = 'example.com'
41 params
['eap_server_erp'] = '1'
42 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
44 dev
[0].request("ERP_FLUSH")
45 dev
[0].connect("test-wpa2-eap", key_mgmt
="WPA-EAP",
46 eap
="PAX", identity
="pax.user@example.com",
47 password_hex
="0123456789abcdef0123456789abcdef",
50 def test_erp(dev
, apdev
):
51 """ERP enabled on server and peer"""
52 check_erp_capa(dev
[0])
53 params
= int_eap_server_params()
54 params
['erp_send_reauth_start'] = '1'
55 params
['erp_domain'] = 'example.com'
56 params
['eap_server_erp'] = '1'
57 params
['disable_pmksa_caching'] = '1'
58 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
60 dev
[0].request("ERP_FLUSH")
61 dev
[0].connect("test-wpa2-eap", key_mgmt
="WPA-EAP",
62 eap
="PSK", identity
="psk.user@example.com",
63 password_hex
="0123456789abcdef0123456789abcdef",
64 erp
="1", scan_freq
="2412")
66 dev
[0].request("DISCONNECT")
67 dev
[0].wait_disconnected(timeout
=15)
68 dev
[0].request("RECONNECT")
69 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout
=15)
71 raise Exception("EAP success timed out")
72 if "EAP re-authentication completed successfully" not in ev
:
73 raise Exception("Did not use ERP")
74 dev
[0].wait_connected(timeout
=15, error
="Reconnection timed out")
76 def test_erp_server_no_match(dev
, apdev
):
77 """ERP enabled on server and peer, but server has no key match"""
78 check_erp_capa(dev
[0])
79 params
= int_eap_server_params()
80 params
['erp_send_reauth_start'] = '1'
81 params
['erp_domain'] = 'example.com'
82 params
['eap_server_erp'] = '1'
83 params
['disable_pmksa_caching'] = '1'
84 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
86 dev
[0].request("ERP_FLUSH")
87 id = dev
[0].connect("test-wpa2-eap", key_mgmt
="WPA-EAP",
88 eap
="PSK", identity
="psk.user@example.com",
89 password_hex
="0123456789abcdef0123456789abcdef",
90 erp
="1", scan_freq
="2412")
91 dev
[0].request("DISCONNECT")
92 dev
[0].wait_disconnected(timeout
=15)
93 hapd
.request("ERP_FLUSH")
94 dev
[0].request("RECONNECT")
95 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-SUCCESS",
96 "CTRL-EVENT-EAP-FAILURE"], timeout
=15)
98 raise Exception("EAP result timed out")
99 if "CTRL-EVENT-EAP-SUCCESS" in ev
:
100 raise Exception("Unexpected EAP success")
101 dev
[0].request("DISCONNECT")
102 dev
[0].select_network(id)
103 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout
=15)
105 raise Exception("EAP success timed out")
106 if "EAP re-authentication completed successfully" in ev
:
107 raise Exception("Unexpected use of ERP")
108 dev
[0].wait_connected(timeout
=15, error
="Reconnection timed out")
110 def start_erp_as(apdev
):
111 params
= { "ssid": "as", "beacon_int": "2000",
112 "radius_server_clients": "auth_serv/radius_clients.conf",
113 "radius_server_auth_port": '18128',
115 "eap_user_file": "auth_serv/eap_user.conf",
116 "ca_cert": "auth_serv/ca.pem",
117 "server_cert": "auth_serv/server.pem",
118 "private_key": "auth_serv/server.key",
119 "eap_sim_db": "unix:/tmp/hlr_auc_gw.sock",
120 "dh_file": "auth_serv/dh.conf",
121 "pac_opaque_encr_key": "000102030405060708090a0b0c0d0e0f",
122 "eap_fast_a_id": "101112131415161718191a1b1c1d1e1f",
123 "eap_fast_a_id_info": "test server",
124 "eap_server_erp": "1",
125 "erp_domain": "example.com" }
126 hostapd
.add_ap(apdev
['ifname'], params
)
128 def test_erp_radius(dev
, apdev
):
129 """ERP enabled on RADIUS server and peer"""
130 check_erp_capa(dev
[0])
131 start_erp_as(apdev
[1])
132 params
= hostapd
.wpa2_eap_params(ssid
="test-wpa2-eap")
133 params
['auth_server_port'] = "18128"
134 params
['erp_send_reauth_start'] = '1'
135 params
['erp_domain'] = 'example.com'
136 params
['disable_pmksa_caching'] = '1'
137 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
139 dev
[0].request("ERP_FLUSH")
140 dev
[0].connect("test-wpa2-eap", key_mgmt
="WPA-EAP",
141 eap
="PSK", identity
="psk.user@example.com",
142 password_hex
="0123456789abcdef0123456789abcdef",
143 erp
="1", scan_freq
="2412")
145 dev
[0].request("DISCONNECT")
146 dev
[0].wait_disconnected(timeout
=15)
147 dev
[0].request("RECONNECT")
148 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout
=15)
150 raise Exception("EAP success timed out")
151 if "EAP re-authentication completed successfully" not in ev
:
152 raise Exception("Did not use ERP")
153 dev
[0].wait_connected(timeout
=15, error
="Reconnection timed out")
155 def erp_test(dev
, hapd
, **kwargs
):
156 res
= dev
.get_capability("eap")
157 if kwargs
['eap'] not in res
:
158 logger
.info("Skip ERP test with %s due to missing support" % kwargs
['eap'])
162 dev
.request("ERP_FLUSH")
163 id = dev
.connect("test-wpa2-eap", key_mgmt
="WPA-EAP", erp
="1",
164 scan_freq
="2412", **kwargs
)
165 dev
.request("DISCONNECT")
166 dev
.wait_disconnected(timeout
=15)
168 dev
.request("RECONNECT")
169 ev
= dev
.wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout
=15)
171 raise Exception("EAP success timed out")
172 if "EAP re-authentication completed successfully" not in ev
:
173 raise Exception("Did not use ERP")
174 dev
.wait_connected(timeout
=15, error
="Reconnection timed out")
175 ev
= hapd
.wait_event([ "AP-STA-CONNECTED" ], timeout
=5)
177 raise Exception("No connection event received from hostapd")
178 dev
.request("DISCONNECT")
180 def test_erp_radius_eap_methods(dev
, apdev
):
181 """ERP enabled on RADIUS server and peer"""
182 check_erp_capa(dev
[0])
183 eap_methods
= dev
[0].get_capability("eap")
184 start_erp_as(apdev
[1])
185 params
= hostapd
.wpa2_eap_params(ssid
="test-wpa2-eap")
186 params
['auth_server_port'] = "18128"
187 params
['erp_send_reauth_start'] = '1'
188 params
['erp_domain'] = 'example.com'
189 params
['disable_pmksa_caching'] = '1'
190 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
192 erp_test(dev
[0], hapd
, eap
="AKA", identity
="0232010000000000@example.com",
193 password
="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123")
194 erp_test(dev
[0], hapd
, eap
="AKA'", identity
="6555444333222111@example.com",
195 password
="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123")
196 erp_test(dev
[0], hapd
, eap
="EKE", identity
="erp-eke@example.com",
198 if "FAST" in eap_methods
:
199 erp_test(dev
[0], hapd
, eap
="FAST", identity
="erp-fast@example.com",
200 password
="password", ca_cert
="auth_serv/ca.pem",
202 phase1
="fast_provisioning=2",
203 pac_file
="blob://fast_pac_auth_erp")
204 erp_test(dev
[0], hapd
, eap
="GPSK", identity
="erp-gpsk@example.com",
205 password
="abcdefghijklmnop0123456789abcdef")
206 erp_test(dev
[0], hapd
, eap
="IKEV2", identity
="erp-ikev2@example.com",
208 erp_test(dev
[0], hapd
, eap
="PAX", identity
="erp-pax@example.com",
209 password_hex
="0123456789abcdef0123456789abcdef")
211 #if "MSCHAPV2" in eap_methods:
212 # erp_test(dev[0], hapd, eap="PEAP", identity="erp-peap@example.com",
213 # password="password", ca_cert="auth_serv/ca.pem",
214 # phase2="auth=MSCHAPV2")
215 erp_test(dev
[0], hapd
, eap
="PSK", identity
="erp-psk@example.com",
216 password_hex
="0123456789abcdef0123456789abcdef")
217 if "PWD" in eap_methods
:
218 erp_test(dev
[0], hapd
, eap
="PWD", identity
="erp-pwd@example.com",
219 password
="secret password")
220 erp_test(dev
[0], hapd
, eap
="SAKE", identity
="erp-sake@example.com",
221 password_hex
="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
222 erp_test(dev
[0], hapd
, eap
="SIM", identity
="1232010000000000@example.com",
223 password
="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
224 erp_test(dev
[0], hapd
, eap
="TLS", identity
="erp-tls@example.com",
225 ca_cert
="auth_serv/ca.pem", client_cert
="auth_serv/user.pem",
226 private_key
="auth_serv/user.key")
227 erp_test(dev
[0], hapd
, eap
="TTLS", identity
="erp-ttls@example.com",
228 password
="password", ca_cert
="auth_serv/ca.pem", phase2
="auth=PAP")
230 def test_erp_key_lifetime_in_memory(dev
, apdev
, params
):
231 """ERP and key lifetime in memory"""
232 check_erp_capa(dev
[0])
233 p
= int_eap_server_params()
234 p
['erp_send_reauth_start'] = '1'
235 p
['erp_domain'] = 'example.com'
236 p
['eap_server_erp'] = '1'
237 p
['disable_pmksa_caching'] = '1'
238 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], p
)
239 password
= "63d2d21ac3c09ed567ee004a34490f1d16e7fa5835edf17ddba70a63f1a90a25"
241 pid
= find_wpas_process(dev
[0])
243 dev
[0].request("ERP_FLUSH")
244 dev
[0].connect("test-wpa2-eap", key_mgmt
="WPA-EAP", eap
="TTLS",
245 identity
="pap-secret@example.com", password
=password
,
246 ca_cert
="auth_serv/ca.pem", phase2
="auth=PAP",
247 erp
="1", scan_freq
="2412")
250 buf
= read_process_memory(pid
, password
)
252 dev
[0].request("DISCONNECT")
253 dev
[0].wait_disconnected(timeout
=15)
263 with
open(os
.path
.join(params
['logdir'], 'log0'), 'r') as f
:
264 for l
in f
.readlines():
265 if "EAP-TTLS: Derived key - hexdump" in l
:
266 val
= l
.strip().split(':')[3].replace(' ', '')
267 msk
= binascii
.unhexlify(val
)
268 if "EAP-TTLS: Derived EMSK - hexdump" in l
:
269 val
= l
.strip().split(':')[3].replace(' ', '')
270 emsk
= binascii
.unhexlify(val
)
271 if "EAP: ERP rRK - hexdump" in l
:
272 val
= l
.strip().split(':')[3].replace(' ', '')
273 rRK
= binascii
.unhexlify(val
)
274 if "EAP: ERP rIK - hexdump" in l
:
275 val
= l
.strip().split(':')[3].replace(' ', '')
276 rIK
= binascii
.unhexlify(val
)
277 if "WPA: PMK - hexdump" in l
:
278 val
= l
.strip().split(':')[3].replace(' ', '')
279 pmk
= binascii
.unhexlify(val
)
280 if "WPA: PTK - hexdump" in l
:
281 val
= l
.strip().split(':')[3].replace(' ', '')
282 ptk
= binascii
.unhexlify(val
)
283 if "WPA: Group Key - hexdump" in l
:
284 val
= l
.strip().split(':')[3].replace(' ', '')
285 gtk
= binascii
.unhexlify(val
)
286 if not msk
or not emsk
or not rIK
or not rRK
or not pmk
or not ptk
or not gtk
:
287 raise Exception("Could not find keys from debug log")
289 raise Exception("Unexpected GTK length")
295 fname
= os
.path
.join(params
['logdir'],
296 'erp_key_lifetime_in_memory.memctx-')
298 logger
.info("Checking keys in memory while associated")
299 get_key_locations(buf
, password
, "Password")
300 get_key_locations(buf
, pmk
, "PMK")
301 get_key_locations(buf
, msk
, "MSK")
302 get_key_locations(buf
, emsk
, "EMSK")
303 get_key_locations(buf
, rRK
, "rRK")
304 get_key_locations(buf
, rIK
, "rIK")
305 if password
not in buf
:
306 raise HwsimSkip("Password not found while associated")
308 raise HwsimSkip("PMK not found while associated")
310 raise Exception("KCK not found while associated")
312 raise Exception("KEK not found while associated")
314 raise Exception("TK found from memory")
316 get_key_locations(buf
, gtk
, "GTK")
317 raise Exception("GTK found from memory")
319 logger
.info("Checking keys in memory after disassociation")
320 buf
= read_process_memory(pid
, password
)
322 # Note: Password is still present in network configuration
323 # Note: PMK is in EAP fast re-auth data
325 get_key_locations(buf
, password
, "Password")
326 get_key_locations(buf
, pmk
, "PMK")
327 get_key_locations(buf
, msk
, "MSK")
328 get_key_locations(buf
, emsk
, "EMSK")
329 get_key_locations(buf
, rRK
, "rRK")
330 get_key_locations(buf
, rIK
, "rIK")
331 verify_not_present(buf
, kck
, fname
, "KCK")
332 verify_not_present(buf
, kek
, fname
, "KEK")
333 verify_not_present(buf
, tk
, fname
, "TK")
334 verify_not_present(buf
, gtk
, fname
, "GTK")
336 dev
[0].request("RECONNECT")
337 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout
=15)
339 raise Exception("EAP success timed out")
340 if "EAP re-authentication completed successfully" not in ev
:
341 raise Exception("Did not use ERP")
342 dev
[0].wait_connected(timeout
=15, error
="Reconnection timed out")
344 dev
[0].request("DISCONNECT")
345 dev
[0].wait_disconnected(timeout
=15)
351 with
open(os
.path
.join(params
['logdir'], 'log0'), 'r') as f
:
352 for l
in f
.readlines():
353 if "WPA: PMK - hexdump" in l
:
354 val
= l
.strip().split(':')[3].replace(' ', '')
355 pmk
= binascii
.unhexlify(val
)
356 if "WPA: PTK - hexdump" in l
:
357 val
= l
.strip().split(':')[3].replace(' ', '')
358 ptk
= binascii
.unhexlify(val
)
359 if "WPA: GTK in EAPOL-Key - hexdump" in l
:
360 val
= l
.strip().split(':')[3].replace(' ', '')
361 gtk
= binascii
.unhexlify(val
)
362 if not pmk
or not ptk
or not gtk
:
363 raise Exception("Could not find keys from debug log")
369 logger
.info("Checking keys in memory after ERP and disassociation")
370 buf
= read_process_memory(pid
, password
)
372 # Note: Password is still present in network configuration
374 get_key_locations(buf
, password
, "Password")
375 get_key_locations(buf
, pmk
, "PMK")
376 get_key_locations(buf
, msk
, "MSK")
377 get_key_locations(buf
, emsk
, "EMSK")
378 get_key_locations(buf
, rRK
, "rRK")
379 get_key_locations(buf
, rIK
, "rIK")
380 verify_not_present(buf
, kck
, fname
, "KCK")
381 verify_not_present(buf
, kek
, fname
, "KEK")
382 verify_not_present(buf
, tk
, fname
, "TK")
383 verify_not_present(buf
, gtk
, fname
, "GTK")
385 dev
[0].request("REMOVE_NETWORK all")
387 logger
.info("Checking keys in memory after network profile removal")
388 buf
= read_process_memory(pid
, password
)
390 # Note: rRK and rIK are still in memory
392 get_key_locations(buf
, password
, "Password")
393 get_key_locations(buf
, pmk
, "PMK")
394 get_key_locations(buf
, msk
, "MSK")
395 get_key_locations(buf
, emsk
, "EMSK")
396 get_key_locations(buf
, rRK
, "rRK")
397 get_key_locations(buf
, rIK
, "rIK")
398 verify_not_present(buf
, password
, fname
, "password")
399 verify_not_present(buf
, pmk
, fname
, "PMK")
400 verify_not_present(buf
, kck
, fname
, "KCK")
401 verify_not_present(buf
, kek
, fname
, "KEK")
402 verify_not_present(buf
, tk
, fname
, "TK")
403 verify_not_present(buf
, gtk
, fname
, "GTK")
404 verify_not_present(buf
, msk
, fname
, "MSK")
405 verify_not_present(buf
, emsk
, fname
, "EMSK")
407 dev
[0].request("ERP_FLUSH")
408 logger
.info("Checking keys in memory after ERP_FLUSH")
409 buf
= read_process_memory(pid
, password
)
410 get_key_locations(buf
, rRK
, "rRK")
411 get_key_locations(buf
, rIK
, "rIK")
412 verify_not_present(buf
, rRK
, fname
, "rRK")
413 verify_not_present(buf
, rIK
, fname
, "rIK")