]>
Commit | Line | Data |
---|---|---|
d81731e6 | 1 | # EAP protocol tests |
e7ac04ce | 2 | # Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi> |
d81731e6 JM |
3 | # |
4 | # This software may be distributed under the terms of the BSD license. | |
5 | # See README for more details. | |
6 | ||
37211e15 JM |
7 | import binascii |
8 | import hashlib | |
d81731e6 JM |
9 | import hmac |
10 | import logging | |
11 | logger = logging.getLogger() | |
12 | import select | |
13 | import struct | |
14 | import threading | |
15 | import time | |
16 | ||
17 | import hostapd | |
d5482411 | 18 | from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger |
d36ae376 | 19 | from test_ap_eap import check_eap_capa, check_hlr_auc_gw_support |
b6f17f2f | 20 | from test_erp import check_erp_capa |
d81731e6 JM |
21 | |
22 | EAP_CODE_REQUEST = 1 | |
23 | EAP_CODE_RESPONSE = 2 | |
24 | EAP_CODE_SUCCESS = 3 | |
25 | EAP_CODE_FAILURE = 4 | |
b6f17f2f JM |
26 | EAP_CODE_INITIATE = 5 |
27 | EAP_CODE_FINISH = 6 | |
d81731e6 JM |
28 | |
29 | EAP_TYPE_IDENTITY = 1 | |
30 | EAP_TYPE_NOTIFICATION = 2 | |
31 | EAP_TYPE_NAK = 3 | |
32 | EAP_TYPE_MD5 = 4 | |
33 | EAP_TYPE_OTP = 5 | |
34 | EAP_TYPE_GTC = 6 | |
35 | EAP_TYPE_TLS = 13 | |
36 | EAP_TYPE_LEAP = 17 | |
37 | EAP_TYPE_SIM = 18 | |
38 | EAP_TYPE_TTLS = 21 | |
39 | EAP_TYPE_AKA = 23 | |
40 | EAP_TYPE_PEAP = 25 | |
41 | EAP_TYPE_MSCHAPV2 = 26 | |
42 | EAP_TYPE_TLV = 33 | |
43 | EAP_TYPE_TNC = 38 | |
44 | EAP_TYPE_FAST = 43 | |
45 | EAP_TYPE_PAX = 46 | |
46 | EAP_TYPE_PSK = 47 | |
47 | EAP_TYPE_SAKE = 48 | |
48 | EAP_TYPE_IKEV2 = 49 | |
49 | EAP_TYPE_AKA_PRIME = 50 | |
50 | EAP_TYPE_GPSK = 51 | |
51 | EAP_TYPE_PWD = 52 | |
52 | EAP_TYPE_EKE = 53 | |
2fd377de | 53 | EAP_TYPE_EXPANDED = 254 |
d81731e6 | 54 | |
b6f17f2f JM |
55 | # Type field in EAP-Initiate and EAP-Finish messages |
56 | EAP_ERP_TYPE_REAUTH_START = 1 | |
57 | EAP_ERP_TYPE_REAUTH = 2 | |
58 | ||
59 | EAP_ERP_TLV_KEYNAME_NAI = 1 | |
60 | EAP_ERP_TV_RRK_LIFETIME = 2 | |
61 | EAP_ERP_TV_RMSK_LIFETIME = 3 | |
62 | EAP_ERP_TLV_DOMAIN_NAME = 4 | |
63 | EAP_ERP_TLV_CRYPTOSUITES = 5 | |
64 | EAP_ERP_TLV_AUTHORIZATION_INDICATION = 6 | |
65 | EAP_ERP_TLV_CALLED_STATION_ID = 128 | |
66 | EAP_ERP_TLV_CALLING_STATION_ID = 129 | |
67 | EAP_ERP_TLV_NAS_IDENTIFIER = 130 | |
68 | EAP_ERP_TLV_NAS_IP_ADDRESS = 131 | |
69 | EAP_ERP_TLV_NAS_IPV6_ADDRESS = 132 | |
70 | ||
d81731e6 JM |
71 | def run_pyrad_server(srv, t_stop, eap_handler): |
72 | srv.RunWithStop(t_stop, eap_handler) | |
73 | ||
74 | def start_radius_server(eap_handler): | |
75 | try: | |
76 | import pyrad.server | |
77 | import pyrad.packet | |
78 | import pyrad.dictionary | |
79 | except ImportError: | |
81e787b7 | 80 | raise HwsimSkip("No pyrad modules available") |
d81731e6 JM |
81 | |
82 | class TestServer(pyrad.server.Server): | |
83 | def _HandleAuthPacket(self, pkt): | |
84 | pyrad.server.Server._HandleAuthPacket(self, pkt) | |
37211e15 JM |
85 | eap = "" |
86 | for p in pkt[79]: | |
87 | eap += p | |
d81731e6 JM |
88 | eap_req = self.eap_handler(self.ctx, eap) |
89 | reply = self.CreateReplyPacket(pkt) | |
90 | if eap_req: | |
cb0555f7 JM |
91 | while True: |
92 | if len(eap_req) > 253: | |
93 | reply.AddAttribute("EAP-Message", eap_req[0:253]) | |
94 | eap_req = eap_req[253:] | |
95 | else: | |
96 | reply.AddAttribute("EAP-Message", eap_req) | |
97 | break | |
18fc8f40 JM |
98 | else: |
99 | logger.info("No EAP request available") | |
d81731e6 JM |
100 | reply.code = pyrad.packet.AccessChallenge |
101 | ||
102 | hmac_obj = hmac.new(reply.secret) | |
103 | hmac_obj.update(struct.pack("B", reply.code)) | |
104 | hmac_obj.update(struct.pack("B", reply.id)) | |
105 | ||
106 | # reply attributes | |
107 | reply.AddAttribute("Message-Authenticator", | |
108 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") | |
109 | attrs = reply._PktEncodeAttributes() | |
110 | ||
111 | # Length | |
112 | flen = 4 + 16 + len(attrs) | |
113 | hmac_obj.update(struct.pack(">H", flen)) | |
114 | hmac_obj.update(pkt.authenticator) | |
115 | hmac_obj.update(attrs) | |
116 | del reply[80] | |
117 | reply.AddAttribute("Message-Authenticator", hmac_obj.digest()) | |
118 | ||
119 | self.SendReplyPacket(pkt.fd, reply) | |
120 | ||
121 | def RunWithStop(self, t_stop, eap_handler): | |
122 | self._poll = select.poll() | |
123 | self._fdmap = {} | |
124 | self._PrepareSockets() | |
125 | self.t_stop = t_stop | |
126 | self.eap_handler = eap_handler | |
127 | self.ctx = {} | |
128 | ||
129 | while not t_stop.is_set(): | |
8a848fae | 130 | for (fd, event) in self._poll.poll(200): |
d81731e6 JM |
131 | if event == select.POLLIN: |
132 | try: | |
133 | fdo = self._fdmap[fd] | |
134 | self._ProcessInput(fdo) | |
135 | except pyrad.server.ServerPacketError as err: | |
136 | logger.info("pyrad server dropping packet: " + str(err)) | |
137 | except pyrad.packet.PacketError as err: | |
138 | logger.info("pyrad server received invalid packet: " + str(err)) | |
139 | else: | |
140 | logger.error("Unexpected event in pyrad server main loop") | |
141 | ||
142 | srv = TestServer(dict=pyrad.dictionary.Dictionary("dictionary.radius"), | |
143 | authport=18138, acctport=18139) | |
144 | srv.hosts["127.0.0.1"] = pyrad.server.RemoteHost("127.0.0.1", | |
145 | "radius", | |
146 | "localhost") | |
147 | srv.BindToAddress("") | |
148 | t_stop = threading.Event() | |
149 | t = threading.Thread(target=run_pyrad_server, args=(srv, t_stop, eap_handler)) | |
150 | t.start() | |
151 | ||
152 | return { 'srv': srv, 'stop': t_stop, 'thread': t } | |
153 | ||
154 | def stop_radius_server(srv): | |
155 | srv['stop'].set() | |
156 | srv['thread'].join() | |
157 | ||
158 | def start_ap(ifname): | |
159 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
160 | params['auth_server_port'] = "18138" | |
161 | hapd = hostapd.add_ap(ifname, params) | |
162 | return hapd | |
163 | ||
2eae05f7 JM |
164 | def test_eap_proto(dev, apdev): |
165 | """EAP protocol tests""" | |
e7ac04ce | 166 | check_eap_capa(dev[0], "MD5") |
2eae05f7 JM |
167 | def eap_handler(ctx, req): |
168 | logger.info("eap_handler - RX " + req.encode("hex")) | |
169 | if 'num' not in ctx: | |
170 | ctx['num'] = 0 | |
171 | ctx['num'] = ctx['num'] + 1 | |
172 | if 'id' not in ctx: | |
173 | ctx['id'] = 1 | |
174 | ctx['id'] = (ctx['id'] + 1) % 256 | |
175 | idx = 0 | |
176 | ||
177 | idx += 1 | |
178 | if ctx['num'] == idx: | |
179 | logger.info("Test: MD5 challenge") | |
180 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
181 | 4 + 1 + 3, | |
182 | EAP_TYPE_MD5, | |
183 | 1, 0xaa, ord('n')) | |
184 | idx += 1 | |
185 | if ctx['num'] == idx: | |
186 | logger.info("Test: EAP-Success - id off by 2") | |
187 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] + 1, 4) | |
188 | ||
189 | idx += 1 | |
190 | if ctx['num'] == idx: | |
191 | logger.info("Test: MD5 challenge") | |
192 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
193 | 4 + 1 + 3, | |
194 | EAP_TYPE_MD5, | |
195 | 1, 0xaa, ord('n')) | |
196 | idx += 1 | |
197 | if ctx['num'] == idx: | |
198 | logger.info("Test: EAP-Success - id off by 3") | |
199 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] + 2, 4) | |
200 | ||
201 | idx += 1 | |
202 | if ctx['num'] == idx: | |
203 | logger.info("Test: MD5 challenge") | |
204 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
205 | 4 + 1 + 3, | |
206 | EAP_TYPE_MD5, | |
207 | 1, 0xaa, ord('n')) | |
208 | idx += 1 | |
209 | if ctx['num'] == idx: | |
210 | logger.info("Test: EAP-Notification/Request") | |
211 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
212 | 4 + 1 + 1, | |
213 | EAP_TYPE_NOTIFICATION, | |
214 | ord('A')) | |
215 | idx += 1 | |
216 | if ctx['num'] == idx: | |
217 | logger.info("Test: EAP-Success") | |
218 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4) | |
219 | ||
220 | idx += 1 | |
221 | if ctx['num'] == idx: | |
222 | logger.info("Test: EAP-Notification/Request") | |
223 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
224 | 4 + 1 + 1, | |
225 | EAP_TYPE_NOTIFICATION, | |
226 | ord('B')) | |
227 | idx += 1 | |
228 | if ctx['num'] == idx: | |
229 | logger.info("Test: MD5 challenge") | |
230 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
231 | 4 + 1 + 3, | |
232 | EAP_TYPE_MD5, | |
233 | 1, 0xaa, ord('n')) | |
234 | idx += 1 | |
235 | if ctx['num'] == idx: | |
236 | logger.info("Test: EAP-Success") | |
237 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4) | |
238 | ||
239 | idx += 1 | |
240 | if ctx['num'] == idx: | |
241 | logger.info("Test: EAP-Notification/Request") | |
242 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
243 | 4 + 1 + 1, | |
244 | EAP_TYPE_NOTIFICATION, | |
245 | ord('C')) | |
246 | idx += 1 | |
247 | if ctx['num'] == idx: | |
248 | logger.info("Test: MD5 challenge") | |
249 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
250 | 4 + 1 + 3, | |
251 | EAP_TYPE_MD5, | |
252 | 1, 0xaa, ord('n')) | |
253 | idx += 1 | |
254 | if ctx['num'] == idx: | |
255 | logger.info("Test: EAP-Notification/Request") | |
256 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
257 | 4 + 1 + 1, | |
258 | EAP_TYPE_NOTIFICATION, | |
259 | ord('D')) | |
260 | idx += 1 | |
261 | if ctx['num'] == idx: | |
262 | logger.info("Test: EAP-Success") | |
263 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4) | |
264 | ||
265 | idx += 1 | |
266 | if ctx['num'] == idx: | |
267 | logger.info("Test: EAP-Notification/Request") | |
268 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
269 | 4 + 1 + 1, | |
270 | EAP_TYPE_NOTIFICATION, | |
271 | ord('E')) | |
272 | idx += 1 | |
273 | if ctx['num'] == idx: | |
274 | logger.info("Test: EAP-Notification/Request (same id)") | |
275 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'] - 1, | |
276 | 4 + 1 + 1, | |
277 | EAP_TYPE_NOTIFICATION, | |
278 | ord('F')) | |
279 | idx += 1 | |
280 | if ctx['num'] == idx: | |
281 | logger.info("Test: Unexpected EAP-Success") | |
282 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 2, 4) | |
283 | ||
284 | return None | |
285 | ||
286 | srv = start_radius_server(eap_handler) | |
2eae05f7 JM |
287 | |
288 | try: | |
289 | hapd = start_ap(apdev[0]['ifname']) | |
290 | ||
291 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
292 | eap="MD5", identity="user", password="password", | |
293 | wait_connect=False) | |
294 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
295 | if ev is None: | |
296 | raise Exception("Timeout on EAP start") | |
297 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) | |
298 | if ev is None: | |
299 | raise Exception("Timeout on EAP success") | |
300 | dev[0].request("REMOVE_NETWORK all") | |
301 | ||
302 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
303 | eap="MD5", identity="user", password="password", | |
304 | wait_connect=False) | |
305 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
306 | if ev is None: | |
307 | raise Exception("Timeout on EAP start") | |
308 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=1) | |
309 | if ev is not None: | |
310 | raise Exception("Unexpected EAP success") | |
311 | dev[0].request("REMOVE_NETWORK all") | |
312 | ||
313 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
314 | eap="MD5", identity="user", password="password", | |
315 | wait_connect=False) | |
316 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
317 | if ev is None: | |
318 | raise Exception("Timeout on EAP start") | |
319 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) | |
320 | if ev is None: | |
321 | raise Exception("Timeout on EAP notification") | |
322 | if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION A": | |
323 | raise Exception("Unexpected notification contents: " + ev) | |
324 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) | |
325 | if ev is None: | |
326 | raise Exception("Timeout on EAP success") | |
327 | dev[0].request("REMOVE_NETWORK all") | |
328 | ||
329 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
330 | eap="MD5", identity="user", password="password", | |
331 | wait_connect=False) | |
332 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) | |
333 | if ev is None: | |
334 | raise Exception("Timeout on EAP notification") | |
335 | if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION B": | |
336 | raise Exception("Unexpected notification contents: " + ev) | |
337 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
338 | if ev is None: | |
339 | raise Exception("Timeout on EAP start") | |
340 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) | |
341 | if ev is None: | |
342 | raise Exception("Timeout on EAP success") | |
343 | dev[0].request("REMOVE_NETWORK all") | |
344 | ||
345 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
346 | eap="MD5", identity="user", password="password", | |
347 | wait_connect=False) | |
348 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) | |
349 | if ev is None: | |
350 | raise Exception("Timeout on EAP notification") | |
351 | if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION C": | |
352 | raise Exception("Unexpected notification contents: " + ev) | |
353 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
354 | if ev is None: | |
355 | raise Exception("Timeout on EAP start") | |
356 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) | |
357 | if ev is None: | |
358 | raise Exception("Timeout on EAP notification") | |
359 | if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION D": | |
360 | raise Exception("Unexpected notification contents: " + ev) | |
361 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) | |
362 | if ev is None: | |
363 | raise Exception("Timeout on EAP success") | |
364 | dev[0].request("REMOVE_NETWORK all") | |
365 | ||
366 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
367 | eap="MD5", identity="user", password="password", | |
368 | wait_connect=False) | |
369 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) | |
370 | if ev is None: | |
371 | raise Exception("Timeout on EAP notification") | |
372 | if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION E": | |
373 | raise Exception("Unexpected notification contents: " + ev) | |
374 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) | |
375 | if ev is None: | |
376 | raise Exception("Timeout on EAP notification") | |
377 | if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION F": | |
378 | raise Exception("Unexpected notification contents: " + ev) | |
379 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=15) | |
380 | if ev is None: | |
381 | raise Exception("Timeout on EAP failure") | |
382 | dev[0].request("REMOVE_NETWORK all") | |
383 | finally: | |
384 | stop_radius_server(srv) | |
385 | ||
d81731e6 JM |
386 | EAP_SAKE_VERSION = 2 |
387 | ||
388 | EAP_SAKE_SUBTYPE_CHALLENGE = 1 | |
389 | EAP_SAKE_SUBTYPE_CONFIRM = 2 | |
390 | EAP_SAKE_SUBTYPE_AUTH_REJECT = 3 | |
391 | EAP_SAKE_SUBTYPE_IDENTITY = 4 | |
392 | ||
393 | EAP_SAKE_AT_RAND_S = 1 | |
394 | EAP_SAKE_AT_RAND_P = 2 | |
395 | EAP_SAKE_AT_MIC_S = 3 | |
396 | EAP_SAKE_AT_MIC_P = 4 | |
397 | EAP_SAKE_AT_SERVERID = 5 | |
398 | EAP_SAKE_AT_PEERID = 6 | |
399 | EAP_SAKE_AT_SPI_S = 7 | |
400 | EAP_SAKE_AT_SPI_P = 8 | |
401 | EAP_SAKE_AT_ANY_ID_REQ = 9 | |
402 | EAP_SAKE_AT_PERM_ID_REQ = 10 | |
403 | EAP_SAKE_AT_ENCR_DATA = 128 | |
404 | EAP_SAKE_AT_IV = 129 | |
405 | EAP_SAKE_AT_PADDING = 130 | |
406 | EAP_SAKE_AT_NEXT_TMPID = 131 | |
407 | EAP_SAKE_AT_MSK_LIFE = 132 | |
408 | ||
409 | def test_eap_proto_sake(dev, apdev): | |
410 | """EAP-SAKE protocol tests""" | |
c49b383f JM |
411 | global eap_proto_sake_test_done |
412 | eap_proto_sake_test_done = False | |
413 | ||
d81731e6 JM |
414 | def sake_challenge(ctx): |
415 | logger.info("Test: Challenge subtype") | |
416 | return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], | |
417 | 4 + 1 + 3 + 18, | |
418 | EAP_TYPE_SAKE, | |
419 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE, | |
420 | EAP_SAKE_AT_RAND_S, 18, 0, 0, 0, 0) | |
421 | ||
422 | def sake_handler(ctx, req): | |
423 | logger.info("sake_handler - RX " + req.encode("hex")) | |
424 | if 'num' not in ctx: | |
425 | ctx['num'] = 0 | |
c49b383f | 426 | ctx['num'] += 1 |
d81731e6 JM |
427 | if 'id' not in ctx: |
428 | ctx['id'] = 1 | |
429 | ctx['id'] = (ctx['id'] + 1) % 256 | |
c49b383f | 430 | idx = 0 |
d81731e6 | 431 | |
c49b383f JM |
432 | idx += 1 |
433 | if ctx['num'] == idx: | |
d81731e6 JM |
434 | logger.info("Test: Missing payload") |
435 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1, | |
436 | EAP_TYPE_SAKE) | |
437 | ||
c49b383f JM |
438 | idx += 1 |
439 | if ctx['num'] == idx: | |
d81731e6 JM |
440 | logger.info("Test: Identity subtype without any attributes") |
441 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
442 | 4 + 1 + 3, | |
443 | EAP_TYPE_SAKE, | |
444 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY) | |
445 | ||
c49b383f JM |
446 | idx += 1 |
447 | if ctx['num'] == idx: | |
d81731e6 JM |
448 | logger.info("Test: Identity subtype") |
449 | return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], | |
450 | 4 + 1 + 3 + 4, | |
451 | EAP_TYPE_SAKE, | |
452 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, | |
453 | EAP_SAKE_AT_ANY_ID_REQ, 4, 0) | |
c49b383f JM |
454 | idx += 1 |
455 | if ctx['num'] == idx: | |
d81731e6 JM |
456 | logger.info("Test: Identity subtype (different session id)") |
457 | return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], | |
458 | 4 + 1 + 3 + 4, | |
459 | EAP_TYPE_SAKE, | |
460 | EAP_SAKE_VERSION, 1, EAP_SAKE_SUBTYPE_IDENTITY, | |
461 | EAP_SAKE_AT_PERM_ID_REQ, 4, 0) | |
462 | ||
c49b383f JM |
463 | idx += 1 |
464 | if ctx['num'] == idx: | |
d81731e6 JM |
465 | logger.info("Test: Identity subtype with too short attribute") |
466 | return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], | |
467 | 4 + 1 + 3 + 2, | |
468 | EAP_TYPE_SAKE, | |
469 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, | |
470 | EAP_SAKE_AT_ANY_ID_REQ, 2) | |
471 | ||
c49b383f JM |
472 | idx += 1 |
473 | if ctx['num'] == idx: | |
d81731e6 JM |
474 | logger.info("Test: Identity subtype with truncated attribute") |
475 | return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], | |
476 | 4 + 1 + 3 + 2, | |
477 | EAP_TYPE_SAKE, | |
478 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, | |
479 | EAP_SAKE_AT_ANY_ID_REQ, 4) | |
480 | ||
288b6f8b JM |
481 | idx += 1 |
482 | if ctx['num'] == idx: | |
483 | logger.info("Test: Identity subtype with too short attribute header") | |
484 | payload = struct.pack("B", EAP_SAKE_AT_ANY_ID_REQ) | |
485 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
486 | 4 + 1 + 3 + len(payload), | |
487 | EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, | |
488 | EAP_SAKE_SUBTYPE_IDENTITY) + payload | |
489 | ||
490 | idx += 1 | |
491 | if ctx['num'] == idx: | |
492 | logger.info("Test: Identity subtype with AT_IV but not AT_ENCR_DATA") | |
493 | payload = struct.pack("BB", EAP_SAKE_AT_IV, 2) | |
494 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
495 | 4 + 1 + 3 + len(payload), | |
496 | EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, | |
497 | EAP_SAKE_SUBTYPE_IDENTITY) + payload | |
498 | ||
499 | idx += 1 | |
500 | if ctx['num'] == idx: | |
501 | logger.info("Test: Identity subtype with skippable and non-skippable unknown attribute") | |
502 | payload = struct.pack("BBBB", 255, 2, 127, 2) | |
503 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
504 | 4 + 1 + 3 + len(payload), | |
505 | EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, | |
506 | EAP_SAKE_SUBTYPE_IDENTITY) + payload | |
507 | ||
508 | idx += 1 | |
509 | if ctx['num'] == idx: | |
510 | logger.info("Test: Identity subtype: AT_RAND_P with invalid payload length") | |
511 | payload = struct.pack("BB", EAP_SAKE_AT_RAND_P, 2) | |
512 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
513 | 4 + 1 + 3 + len(payload), | |
514 | EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, | |
515 | EAP_SAKE_SUBTYPE_IDENTITY) + payload | |
516 | ||
517 | idx += 1 | |
518 | if ctx['num'] == idx: | |
519 | logger.info("Test: Identity subtype: AT_MIC_P with invalid payload length") | |
520 | payload = struct.pack("BB", EAP_SAKE_AT_MIC_P, 2) | |
521 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
522 | 4 + 1 + 3 + len(payload), | |
523 | EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, | |
524 | EAP_SAKE_SUBTYPE_IDENTITY) + payload | |
525 | ||
526 | idx += 1 | |
527 | if ctx['num'] == idx: | |
528 | logger.info("Test: Identity subtype: AT_PERM_ID_REQ with invalid payload length") | |
529 | payload = struct.pack("BBBBBBBBBBBBBB", | |
530 | EAP_SAKE_AT_SPI_S, 2, | |
531 | EAP_SAKE_AT_SPI_P, 2, | |
532 | EAP_SAKE_AT_ENCR_DATA, 2, | |
533 | EAP_SAKE_AT_NEXT_TMPID, 2, | |
534 | EAP_SAKE_AT_PERM_ID_REQ, 4, 0, 0, | |
535 | EAP_SAKE_AT_PERM_ID_REQ, 2) | |
536 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
537 | 4 + 1 + 3 + len(payload), | |
538 | EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, | |
539 | EAP_SAKE_SUBTYPE_IDENTITY) + payload | |
540 | ||
541 | idx += 1 | |
542 | if ctx['num'] == idx: | |
543 | logger.info("Test: Identity subtype: AT_PADDING") | |
544 | payload = struct.pack("BBBBBB", | |
545 | EAP_SAKE_AT_PADDING, 3, 0, | |
546 | EAP_SAKE_AT_PADDING, 3, 1) | |
547 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
548 | 4 + 1 + 3 + len(payload), | |
549 | EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, | |
550 | EAP_SAKE_SUBTYPE_IDENTITY) + payload | |
551 | ||
552 | idx += 1 | |
553 | if ctx['num'] == idx: | |
554 | logger.info("Test: Identity subtype: AT_MSK_LIFE") | |
555 | payload = struct.pack(">BBLBBH", | |
556 | EAP_SAKE_AT_MSK_LIFE, 6, 0, | |
557 | EAP_SAKE_AT_MSK_LIFE, 4, 0) | |
558 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
559 | 4 + 1 + 3 + len(payload), | |
560 | EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, | |
561 | EAP_SAKE_SUBTYPE_IDENTITY) + payload | |
562 | ||
563 | idx += 1 | |
564 | if ctx['num'] == idx: | |
565 | logger.info("Test: Identity subtype with invalid attribute length") | |
566 | payload = struct.pack("BB", EAP_SAKE_AT_ANY_ID_REQ, 0) | |
567 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
568 | 4 + 1 + 3 + len(payload), | |
569 | EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, | |
570 | EAP_SAKE_SUBTYPE_IDENTITY) + payload | |
571 | ||
c49b383f JM |
572 | idx += 1 |
573 | if ctx['num'] == idx: | |
d81731e6 JM |
574 | logger.info("Test: Unknown subtype") |
575 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
576 | 4 + 1 + 3, | |
577 | EAP_TYPE_SAKE, | |
578 | EAP_SAKE_VERSION, 0, 123) | |
579 | ||
c49b383f JM |
580 | idx += 1 |
581 | if ctx['num'] == idx: | |
d81731e6 JM |
582 | logger.info("Test: Challenge subtype without any attributes") |
583 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
584 | 4 + 1 + 3, | |
585 | EAP_TYPE_SAKE, | |
586 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE) | |
587 | ||
c49b383f JM |
588 | idx += 1 |
589 | if ctx['num'] == idx: | |
d81731e6 JM |
590 | logger.info("Test: Challenge subtype with too short AT_RAND_S") |
591 | return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], | |
592 | 4 + 1 + 3 + 2, | |
593 | EAP_TYPE_SAKE, | |
594 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE, | |
595 | EAP_SAKE_AT_RAND_S, 2) | |
596 | ||
c49b383f JM |
597 | idx += 1 |
598 | if ctx['num'] == idx: | |
d81731e6 | 599 | return sake_challenge(ctx) |
c49b383f JM |
600 | idx += 1 |
601 | if ctx['num'] == idx: | |
d81731e6 JM |
602 | logger.info("Test: Unexpected Identity subtype") |
603 | return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], | |
604 | 4 + 1 + 3 + 4, | |
605 | EAP_TYPE_SAKE, | |
606 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, | |
607 | EAP_SAKE_AT_ANY_ID_REQ, 4, 0) | |
608 | ||
c49b383f JM |
609 | idx += 1 |
610 | if ctx['num'] == idx: | |
d81731e6 | 611 | return sake_challenge(ctx) |
c49b383f JM |
612 | idx += 1 |
613 | if ctx['num'] == idx: | |
d81731e6 JM |
614 | logger.info("Test: Unexpected Challenge subtype") |
615 | return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], | |
616 | 4 + 1 + 3 + 18, | |
617 | EAP_TYPE_SAKE, | |
618 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE, | |
619 | EAP_SAKE_AT_RAND_S, 18, 0, 0, 0, 0) | |
620 | ||
c49b383f JM |
621 | idx += 1 |
622 | if ctx['num'] == idx: | |
d81731e6 | 623 | return sake_challenge(ctx) |
c49b383f JM |
624 | idx += 1 |
625 | if ctx['num'] == idx: | |
d81731e6 JM |
626 | logger.info("Test: Confirm subtype without any attributes") |
627 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
628 | 4 + 1 + 3, | |
629 | EAP_TYPE_SAKE, | |
630 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM) | |
631 | ||
c49b383f JM |
632 | idx += 1 |
633 | if ctx['num'] == idx: | |
d81731e6 | 634 | return sake_challenge(ctx) |
c49b383f JM |
635 | idx += 1 |
636 | if ctx['num'] == idx: | |
d81731e6 JM |
637 | logger.info("Test: Confirm subtype with too short AT_MIC_S") |
638 | return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], | |
639 | 4 + 1 + 3 + 2, | |
640 | EAP_TYPE_SAKE, | |
641 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM, | |
642 | EAP_SAKE_AT_MIC_S, 2) | |
643 | ||
c49b383f JM |
644 | idx += 1 |
645 | if ctx['num'] == idx: | |
d81731e6 JM |
646 | logger.info("Test: Unexpected Confirm subtype") |
647 | return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], | |
648 | 4 + 1 + 3 + 18, | |
649 | EAP_TYPE_SAKE, | |
650 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM, | |
651 | EAP_SAKE_AT_MIC_S, 18, 0, 0, 0, 0) | |
652 | ||
c49b383f JM |
653 | idx += 1 |
654 | if ctx['num'] == idx: | |
d81731e6 | 655 | return sake_challenge(ctx) |
c49b383f JM |
656 | idx += 1 |
657 | if ctx['num'] == idx: | |
d81731e6 JM |
658 | logger.info("Test: Confirm subtype with incorrect AT_MIC_S") |
659 | return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], | |
660 | 4 + 1 + 3 + 18, | |
661 | EAP_TYPE_SAKE, | |
662 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM, | |
663 | EAP_SAKE_AT_MIC_S, 18, 0, 0, 0, 0) | |
664 | ||
c49b383f JM |
665 | global eap_proto_sake_test_done |
666 | if eap_proto_sake_test_done: | |
667 | return sake_challenge(ctx) | |
668 | ||
669 | logger.info("No more test responses available - test case completed") | |
670 | eap_proto_sake_test_done = True | |
671 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
d81731e6 JM |
672 | |
673 | srv = start_radius_server(sake_handler) | |
d81731e6 JM |
674 | |
675 | try: | |
676 | hapd = start_ap(apdev[0]['ifname']) | |
677 | ||
c49b383f | 678 | while not eap_proto_sake_test_done: |
d81731e6 JM |
679 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", |
680 | eap="SAKE", identity="sake user", | |
681 | password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", | |
682 | wait_connect=False) | |
683 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
684 | if ev is None: | |
685 | raise Exception("Timeout on EAP start") | |
686 | time.sleep(0.1) | |
687 | dev[0].request("REMOVE_NETWORK all") | |
688 | ||
689 | logger.info("Too short password") | |
690 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
691 | eap="SAKE", identity="sake user", | |
692 | password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd", | |
693 | wait_connect=False) | |
694 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
695 | if ev is None: | |
696 | raise Exception("Timeout on EAP start") | |
697 | time.sleep(0.1) | |
698 | finally: | |
699 | stop_radius_server(srv) | |
18fc8f40 | 700 | |
ab4ea0e9 JM |
701 | def test_eap_proto_sake_errors(dev, apdev): |
702 | """EAP-SAKE local error cases""" | |
703 | check_eap_capa(dev[0], "SAKE") | |
704 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
705 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
706 | ||
707 | for i in range(1, 3): | |
708 | with alloc_fail(dev[0], i, "eap_sake_init"): | |
709 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
710 | eap="SAKE", identity="sake user", | |
711 | password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", | |
712 | wait_connect=False) | |
713 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
714 | timeout=15) | |
715 | if ev is None: | |
716 | raise Exception("Timeout on EAP start") | |
717 | dev[0].request("REMOVE_NETWORK all") | |
718 | dev[0].wait_disconnected() | |
719 | ||
720 | tests = [ ( 1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_challenge" ), | |
721 | ( 1, "=eap_sake_process_challenge" ), | |
722 | ( 1, "eap_sake_compute_mic;eap_sake_process_challenge" ), | |
723 | ( 1, "eap_sake_build_msg;eap_sake_process_confirm" ), | |
724 | ( 2, "eap_sake_compute_mic;eap_sake_process_confirm" ), | |
725 | ( 1, "eap_sake_getKey" ), | |
726 | ( 1, "eap_sake_get_emsk" ), | |
727 | ( 1, "eap_sake_get_session_id" ) ] | |
728 | for count, func in tests: | |
729 | with alloc_fail(dev[0], count, func): | |
730 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
731 | eap="SAKE", identity="sake user", | |
732 | password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", | |
733 | erp="1", | |
734 | wait_connect=False) | |
735 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
736 | timeout=15) | |
737 | if ev is None: | |
738 | raise Exception("Timeout on EAP start") | |
739 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
740 | dev[0].request("REMOVE_NETWORK all") | |
741 | dev[0].wait_disconnected() | |
742 | ||
743 | with fail_test(dev[0], 1, "os_get_random;eap_sake_process_challenge"): | |
744 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
745 | eap="SAKE", identity="sake user", | |
746 | password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", | |
747 | wait_connect=False) | |
748 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
749 | if ev is None: | |
750 | raise Exception("Timeout on EAP start") | |
751 | wait_fail_trigger(dev[0], "GET_FAIL") | |
752 | dev[0].request("REMOVE_NETWORK all") | |
753 | dev[0].wait_disconnected() | |
754 | ||
755 | def test_eap_proto_sake_errors2(dev, apdev): | |
756 | """EAP-SAKE protocol tests (2)""" | |
757 | def sake_handler(ctx, req): | |
758 | logger.info("sake_handler - RX " + req.encode("hex")) | |
759 | if 'num' not in ctx: | |
760 | ctx['num'] = 0 | |
761 | ctx['num'] += 1 | |
762 | if 'id' not in ctx: | |
763 | ctx['id'] = 1 | |
764 | ctx['id'] = (ctx['id'] + 1) % 256 | |
765 | idx = 0 | |
766 | ||
767 | idx += 1 | |
768 | if ctx['num'] == idx: | |
769 | logger.info("Test: Identity subtype") | |
770 | return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], | |
771 | 4 + 1 + 3 + 4, | |
772 | EAP_TYPE_SAKE, | |
773 | EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, | |
774 | EAP_SAKE_AT_ANY_ID_REQ, 4, 0) | |
775 | ||
776 | srv = start_radius_server(sake_handler) | |
777 | ||
778 | try: | |
779 | hapd = start_ap(apdev[0]['ifname']) | |
780 | ||
781 | with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_identity"): | |
782 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
783 | eap="SAKE", identity="sake user", | |
784 | password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", | |
785 | wait_connect=False) | |
786 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
787 | timeout=15) | |
788 | if ev is None: | |
789 | raise Exception("Timeout on EAP start") | |
790 | dev[0].request("REMOVE_NETWORK all") | |
791 | dev[0].wait_disconnected() | |
792 | ||
793 | finally: | |
794 | stop_radius_server(srv) | |
795 | ||
18fc8f40 JM |
796 | def test_eap_proto_leap(dev, apdev): |
797 | """EAP-LEAP protocol tests""" | |
597516df | 798 | check_eap_capa(dev[0], "LEAP") |
18fc8f40 JM |
799 | def leap_handler(ctx, req): |
800 | logger.info("leap_handler - RX " + req.encode("hex")) | |
801 | if 'num' not in ctx: | |
802 | ctx['num'] = 0 | |
803 | ctx['num'] = ctx['num'] + 1 | |
804 | if 'id' not in ctx: | |
805 | ctx['id'] = 1 | |
806 | ctx['id'] = (ctx['id'] + 1) % 256 | |
807 | ||
808 | if ctx['num'] == 1: | |
809 | logger.info("Test: Missing payload") | |
810 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
811 | 4 + 1, | |
812 | EAP_TYPE_LEAP) | |
813 | ||
814 | if ctx['num'] == 2: | |
815 | logger.info("Test: Unexpected version") | |
816 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
817 | 4 + 1 + 3, | |
818 | EAP_TYPE_LEAP, | |
819 | 0, 0, 0) | |
820 | ||
821 | if ctx['num'] == 3: | |
822 | logger.info("Test: Invalid challenge length") | |
823 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
824 | 4 + 1 + 3, | |
825 | EAP_TYPE_LEAP, | |
826 | 1, 0, 0) | |
827 | ||
828 | if ctx['num'] == 4: | |
829 | logger.info("Test: Truncated challenge") | |
830 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
831 | 4 + 1 + 3, | |
832 | EAP_TYPE_LEAP, | |
833 | 1, 0, 8) | |
834 | ||
835 | if ctx['num'] == 5: | |
836 | logger.info("Test: Valid challenge") | |
837 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
838 | 4 + 1 + 3 + 8, | |
839 | EAP_TYPE_LEAP, | |
840 | 1, 0, 8, 0, 0) | |
841 | if ctx['num'] == 6: | |
842 | logger.info("Test: Missing payload in Response") | |
843 | return struct.pack(">BBHB", EAP_CODE_RESPONSE, ctx['id'], | |
844 | 4 + 1, | |
845 | EAP_TYPE_LEAP) | |
846 | ||
847 | if ctx['num'] == 7: | |
848 | logger.info("Test: Valid challenge") | |
849 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
850 | 4 + 1 + 3 + 8, | |
851 | EAP_TYPE_LEAP, | |
852 | 1, 0, 8, 0, 0) | |
853 | if ctx['num'] == 8: | |
854 | logger.info("Test: Unexpected version in Response") | |
855 | return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'], | |
856 | 4 + 1 + 3, | |
857 | EAP_TYPE_LEAP, | |
858 | 0, 0, 8) | |
859 | ||
860 | if ctx['num'] == 9: | |
861 | logger.info("Test: Valid challenge") | |
862 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
863 | 4 + 1 + 3 + 8, | |
864 | EAP_TYPE_LEAP, | |
865 | 1, 0, 8, 0, 0) | |
866 | if ctx['num'] == 10: | |
867 | logger.info("Test: Invalid challenge length in Response") | |
868 | return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'], | |
869 | 4 + 1 + 3, | |
870 | EAP_TYPE_LEAP, | |
871 | 1, 0, 0) | |
872 | ||
873 | if ctx['num'] == 11: | |
874 | logger.info("Test: Valid challenge") | |
875 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
876 | 4 + 1 + 3 + 8, | |
877 | EAP_TYPE_LEAP, | |
878 | 1, 0, 8, 0, 0) | |
879 | if ctx['num'] == 12: | |
880 | logger.info("Test: Truncated challenge in Response") | |
881 | return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'], | |
882 | 4 + 1 + 3, | |
883 | EAP_TYPE_LEAP, | |
884 | 1, 0, 24) | |
885 | ||
886 | if ctx['num'] == 13: | |
887 | logger.info("Test: Valid challenge") | |
888 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
889 | 4 + 1 + 3 + 8, | |
890 | EAP_TYPE_LEAP, | |
891 | 1, 0, 8, 0, 0) | |
892 | if ctx['num'] == 14: | |
893 | logger.info("Test: Invalid challange value in Response") | |
894 | return struct.pack(">BBHBBBB6L", EAP_CODE_RESPONSE, ctx['id'], | |
895 | 4 + 1 + 3 + 24, | |
896 | EAP_TYPE_LEAP, | |
897 | 1, 0, 24, | |
898 | 0, 0, 0, 0, 0, 0) | |
899 | ||
900 | if ctx['num'] == 15: | |
901 | logger.info("Test: Valid challenge") | |
902 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
903 | 4 + 1 + 3 + 8, | |
904 | EAP_TYPE_LEAP, | |
905 | 1, 0, 8, 0, 0) | |
906 | if ctx['num'] == 16: | |
907 | logger.info("Test: Valid challange value in Response") | |
908 | return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], | |
909 | 4 + 1 + 3 + 24, | |
910 | EAP_TYPE_LEAP, | |
911 | 1, 0, 24, | |
912 | 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, | |
913 | 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, | |
914 | 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) | |
915 | ||
916 | if ctx['num'] == 17: | |
917 | logger.info("Test: Valid challenge") | |
918 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
919 | 4 + 1 + 3 + 8, | |
920 | EAP_TYPE_LEAP, | |
921 | 1, 0, 8, 0, 0) | |
922 | if ctx['num'] == 18: | |
923 | logger.info("Test: Success") | |
924 | return struct.pack(">BBHB", EAP_CODE_SUCCESS, ctx['id'], | |
925 | 4 + 1, | |
926 | EAP_TYPE_LEAP) | |
927 | # hostapd will drop the next frame in the sequence | |
928 | ||
929 | if ctx['num'] == 19: | |
930 | logger.info("Test: Valid challenge") | |
931 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
932 | 4 + 1 + 3 + 8, | |
933 | EAP_TYPE_LEAP, | |
934 | 1, 0, 8, 0, 0) | |
935 | if ctx['num'] == 20: | |
936 | logger.info("Test: Failure") | |
937 | return struct.pack(">BBHB", EAP_CODE_FAILURE, ctx['id'], | |
938 | 4 + 1, | |
939 | EAP_TYPE_LEAP) | |
940 | ||
941 | return None | |
942 | ||
943 | srv = start_radius_server(leap_handler) | |
18fc8f40 JM |
944 | |
945 | try: | |
946 | hapd = start_ap(apdev[0]['ifname']) | |
947 | ||
948 | for i in range(0, 12): | |
949 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
950 | eap="LEAP", identity="user", password="password", | |
951 | wait_connect=False) | |
952 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
953 | if ev is None: | |
954 | raise Exception("Timeout on EAP start") | |
955 | time.sleep(0.1) | |
956 | if i == 10: | |
957 | logger.info("Wait for additional roundtrip") | |
958 | time.sleep(1) | |
959 | dev[0].request("REMOVE_NETWORK all") | |
960 | finally: | |
961 | stop_radius_server(srv) | |
8604a68e | 962 | |
e114e999 JM |
963 | def test_eap_proto_leap_errors(dev, apdev): |
964 | """EAP-LEAP protocol tests (error paths)""" | |
965 | check_eap_capa(dev[0], "LEAP") | |
966 | ||
967 | def leap_handler2(ctx, req): | |
968 | logger.info("leap_handler2 - RX " + req.encode("hex")) | |
969 | if 'num' not in ctx: | |
970 | ctx['num'] = 0 | |
971 | ctx['num'] = ctx['num'] + 1 | |
972 | if 'id' not in ctx: | |
973 | ctx['id'] = 1 | |
974 | ctx['id'] = (ctx['id'] + 1) % 256 | |
975 | idx = 0 | |
976 | ||
977 | idx += 1 | |
978 | if ctx['num'] == idx: | |
979 | logger.info("Test: Valid challenge") | |
980 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
981 | 4 + 1 + 3 + 8, | |
982 | EAP_TYPE_LEAP, | |
983 | 1, 0, 8, 0, 0) | |
984 | idx += 1 | |
985 | if ctx['num'] == idx: | |
986 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
987 | ||
988 | idx += 1 | |
989 | if ctx['num'] == idx: | |
990 | logger.info("Test: Valid challenge") | |
991 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
992 | 4 + 1 + 3 + 8, | |
993 | EAP_TYPE_LEAP, | |
994 | 1, 0, 8, 0, 0) | |
995 | ||
996 | idx += 1 | |
997 | if ctx['num'] == idx: | |
998 | logger.info("Test: Valid challenge") | |
999 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
1000 | 4 + 1 + 3 + 8, | |
1001 | EAP_TYPE_LEAP, | |
1002 | 1, 0, 8, 0, 0) | |
1003 | idx += 1 | |
1004 | if ctx['num'] == idx: | |
1005 | logger.info("Test: Success") | |
1006 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) | |
1007 | ||
1008 | idx += 1 | |
1009 | if ctx['num'] == idx: | |
1010 | logger.info("Test: Valid challenge") | |
1011 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
1012 | 4 + 1 + 3 + 8, | |
1013 | EAP_TYPE_LEAP, | |
1014 | 1, 0, 8, 0, 0) | |
1015 | idx += 1 | |
1016 | if ctx['num'] == idx: | |
1017 | logger.info("Test: Success") | |
1018 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) | |
1019 | ||
1020 | idx += 1 | |
1021 | if ctx['num'] == idx: | |
1022 | logger.info("Test: Valid challenge") | |
1023 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
1024 | 4 + 1 + 3 + 8, | |
1025 | EAP_TYPE_LEAP, | |
1026 | 1, 0, 8, 0, 0) | |
1027 | idx += 1 | |
1028 | if ctx['num'] == idx: | |
1029 | logger.info("Test: Valid challange value in Response") | |
1030 | return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], | |
1031 | 4 + 1 + 3 + 24, | |
1032 | EAP_TYPE_LEAP, | |
1033 | 1, 0, 24, | |
1034 | 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, | |
1035 | 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, | |
1036 | 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) | |
1037 | ||
1038 | idx += 1 | |
1039 | if ctx['num'] == idx: | |
1040 | logger.info("Test: Valid challenge") | |
1041 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
1042 | 4 + 1 + 3 + 8, | |
1043 | EAP_TYPE_LEAP, | |
1044 | 1, 0, 8, 0, 0) | |
1045 | idx += 1 | |
1046 | if ctx['num'] == idx: | |
1047 | logger.info("Test: Valid challange value in Response") | |
1048 | return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], | |
1049 | 4 + 1 + 3 + 24, | |
1050 | EAP_TYPE_LEAP, | |
1051 | 1, 0, 24, | |
1052 | 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, | |
1053 | 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, | |
1054 | 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) | |
1055 | ||
1056 | idx += 1 | |
1057 | if ctx['num'] == idx: | |
1058 | logger.info("Test: Valid challenge") | |
1059 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
1060 | 4 + 1 + 3 + 8, | |
1061 | EAP_TYPE_LEAP, | |
1062 | 1, 0, 8, 0, 0) | |
1063 | idx += 1 | |
1064 | if ctx['num'] == idx: | |
1065 | logger.info("Test: Valid challange value in Response") | |
1066 | return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], | |
1067 | 4 + 1 + 3 + 24, | |
1068 | EAP_TYPE_LEAP, | |
1069 | 1, 0, 24, | |
1070 | 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, | |
1071 | 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, | |
1072 | 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) | |
1073 | ||
1074 | idx += 1 | |
1075 | if ctx['num'] == idx: | |
1076 | logger.info("Test: Valid challenge") | |
1077 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
1078 | 4 + 1 + 3 + 8, | |
1079 | EAP_TYPE_LEAP, | |
1080 | 1, 0, 8, 0, 0) | |
1081 | idx += 1 | |
1082 | if ctx['num'] == idx: | |
1083 | logger.info("Test: Valid challange value in Response") | |
1084 | return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], | |
1085 | 4 + 1 + 3 + 24, | |
1086 | EAP_TYPE_LEAP, | |
1087 | 1, 0, 24, | |
1088 | 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, | |
1089 | 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, | |
1090 | 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) | |
1091 | ||
1092 | idx += 1 | |
1093 | if ctx['num'] == idx: | |
1094 | logger.info("Test: Valid challenge") | |
1095 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
1096 | 4 + 1 + 3 + 8, | |
1097 | EAP_TYPE_LEAP, | |
1098 | 1, 0, 8, 0, 0) | |
1099 | idx += 1 | |
1100 | if ctx['num'] == idx: | |
1101 | logger.info("Test: Valid challange value in Response") | |
1102 | return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], | |
1103 | 4 + 1 + 3 + 24, | |
1104 | EAP_TYPE_LEAP, | |
1105 | 1, 0, 24, | |
1106 | 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, | |
1107 | 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, | |
1108 | 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) | |
1109 | ||
1110 | idx += 1 | |
1111 | if ctx['num'] == idx: | |
1112 | logger.info("Test: Valid challenge") | |
1113 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
1114 | 4 + 1 + 3 + 8, | |
1115 | EAP_TYPE_LEAP, | |
1116 | 1, 0, 8, 0, 0) | |
1117 | idx += 1 | |
1118 | if ctx['num'] == idx: | |
1119 | logger.info("Test: Valid challange value in Response") | |
1120 | return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], | |
1121 | 4 + 1 + 3 + 24, | |
1122 | EAP_TYPE_LEAP, | |
1123 | 1, 0, 24, | |
1124 | 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, | |
1125 | 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, | |
1126 | 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) | |
1127 | ||
1128 | idx += 1 | |
1129 | if ctx['num'] == idx: | |
1130 | logger.info("Test: Valid challenge") | |
1131 | return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
1132 | 4 + 1 + 3 + 8, | |
1133 | EAP_TYPE_LEAP, | |
1134 | 1, 0, 8, 0, 0) | |
1135 | idx += 1 | |
1136 | if ctx['num'] == idx: | |
1137 | logger.info("Test: Valid challange value in Response") | |
1138 | return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], | |
1139 | 4 + 1 + 3 + 24, | |
1140 | EAP_TYPE_LEAP, | |
1141 | 1, 0, 24, | |
1142 | 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, | |
1143 | 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, | |
1144 | 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) | |
1145 | ||
1146 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
1147 | ||
1148 | srv = start_radius_server(leap_handler2) | |
1149 | ||
1150 | try: | |
1151 | hapd = start_ap(apdev[0]['ifname']) | |
1152 | ||
1153 | with alloc_fail(dev[0], 1, "eap_leap_init"): | |
1154 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1155 | eap="LEAP", identity="user", password="password", | |
1156 | wait_connect=False) | |
1157 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
1158 | dev[0].request("REMOVE_NETWORK all") | |
1159 | dev[0].wait_disconnected() | |
1160 | ||
1161 | with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_leap_process_request"): | |
1162 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1163 | eap="LEAP", identity="user", | |
1164 | password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", | |
1165 | wait_connect=False) | |
1166 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
1167 | dev[0].request("REMOVE_NETWORK all") | |
1168 | dev[0].wait_disconnected() | |
1169 | ||
1170 | with alloc_fail(dev[0], 1, "eap_leap_process_success"): | |
1171 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1172 | eap="LEAP", identity="user", password="password", | |
1173 | wait_connect=False) | |
1174 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
1175 | dev[0].request("REMOVE_NETWORK all") | |
1176 | dev[0].wait_disconnected() | |
1177 | ||
1178 | with fail_test(dev[0], 1, "os_get_random;eap_leap_process_success"): | |
1179 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1180 | eap="LEAP", identity="user", password="password", | |
1181 | wait_connect=False) | |
1182 | wait_fail_trigger(dev[0], "GET_FAIL") | |
1183 | dev[0].request("REMOVE_NETWORK all") | |
1184 | dev[0].wait_disconnected() | |
1185 | ||
1186 | with fail_test(dev[0], 1, "eap_leap_process_response"): | |
1187 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1188 | eap="LEAP", identity="user", | |
1189 | password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", | |
1190 | wait_connect=False) | |
1191 | wait_fail_trigger(dev[0], "GET_FAIL") | |
1192 | dev[0].request("REMOVE_NETWORK all") | |
1193 | dev[0].wait_disconnected() | |
1194 | ||
1195 | with fail_test(dev[0], 1, "nt_password_hash;eap_leap_process_response"): | |
1196 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1197 | eap="LEAP", identity="user", password="password", | |
1198 | wait_connect=False) | |
1199 | wait_fail_trigger(dev[0], "GET_FAIL") | |
1200 | dev[0].request("REMOVE_NETWORK all") | |
1201 | dev[0].wait_disconnected() | |
1202 | ||
1203 | with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_process_response"): | |
1204 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1205 | eap="LEAP", identity="user", password="password", | |
1206 | wait_connect=False) | |
1207 | wait_fail_trigger(dev[0], "GET_FAIL") | |
1208 | dev[0].request("REMOVE_NETWORK all") | |
1209 | dev[0].wait_disconnected() | |
1210 | ||
1211 | with alloc_fail(dev[0], 1, "eap_leap_getKey"): | |
1212 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1213 | eap="LEAP", identity="user", | |
1214 | password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", | |
1215 | wait_connect=False) | |
1216 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
1217 | dev[0].request("REMOVE_NETWORK all") | |
1218 | dev[0].wait_disconnected() | |
1219 | ||
1220 | with fail_test(dev[0], 1, "eap_leap_getKey"): | |
1221 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1222 | eap="LEAP", identity="user", | |
1223 | password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", | |
1224 | wait_connect=False) | |
1225 | wait_fail_trigger(dev[0], "GET_FAIL") | |
1226 | dev[0].request("REMOVE_NETWORK all") | |
1227 | dev[0].wait_disconnected() | |
1228 | ||
1229 | with fail_test(dev[0], 1, "nt_password_hash;eap_leap_getKey"): | |
1230 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1231 | eap="LEAP", identity="user", password="password", | |
1232 | wait_connect=False) | |
1233 | wait_fail_trigger(dev[0], "GET_FAIL") | |
1234 | dev[0].request("REMOVE_NETWORK all") | |
1235 | dev[0].wait_disconnected() | |
1236 | ||
1237 | with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_getKey"): | |
1238 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1239 | eap="LEAP", identity="user", password="password", | |
1240 | wait_connect=False) | |
1241 | wait_fail_trigger(dev[0], "GET_FAIL") | |
1242 | dev[0].request("REMOVE_NETWORK all") | |
1243 | dev[0].wait_disconnected() | |
1244 | finally: | |
1245 | stop_radius_server(srv) | |
1246 | ||
8604a68e JM |
1247 | def test_eap_proto_md5(dev, apdev): |
1248 | """EAP-MD5 protocol tests""" | |
e7ac04ce JM |
1249 | check_eap_capa(dev[0], "MD5") |
1250 | ||
8604a68e JM |
1251 | def md5_handler(ctx, req): |
1252 | logger.info("md5_handler - RX " + req.encode("hex")) | |
1253 | if 'num' not in ctx: | |
1254 | ctx['num'] = 0 | |
1255 | ctx['num'] = ctx['num'] + 1 | |
1256 | if 'id' not in ctx: | |
1257 | ctx['id'] = 1 | |
1258 | ctx['id'] = (ctx['id'] + 1) % 256 | |
1259 | ||
1260 | if ctx['num'] == 1: | |
1261 | logger.info("Test: Missing payload") | |
1262 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
1263 | 4 + 1, | |
1264 | EAP_TYPE_MD5) | |
1265 | ||
1266 | if ctx['num'] == 2: | |
1267 | logger.info("Test: Zero-length challenge") | |
1268 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1269 | 4 + 1 + 1, | |
1270 | EAP_TYPE_MD5, | |
1271 | 0) | |
1272 | ||
1273 | if ctx['num'] == 3: | |
1274 | logger.info("Test: Truncated challenge") | |
1275 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1276 | 4 + 1 + 1, | |
1277 | EAP_TYPE_MD5, | |
1278 | 1) | |
1279 | ||
1280 | if ctx['num'] == 4: | |
1281 | logger.info("Test: Shortest possible challenge and name") | |
1282 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
1283 | 4 + 1 + 3, | |
1284 | EAP_TYPE_MD5, | |
1285 | 1, 0xaa, ord('n')) | |
1286 | ||
1287 | return None | |
1288 | ||
1289 | srv = start_radius_server(md5_handler) | |
8604a68e JM |
1290 | |
1291 | try: | |
1292 | hapd = start_ap(apdev[0]['ifname']) | |
1293 | ||
1294 | for i in range(0, 4): | |
1295 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1296 | eap="MD5", identity="user", password="password", | |
1297 | wait_connect=False) | |
1298 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
1299 | if ev is None: | |
1300 | raise Exception("Timeout on EAP start") | |
1301 | time.sleep(0.1) | |
1302 | dev[0].request("REMOVE_NETWORK all") | |
1303 | finally: | |
1304 | stop_radius_server(srv) | |
d5c14b25 | 1305 | |
d5482411 JM |
1306 | def test_eap_proto_md5_errors(dev, apdev): |
1307 | """EAP-MD5 local error cases""" | |
1308 | check_eap_capa(dev[0], "MD5") | |
1309 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
1310 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
1311 | ||
1312 | with fail_test(dev[0], 1, "chap_md5"): | |
1313 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1314 | eap="MD5", identity="phase1-user", password="password", | |
1315 | wait_connect=False) | |
1316 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15) | |
1317 | if ev is None: | |
1318 | raise Exception("Timeout on EAP start") | |
1319 | dev[0].request("REMOVE_NETWORK all") | |
1320 | dev[0].wait_disconnected() | |
1321 | ||
1322 | with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_md5_process"): | |
1323 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1324 | eap="MD5", identity="phase1-user", password="password", | |
1325 | wait_connect=False) | |
1326 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15) | |
1327 | if ev is None: | |
1328 | raise Exception("Timeout on EAP start") | |
1329 | time.sleep(0.1) | |
1330 | dev[0].request("REMOVE_NETWORK all") | |
1331 | ||
d5c14b25 JM |
1332 | def test_eap_proto_otp(dev, apdev): |
1333 | """EAP-OTP protocol tests""" | |
1334 | def otp_handler(ctx, req): | |
1335 | logger.info("otp_handler - RX " + req.encode("hex")) | |
1336 | if 'num' not in ctx: | |
1337 | ctx['num'] = 0 | |
1338 | ctx['num'] = ctx['num'] + 1 | |
1339 | if 'id' not in ctx: | |
1340 | ctx['id'] = 1 | |
1341 | ctx['id'] = (ctx['id'] + 1) % 256 | |
1342 | ||
1343 | if ctx['num'] == 1: | |
1344 | logger.info("Test: Empty payload") | |
1345 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
1346 | 4 + 1, | |
1347 | EAP_TYPE_OTP) | |
1348 | if ctx['num'] == 2: | |
1349 | logger.info("Test: Success") | |
1350 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], | |
1351 | 4) | |
1352 | ||
1353 | if ctx['num'] == 3: | |
1354 | logger.info("Test: Challenge included") | |
1355 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1356 | 4 + 1 + 1, | |
1357 | EAP_TYPE_OTP, | |
1358 | ord('A')) | |
1359 | if ctx['num'] == 4: | |
1360 | logger.info("Test: Success") | |
1361 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], | |
1362 | 4) | |
1363 | ||
1364 | return None | |
1365 | ||
1366 | srv = start_radius_server(otp_handler) | |
d5c14b25 JM |
1367 | |
1368 | try: | |
1369 | hapd = start_ap(apdev[0]['ifname']) | |
1370 | ||
1371 | for i in range(0, 1): | |
1372 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1373 | eap="OTP", identity="user", password="password", | |
1374 | wait_connect=False) | |
1375 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
1376 | timeout=15) | |
1377 | if ev is None: | |
1378 | raise Exception("Timeout on EAP start") | |
1379 | time.sleep(0.1) | |
1380 | dev[0].request("REMOVE_NETWORK all") | |
1381 | ||
1382 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1383 | eap="OTP", identity="user", wait_connect=False) | |
1384 | ev = dev[0].wait_event(["CTRL-REQ-OTP"]) | |
1385 | if ev is None: | |
1386 | raise Exception("Request for password timed out") | |
1387 | id = ev.split(':')[0].split('-')[-1] | |
1388 | dev[0].request("CTRL-RSP-OTP-" + id + ":password") | |
1389 | ev = dev[0].wait_event("CTRL-EVENT-EAP-SUCCESS") | |
1390 | if ev is None: | |
1391 | raise Exception("Success not reported") | |
1392 | finally: | |
1393 | stop_radius_server(srv) | |
2e9f8ee7 | 1394 | |
2386bb97 JM |
1395 | def test_eap_proto_otp_errors(dev, apdev): |
1396 | """EAP-OTP local error cases""" | |
1397 | def otp_handler2(ctx, req): | |
1398 | logger.info("otp_handler2 - RX " + req.encode("hex")) | |
1399 | if 'num' not in ctx: | |
1400 | ctx['num'] = 0 | |
1401 | ctx['num'] = ctx['num'] + 1 | |
1402 | if 'id' not in ctx: | |
1403 | ctx['id'] = 1 | |
1404 | ctx['id'] = (ctx['id'] + 1) % 256 | |
1405 | idx = 0 | |
1406 | ||
1407 | idx += 1 | |
1408 | if ctx['num'] == idx: | |
1409 | logger.info("Test: Challenge included") | |
1410 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1411 | 4 + 1 + 1, | |
1412 | EAP_TYPE_OTP, | |
1413 | ord('A')) | |
1414 | ||
1415 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
1416 | ||
1417 | srv = start_radius_server(otp_handler2) | |
1418 | ||
1419 | try: | |
1420 | hapd = start_ap(apdev[0]['ifname']) | |
1421 | ||
1422 | with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_otp_process"): | |
1423 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1424 | eap="OTP", identity="user", password="password", | |
1425 | wait_connect=False) | |
1426 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
1427 | dev[0].request("REMOVE_NETWORK all") | |
1428 | dev[0].wait_disconnected() | |
1429 | finally: | |
1430 | stop_radius_server(srv) | |
1431 | ||
2e9f8ee7 JM |
1432 | EAP_GPSK_OPCODE_GPSK_1 = 1 |
1433 | EAP_GPSK_OPCODE_GPSK_2 = 2 | |
1434 | EAP_GPSK_OPCODE_GPSK_3 = 3 | |
1435 | EAP_GPSK_OPCODE_GPSK_4 = 4 | |
1436 | EAP_GPSK_OPCODE_FAIL = 5 | |
1437 | EAP_GPSK_OPCODE_PROTECTED_FAIL = 6 | |
1438 | ||
1439 | def test_eap_proto_gpsk(dev, apdev): | |
1440 | """EAP-GPSK protocol tests""" | |
1441 | def gpsk_handler(ctx, req): | |
1442 | logger.info("gpsk_handler - RX " + req.encode("hex")) | |
1443 | if 'num' not in ctx: | |
1444 | ctx['num'] = 0 | |
1445 | ctx['num'] = ctx['num'] + 1 | |
1446 | if 'id' not in ctx: | |
1447 | ctx['id'] = 1 | |
1448 | ctx['id'] = (ctx['id'] + 1) % 256 | |
1449 | ||
1450 | idx = 0 | |
1451 | ||
1452 | idx += 1 | |
1453 | if ctx['num'] == idx: | |
1454 | logger.info("Test: Missing payload") | |
1455 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
1456 | 4 + 1, | |
1457 | EAP_TYPE_GPSK) | |
1458 | ||
1459 | idx += 1 | |
1460 | if ctx['num'] == idx: | |
1461 | logger.info("Test: Unknown opcode") | |
1462 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1463 | 4 + 1 + 1, | |
1464 | EAP_TYPE_GPSK, | |
1465 | 255) | |
1466 | ||
1467 | idx += 1 | |
1468 | if ctx['num'] == idx: | |
1469 | logger.info("Test: Unexpected GPSK-3") | |
1470 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1471 | 4 + 1 + 1, | |
1472 | EAP_TYPE_GPSK, | |
1473 | EAP_GPSK_OPCODE_GPSK_3) | |
1474 | ||
1475 | idx += 1 | |
1476 | if ctx['num'] == idx: | |
1477 | logger.info("Test: GPSK-1 Too short GPSK-1") | |
1478 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1479 | 4 + 1 + 1, | |
1480 | EAP_TYPE_GPSK, | |
1481 | EAP_GPSK_OPCODE_GPSK_1) | |
1482 | ||
1483 | idx += 1 | |
1484 | if ctx['num'] == idx: | |
1485 | logger.info("Test: GPSK-1 Truncated ID_Server") | |
1486 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
1487 | 4 + 1 + 1 + 2, | |
1488 | EAP_TYPE_GPSK, | |
1489 | EAP_GPSK_OPCODE_GPSK_1, 1) | |
1490 | ||
1491 | idx += 1 | |
1492 | if ctx['num'] == idx: | |
1493 | logger.info("Test: GPSK-1 Missing RAND_Server") | |
1494 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
1495 | 4 + 1 + 1 + 2, | |
1496 | EAP_TYPE_GPSK, | |
1497 | EAP_GPSK_OPCODE_GPSK_1, 0) | |
1498 | ||
1499 | idx += 1 | |
1500 | if ctx['num'] == idx: | |
1501 | logger.info("Test: GPSK-1 Missing CSuite_List") | |
1502 | return struct.pack(">BBHBBH8L", EAP_CODE_REQUEST, ctx['id'], | |
1503 | 4 + 1 + 1 + 2 + 32, | |
1504 | EAP_TYPE_GPSK, | |
1505 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1506 | 0, 0, 0, 0, 0, 0, 0, 0) | |
1507 | ||
1508 | idx += 1 | |
1509 | if ctx['num'] == idx: | |
1510 | logger.info("Test: GPSK-1 Truncated CSuite_List") | |
1511 | return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'], | |
1512 | 4 + 1 + 1 + 2 + 32 + 2, | |
1513 | EAP_TYPE_GPSK, | |
1514 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1515 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1516 | 1) | |
1517 | ||
1518 | idx += 1 | |
1519 | if ctx['num'] == idx: | |
1520 | logger.info("Test: GPSK-1 Empty CSuite_List") | |
1521 | return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'], | |
1522 | 4 + 1 + 1 + 2 + 32 + 2, | |
1523 | EAP_TYPE_GPSK, | |
1524 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1525 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1526 | 0) | |
1527 | ||
1528 | idx += 1 | |
1529 | if ctx['num'] == idx: | |
1530 | logger.info("Test: GPSK-1 Invalid CSuite_List") | |
1531 | return struct.pack(">BBHBBH8LHB", EAP_CODE_REQUEST, ctx['id'], | |
1532 | 4 + 1 + 1 + 2 + 32 + 2 + 1, | |
1533 | EAP_TYPE_GPSK, | |
1534 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1535 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1536 | 1, 0) | |
1537 | ||
1538 | idx += 1 | |
1539 | if ctx['num'] == idx: | |
1540 | logger.info("Test: GPSK-1 No supported CSuite") | |
1541 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1542 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1543 | EAP_TYPE_GPSK, | |
1544 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1545 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1546 | 6, 0, 0) | |
1547 | ||
1548 | idx += 1 | |
1549 | if ctx['num'] == idx: | |
1550 | logger.info("Test: GPSK-1 Supported CSuite") | |
1551 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1552 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1553 | EAP_TYPE_GPSK, | |
1554 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1555 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1556 | 6, 0, 1) | |
1557 | idx += 1 | |
1558 | if ctx['num'] == idx: | |
1559 | logger.info("Test: Unexpected GPSK-1") | |
1560 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1561 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1562 | EAP_TYPE_GPSK, | |
1563 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1564 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1565 | 6, 0, 1) | |
1566 | ||
1567 | idx += 1 | |
1568 | if ctx['num'] == idx: | |
1569 | logger.info("Test: GPSK-1 Supported CSuite but too short key") | |
1570 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1571 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1572 | EAP_TYPE_GPSK, | |
1573 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1574 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1575 | 6, 0, 1) | |
1576 | ||
1577 | idx += 1 | |
1578 | if ctx['num'] == idx: | |
1579 | logger.info("Test: GPSK-1 Supported CSuite") | |
1580 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1581 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1582 | EAP_TYPE_GPSK, | |
1583 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1584 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1585 | 6, 0, 1) | |
1586 | idx += 1 | |
1587 | if ctx['num'] == idx: | |
1588 | logger.info("Test: Too short GPSK-3") | |
1589 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1590 | 4 + 1 + 1, | |
1591 | EAP_TYPE_GPSK, | |
1592 | EAP_GPSK_OPCODE_GPSK_3) | |
1593 | ||
1594 | idx += 1 | |
1595 | if ctx['num'] == idx: | |
1596 | logger.info("Test: GPSK-1 Supported CSuite") | |
1597 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1598 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1599 | EAP_TYPE_GPSK, | |
1600 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1601 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1602 | 6, 0, 1) | |
1603 | idx += 1 | |
1604 | if ctx['num'] == idx: | |
1605 | logger.info("Test: GPSK-3 Mismatch in RAND_Peer") | |
1606 | return struct.pack(">BBHBB8L", EAP_CODE_REQUEST, ctx['id'], | |
1607 | 4 + 1 + 1 + 32, | |
1608 | EAP_TYPE_GPSK, | |
1609 | EAP_GPSK_OPCODE_GPSK_3, | |
1610 | 0, 0, 0, 0, 0, 0, 0, 0) | |
1611 | ||
1612 | idx += 1 | |
1613 | if ctx['num'] == idx: | |
1614 | logger.info("Test: GPSK-1 Supported CSuite") | |
1615 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1616 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1617 | EAP_TYPE_GPSK, | |
1618 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1619 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1620 | 6, 0, 1) | |
1621 | idx += 1 | |
1622 | if ctx['num'] == idx: | |
1623 | logger.info("Test: GPSK-3 Missing RAND_Server") | |
1624 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1625 | 4 + 1 + 1 + 32, | |
1626 | EAP_TYPE_GPSK, | |
1627 | EAP_GPSK_OPCODE_GPSK_3) | |
1628 | msg += req[14:46] | |
1629 | return msg | |
1630 | ||
1631 | idx += 1 | |
1632 | if ctx['num'] == idx: | |
1633 | logger.info("Test: GPSK-1 Supported CSuite") | |
1634 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1635 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1636 | EAP_TYPE_GPSK, | |
1637 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1638 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1639 | 6, 0, 1) | |
1640 | idx += 1 | |
1641 | if ctx['num'] == idx: | |
1642 | logger.info("Test: GPSK-3 Mismatch in RAND_Server") | |
1643 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1644 | 4 + 1 + 1 + 32 + 32, | |
1645 | EAP_TYPE_GPSK, | |
1646 | EAP_GPSK_OPCODE_GPSK_3) | |
1647 | msg += req[14:46] | |
1648 | msg += struct.pack(">8L", 1, 1, 1, 1, 1, 1, 1, 1) | |
1649 | return msg | |
1650 | ||
1651 | idx += 1 | |
1652 | if ctx['num'] == idx: | |
1653 | logger.info("Test: GPSK-1 Supported CSuite") | |
1654 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1655 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1656 | EAP_TYPE_GPSK, | |
1657 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1658 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1659 | 6, 0, 1) | |
1660 | idx += 1 | |
1661 | if ctx['num'] == idx: | |
1662 | logger.info("Test: GPSK-3 Missing ID_Server") | |
1663 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1664 | 4 + 1 + 1 + 32 + 32, | |
1665 | EAP_TYPE_GPSK, | |
1666 | EAP_GPSK_OPCODE_GPSK_3) | |
1667 | msg += req[14:46] | |
1668 | msg += struct.pack(">8L", 0, 0, 0, 0, 0, 0, 0, 0) | |
1669 | return msg | |
1670 | ||
1671 | idx += 1 | |
1672 | if ctx['num'] == idx: | |
1673 | logger.info("Test: GPSK-1 Supported CSuite") | |
1674 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1675 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1676 | EAP_TYPE_GPSK, | |
1677 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1678 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1679 | 6, 0, 1) | |
1680 | idx += 1 | |
1681 | if ctx['num'] == idx: | |
1682 | logger.info("Test: GPSK-3 Truncated ID_Server") | |
1683 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1684 | 4 + 1 + 1 + 32 + 32 + 2, | |
1685 | EAP_TYPE_GPSK, | |
1686 | EAP_GPSK_OPCODE_GPSK_3) | |
1687 | msg += req[14:46] | |
1688 | msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 1) | |
1689 | return msg | |
1690 | ||
1691 | idx += 1 | |
1692 | if ctx['num'] == idx: | |
1693 | logger.info("Test: GPSK-1 Supported CSuite") | |
1694 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1695 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1696 | EAP_TYPE_GPSK, | |
1697 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1698 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1699 | 6, 0, 1) | |
1700 | idx += 1 | |
1701 | if ctx['num'] == idx: | |
1702 | logger.info("Test: GPSK-3 Mismatch in ID_Server") | |
1703 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1704 | 4 + 1 + 1 + 32 + 32 + 3, | |
1705 | EAP_TYPE_GPSK, | |
1706 | EAP_GPSK_OPCODE_GPSK_3) | |
1707 | msg += req[14:46] | |
1708 | msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B')) | |
1709 | return msg | |
1710 | ||
1711 | idx += 1 | |
1712 | if ctx['num'] == idx: | |
1713 | logger.info("Test: GPSK-1 Supported CSuite") | |
1714 | return struct.pack(">BBHBBHB8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1715 | 4 + 1 + 1 + 3 + 32 + 2 + 6, | |
1716 | EAP_TYPE_GPSK, | |
1717 | EAP_GPSK_OPCODE_GPSK_1, 1, ord('A'), | |
1718 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1719 | 6, 0, 1) | |
1720 | idx += 1 | |
1721 | if ctx['num'] == idx: | |
1722 | logger.info("Test: GPSK-3 Mismatch in ID_Server (same length)") | |
1723 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1724 | 4 + 1 + 1 + 32 + 32 + 3, | |
1725 | EAP_TYPE_GPSK, | |
1726 | EAP_GPSK_OPCODE_GPSK_3) | |
1727 | msg += req[15:47] | |
1728 | msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B')) | |
1729 | return msg | |
1730 | ||
1731 | idx += 1 | |
1732 | if ctx['num'] == idx: | |
1733 | logger.info("Test: GPSK-1 Supported CSuite") | |
1734 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1735 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1736 | EAP_TYPE_GPSK, | |
1737 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1738 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1739 | 6, 0, 1) | |
1740 | idx += 1 | |
1741 | if ctx['num'] == idx: | |
1742 | logger.info("Test: GPSK-3 Missing CSuite_Sel") | |
1743 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1744 | 4 + 1 + 1 + 32 + 32 + 2, | |
1745 | EAP_TYPE_GPSK, | |
1746 | EAP_GPSK_OPCODE_GPSK_3) | |
1747 | msg += req[14:46] | |
1748 | msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 0) | |
1749 | return msg | |
1750 | ||
1751 | idx += 1 | |
1752 | if ctx['num'] == idx: | |
1753 | logger.info("Test: GPSK-1 Supported CSuite") | |
1754 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1755 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1756 | EAP_TYPE_GPSK, | |
1757 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1758 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1759 | 6, 0, 1) | |
1760 | idx += 1 | |
1761 | if ctx['num'] == idx: | |
1762 | logger.info("Test: GPSK-3 Mismatch in CSuite_Sel") | |
1763 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1764 | 4 + 1 + 1 + 32 + 32 + 2 + 6, | |
1765 | EAP_TYPE_GPSK, | |
1766 | EAP_GPSK_OPCODE_GPSK_3) | |
1767 | msg += req[14:46] | |
1768 | msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2) | |
1769 | return msg | |
1770 | ||
1771 | idx += 1 | |
1772 | if ctx['num'] == idx: | |
1773 | logger.info("Test: GPSK-1 Supported CSuite") | |
1774 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1775 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1776 | EAP_TYPE_GPSK, | |
1777 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1778 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1779 | 6, 0, 1) | |
1780 | idx += 1 | |
1781 | if ctx['num'] == idx: | |
1782 | logger.info("Test: GPSK-3 Missing len(PD_Payload_Block)") | |
1783 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1784 | 4 + 1 + 1 + 32 + 32 + 2 + 6, | |
1785 | EAP_TYPE_GPSK, | |
1786 | EAP_GPSK_OPCODE_GPSK_3) | |
1787 | msg += req[14:46] | |
1788 | msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1) | |
1789 | return msg | |
1790 | ||
1791 | idx += 1 | |
1792 | if ctx['num'] == idx: | |
1793 | logger.info("Test: GPSK-1 Supported CSuite") | |
1794 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1795 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1796 | EAP_TYPE_GPSK, | |
1797 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1798 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1799 | 6, 0, 1) | |
1800 | idx += 1 | |
1801 | if ctx['num'] == idx: | |
1802 | logger.info("Test: GPSK-3 Truncated PD_Payload_Block") | |
1803 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1804 | 4 + 1 + 1 + 32 + 32 + 2 + 6 + 2, | |
1805 | EAP_TYPE_GPSK, | |
1806 | EAP_GPSK_OPCODE_GPSK_3) | |
1807 | msg += req[14:46] | |
1808 | msg += struct.pack(">8LHLHH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1) | |
1809 | return msg | |
1810 | ||
1811 | idx += 1 | |
1812 | if ctx['num'] == idx: | |
1813 | logger.info("Test: GPSK-1 Supported CSuite") | |
1814 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1815 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1816 | EAP_TYPE_GPSK, | |
1817 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1818 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1819 | 6, 0, 1) | |
1820 | idx += 1 | |
1821 | if ctx['num'] == idx: | |
1822 | logger.info("Test: GPSK-3 Missing MAC") | |
1823 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1824 | 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3, | |
1825 | EAP_TYPE_GPSK, | |
1826 | EAP_GPSK_OPCODE_GPSK_3) | |
1827 | msg += req[14:46] | |
1828 | msg += struct.pack(">8LHLHHB", | |
1829 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123) | |
1830 | return msg | |
1831 | ||
1832 | idx += 1 | |
1833 | if ctx['num'] == idx: | |
1834 | logger.info("Test: GPSK-1 Supported CSuite") | |
1835 | return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], | |
1836 | 4 + 1 + 1 + 2 + 32 + 2 + 6, | |
1837 | EAP_TYPE_GPSK, | |
1838 | EAP_GPSK_OPCODE_GPSK_1, 0, | |
1839 | 0, 0, 0, 0, 0, 0, 0, 0, | |
1840 | 6, 0, 1) | |
1841 | idx += 1 | |
1842 | if ctx['num'] == idx: | |
1843 | logger.info("Test: GPSK-3 Incorrect MAC") | |
1844 | msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1845 | 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3 + 16, | |
1846 | EAP_TYPE_GPSK, | |
1847 | EAP_GPSK_OPCODE_GPSK_3) | |
1848 | msg += req[14:46] | |
1849 | msg += struct.pack(">8LHLHHB4L", | |
1850 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123, | |
1851 | 0, 0, 0, 0) | |
1852 | return msg | |
1853 | ||
1854 | return None | |
1855 | ||
1856 | srv = start_radius_server(gpsk_handler) | |
2e9f8ee7 JM |
1857 | |
1858 | try: | |
1859 | hapd = start_ap(apdev[0]['ifname']) | |
1860 | ||
1861 | for i in range(0, 27): | |
1862 | if i == 12: | |
1863 | pw = "short" | |
1864 | else: | |
1865 | pw = "abcdefghijklmnop0123456789abcdef" | |
1866 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
1867 | eap="GPSK", identity="user", password=pw, | |
1868 | wait_connect=False) | |
1869 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
1870 | timeout=15) | |
1871 | if ev is None: | |
1872 | raise Exception("Timeout on EAP start") | |
1873 | time.sleep(0.05) | |
1874 | dev[0].request("REMOVE_NETWORK all") | |
1875 | finally: | |
1876 | stop_radius_server(srv) | |
30d62b7a JM |
1877 | |
1878 | EAP_EKE_ID = 1 | |
1879 | EAP_EKE_COMMIT = 2 | |
1880 | EAP_EKE_CONFIRM = 3 | |
1881 | EAP_EKE_FAILURE = 4 | |
1882 | ||
1883 | def test_eap_proto_eke(dev, apdev): | |
1884 | """EAP-EKE protocol tests""" | |
1885 | def eke_handler(ctx, req): | |
1886 | logger.info("eke_handler - RX " + req.encode("hex")) | |
1887 | if 'num' not in ctx: | |
1888 | ctx['num'] = 0 | |
1889 | ctx['num'] = ctx['num'] + 1 | |
1890 | if 'id' not in ctx: | |
1891 | ctx['id'] = 1 | |
1892 | ctx['id'] = (ctx['id'] + 1) % 256 | |
1893 | ||
1894 | idx = 0 | |
1895 | ||
1896 | idx += 1 | |
1897 | if ctx['num'] == idx: | |
1898 | logger.info("Test: Missing payload") | |
1899 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
1900 | 4 + 1, | |
1901 | EAP_TYPE_EKE) | |
1902 | ||
1903 | idx += 1 | |
1904 | if ctx['num'] == idx: | |
1905 | logger.info("Test: Unknown exchange") | |
1906 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1907 | 4 + 1 + 1, | |
1908 | EAP_TYPE_EKE, | |
1909 | 255) | |
1910 | ||
1911 | idx += 1 | |
1912 | if ctx['num'] == idx: | |
1913 | logger.info("Test: No NumProposals in EAP-EKE-ID/Request") | |
1914 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
1915 | 4 + 1 + 1, | |
1916 | EAP_TYPE_EKE, | |
1917 | EAP_EKE_ID) | |
1918 | idx += 1 | |
1919 | if ctx['num'] == idx: | |
1920 | logger.info("Test: EAP-Failure") | |
1921 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
1922 | ||
1923 | idx += 1 | |
1924 | if ctx['num'] == idx: | |
1925 | logger.info("Test: NumProposals=0 in EAP-EKE-ID/Request") | |
1926 | return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], | |
1927 | 4 + 1 + 1 + 1, | |
1928 | EAP_TYPE_EKE, | |
1929 | EAP_EKE_ID, | |
1930 | 0) | |
1931 | idx += 1 | |
1932 | if ctx['num'] == idx: | |
1933 | logger.info("Test: EAP-Failure") | |
1934 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
1935 | ||
1936 | idx += 1 | |
1937 | if ctx['num'] == idx: | |
1938 | logger.info("Test: Truncated Proposals list in EAP-EKE-ID/Request") | |
1939 | return struct.pack(">BBHBBBB4B", EAP_CODE_REQUEST, ctx['id'], | |
1940 | 4 + 1 + 1 + 2 + 4, | |
1941 | EAP_TYPE_EKE, | |
1942 | EAP_EKE_ID, | |
1943 | 2, 0, 0, 0, 0, 0) | |
1944 | idx += 1 | |
1945 | if ctx['num'] == idx: | |
1946 | logger.info("Test: EAP-Failure") | |
1947 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
1948 | ||
1949 | idx += 1 | |
1950 | if ctx['num'] == idx: | |
1951 | logger.info("Test: Unsupported proposals in EAP-EKE-ID/Request") | |
1952 | return struct.pack(">BBHBBBB4B4B4B4B", EAP_CODE_REQUEST, ctx['id'], | |
1953 | 4 + 1 + 1 + 2 + 4 * 4, | |
1954 | EAP_TYPE_EKE, | |
1955 | EAP_EKE_ID, | |
1956 | 4, 0, | |
1957 | 0, 0, 0, 0, | |
1958 | 3, 0, 0, 0, | |
1959 | 3, 1, 0, 0, | |
1960 | 3, 1, 1, 0) | |
1961 | idx += 1 | |
1962 | if ctx['num'] == idx: | |
1963 | logger.info("Test: EAP-Failure") | |
1964 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
1965 | ||
1966 | idx += 1 | |
1967 | if ctx['num'] == idx: | |
1968 | logger.info("Test: Missing IDType/Identity in EAP-EKE-ID/Request") | |
1969 | return struct.pack(">BBHBBBB4B4B4B4B4B", | |
1970 | EAP_CODE_REQUEST, ctx['id'], | |
1971 | 4 + 1 + 1 + 2 + 5 * 4, | |
1972 | EAP_TYPE_EKE, | |
1973 | EAP_EKE_ID, | |
1974 | 5, 0, | |
1975 | 0, 0, 0, 0, | |
1976 | 3, 0, 0, 0, | |
1977 | 3, 1, 0, 0, | |
1978 | 3, 1, 1, 0, | |
1979 | 3, 1, 1, 1) | |
1980 | idx += 1 | |
1981 | if ctx['num'] == idx: | |
1982 | logger.info("Test: EAP-Failure") | |
1983 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
1984 | ||
1985 | idx += 1 | |
1986 | if ctx['num'] == idx: | |
1987 | logger.info("Test: Valid EAP-EKE-ID/Request") | |
1988 | return struct.pack(">BBHBBBB4BB", | |
1989 | EAP_CODE_REQUEST, ctx['id'], | |
1990 | 4 + 1 + 1 + 2 + 4 + 1, | |
1991 | EAP_TYPE_EKE, | |
1992 | EAP_EKE_ID, | |
1993 | 1, 0, | |
1994 | 3, 1, 1, 1, | |
1995 | 255) | |
1996 | idx += 1 | |
1997 | if ctx['num'] == idx: | |
1998 | logger.info("Test: Unexpected EAP-EKE-ID/Request") | |
1999 | return struct.pack(">BBHBBBB4BB", | |
2000 | EAP_CODE_REQUEST, ctx['id'], | |
2001 | 4 + 1 + 1 + 2 + 4 + 1, | |
2002 | EAP_TYPE_EKE, | |
2003 | EAP_EKE_ID, | |
2004 | 1, 0, | |
2005 | 3, 1, 1, 1, | |
2006 | 255) | |
2007 | idx += 1 | |
2008 | if ctx['num'] == idx: | |
2009 | logger.info("Test: EAP-Failure") | |
2010 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2011 | ||
2012 | idx += 1 | |
2013 | if ctx['num'] == idx: | |
2014 | logger.info("Test: Valid EAP-EKE-ID/Request") | |
2015 | return struct.pack(">BBHBBBB4BB", | |
2016 | EAP_CODE_REQUEST, ctx['id'], | |
2017 | 4 + 1 + 1 + 2 + 4 + 1, | |
2018 | EAP_TYPE_EKE, | |
2019 | EAP_EKE_ID, | |
2020 | 1, 0, | |
2021 | 3, 1, 1, 1, | |
2022 | 255) | |
2023 | idx += 1 | |
2024 | if ctx['num'] == idx: | |
2025 | logger.info("Test: Unexpected EAP-EKE-Confirm/Request") | |
2026 | return struct.pack(">BBHBB", | |
2027 | EAP_CODE_REQUEST, ctx['id'], | |
2028 | 4 + 1 + 1, | |
2029 | EAP_TYPE_EKE, | |
2030 | EAP_EKE_CONFIRM) | |
2031 | idx += 1 | |
2032 | if ctx['num'] == idx: | |
2033 | logger.info("Test: EAP-Failure") | |
2034 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2035 | ||
2036 | idx += 1 | |
2037 | if ctx['num'] == idx: | |
2038 | logger.info("Test: Too short EAP-EKE-Failure/Request") | |
2039 | return struct.pack(">BBHBB", | |
2040 | EAP_CODE_REQUEST, ctx['id'], | |
2041 | 4 + 1 + 1, | |
2042 | EAP_TYPE_EKE, | |
2043 | EAP_EKE_FAILURE) | |
2044 | idx += 1 | |
2045 | if ctx['num'] == idx: | |
2046 | logger.info("Test: EAP-Failure") | |
2047 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2048 | ||
2049 | idx += 1 | |
2050 | if ctx['num'] == idx: | |
2051 | logger.info("Test: Unexpected EAP-EKE-Commit/Request") | |
2052 | return struct.pack(">BBHBB", | |
2053 | EAP_CODE_REQUEST, ctx['id'], | |
2054 | 4 + 1 + 1, | |
2055 | EAP_TYPE_EKE, | |
2056 | EAP_EKE_COMMIT) | |
2057 | idx += 1 | |
2058 | if ctx['num'] == idx: | |
2059 | logger.info("Test: EAP-Failure") | |
2060 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2061 | ||
2062 | idx += 1 | |
2063 | if ctx['num'] == idx: | |
2064 | logger.info("Test: Valid EAP-EKE-ID/Request") | |
2065 | return struct.pack(">BBHBBBB4BB", | |
2066 | EAP_CODE_REQUEST, ctx['id'], | |
2067 | 4 + 1 + 1 + 2 + 4 + 1, | |
2068 | EAP_TYPE_EKE, | |
2069 | EAP_EKE_ID, | |
2070 | 1, 0, | |
2071 | 3, 1, 1, 1, | |
2072 | 255) | |
2073 | idx += 1 | |
2074 | if ctx['num'] == idx: | |
2075 | logger.info("Test: Too short EAP-EKE-Commit/Request") | |
2076 | return struct.pack(">BBHBB", | |
2077 | EAP_CODE_REQUEST, ctx['id'], | |
2078 | 4 + 1 + 1, | |
2079 | EAP_TYPE_EKE, | |
2080 | EAP_EKE_COMMIT) | |
2081 | idx += 1 | |
2082 | if ctx['num'] == idx: | |
2083 | logger.info("Test: EAP-Failure") | |
2084 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2085 | ||
2086 | idx += 1 | |
2087 | if ctx['num'] == idx: | |
2088 | logger.info("Test: Valid EAP-EKE-ID/Request") | |
2089 | return struct.pack(">BBHBBBB4BB", | |
2090 | EAP_CODE_REQUEST, ctx['id'], | |
2091 | 4 + 1 + 1 + 2 + 4 + 1, | |
2092 | EAP_TYPE_EKE, | |
2093 | EAP_EKE_ID, | |
2094 | 1, 0, | |
2095 | 1, 1, 1, 1, | |
2096 | 255) | |
2097 | idx += 1 | |
2098 | if ctx['num'] == idx: | |
2099 | logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request") | |
2100 | return struct.pack(">BBHBB4L32L", | |
2101 | EAP_CODE_REQUEST, ctx['id'], | |
2102 | 4 + 1 + 1 + 16 + 128, | |
2103 | EAP_TYPE_EKE, | |
2104 | EAP_EKE_COMMIT, | |
2105 | 0, 0, 0, 0, | |
2106 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
2107 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | |
2108 | idx += 1 | |
2109 | if ctx['num'] == idx: | |
2110 | logger.info("Test: Too short EAP-EKE-Confirm/Request") | |
2111 | return struct.pack(">BBHBB", | |
2112 | EAP_CODE_REQUEST, ctx['id'], | |
2113 | 4 + 1 + 1, | |
2114 | EAP_TYPE_EKE, | |
2115 | EAP_EKE_CONFIRM) | |
2116 | idx += 1 | |
2117 | if ctx['num'] == idx: | |
2118 | logger.info("Test: EAP-Failure") | |
2119 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2120 | ||
2121 | idx += 1 | |
2122 | if ctx['num'] == idx: | |
2123 | logger.info("Test: Valid EAP-EKE-ID/Request") | |
2124 | return struct.pack(">BBHBBBB4BB", | |
2125 | EAP_CODE_REQUEST, ctx['id'], | |
2126 | 4 + 1 + 1 + 2 + 4 + 1, | |
2127 | EAP_TYPE_EKE, | |
2128 | EAP_EKE_ID, | |
2129 | 1, 0, | |
2130 | 1, 1, 1, 1, | |
2131 | 255) | |
2132 | idx += 1 | |
2133 | if ctx['num'] == idx: | |
2134 | logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request") | |
2135 | return struct.pack(">BBHBB4L32L", | |
2136 | EAP_CODE_REQUEST, ctx['id'], | |
2137 | 4 + 1 + 1 + 16 + 128, | |
2138 | EAP_TYPE_EKE, | |
2139 | EAP_EKE_COMMIT, | |
2140 | 0, 0, 0, 0, | |
2141 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
2142 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | |
2143 | idx += 1 | |
2144 | if ctx['num'] == idx: | |
2145 | logger.info("Test: Invalid PNonce_PS and Auth_S values in EAP-EKE-Confirm/Request") | |
2146 | return struct.pack(">BBHBB4L8L5L5L", | |
2147 | EAP_CODE_REQUEST, ctx['id'], | |
2148 | 4 + 1 + 1 + 16 + 2 * 16 + 20 + 20, | |
2149 | EAP_TYPE_EKE, | |
2150 | EAP_EKE_CONFIRM, | |
2151 | 0, 0, 0, 0, | |
2152 | 0, 0, 0, 0, 0, 0, 0, 0, | |
2153 | 0, 0, 0, 0, 0, | |
2154 | 0, 0, 0, 0, 0) | |
2155 | idx += 1 | |
2156 | if ctx['num'] == idx: | |
2157 | logger.info("Test: EAP-Failure") | |
2158 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2159 | ||
2160 | return None | |
2161 | ||
2162 | srv = start_radius_server(eke_handler) | |
30d62b7a JM |
2163 | |
2164 | try: | |
2165 | hapd = start_ap(apdev[0]['ifname']) | |
2166 | ||
2167 | for i in range(0, 14): | |
2168 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
2169 | eap="EKE", identity="user", password="password", | |
2170 | wait_connect=False) | |
2171 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
2172 | timeout=15) | |
2173 | if ev is None: | |
2174 | raise Exception("Timeout on EAP start") | |
2175 | if i in [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]: | |
2176 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], | |
2177 | timeout=10) | |
2178 | if ev is None: | |
2179 | raise Exception("Timeout on EAP failure") | |
2180 | else: | |
2181 | time.sleep(0.05) | |
2182 | dev[0].request("REMOVE_NETWORK all") | |
2183 | dev[0].dump_monitor() | |
2184 | finally: | |
2185 | stop_radius_server(srv) | |
09544316 | 2186 | |
850e054c JM |
2187 | def eap_eke_test_fail(dev, phase1=None, success=False): |
2188 | dev.connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
2189 | eap="EKE", identity="eke user", password="hello", | |
2190 | phase1=phase1, erp="1", wait_connect=False) | |
2191 | ev = dev.wait_event([ "CTRL-EVENT-EAP-FAILURE", | |
2192 | "CTRL-EVENT-EAP-SUCCESS" ], timeout=5) | |
2193 | if ev is None: | |
2194 | raise Exception("Timeout on EAP failure") | |
2195 | if not success and "CTRL-EVENT-EAP-FAILURE" not in ev: | |
2196 | raise Exception("EAP did not fail during failure test") | |
2197 | dev.request("REMOVE_NETWORK all") | |
2198 | dev.wait_disconnected() | |
2199 | ||
2200 | def test_eap_proto_eke_errors(dev, apdev): | |
2201 | """EAP-EKE local error cases""" | |
2202 | check_eap_capa(dev[0], "EKE") | |
2203 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
2204 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
2205 | ||
2206 | for i in range(1, 3): | |
2207 | with alloc_fail(dev[0], i, "eap_eke_init"): | |
2208 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
2209 | eap="EKE", identity="eke user", password="hello", | |
2210 | wait_connect=False) | |
2211 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
2212 | timeout=15) | |
2213 | if ev is None: | |
2214 | raise Exception("Timeout on EAP start") | |
2215 | dev[0].request("REMOVE_NETWORK all") | |
2216 | dev[0].wait_disconnected() | |
2217 | ||
2218 | tests = [ (1, "eap_eke_dh_init", None), | |
2219 | (1, "eap_eke_prf_hmac_sha1", "dhgroup=3 encr=1 prf=1 mac=1"), | |
2220 | (1, "eap_eke_prf_hmac_sha256", "dhgroup=5 encr=1 prf=2 mac=2"), | |
2221 | (1, "eap_eke_prf", None), | |
2222 | (1, "os_get_random;eap_eke_dhcomp", None), | |
2223 | (1, "aes_128_cbc_encrypt;eap_eke_dhcomp", None), | |
2224 | (1, "aes_128_cbc_decrypt;eap_eke_shared_secret", None), | |
2225 | (1, "eap_eke_prf;eap_eke_shared_secret", None), | |
2226 | (1, "eap_eke_prfplus;eap_eke_derive_ke_ki", None), | |
2227 | (1, "eap_eke_prfplus;eap_eke_derive_ka", None), | |
2228 | (1, "eap_eke_prfplus;eap_eke_derive_msk", None), | |
2229 | (1, "os_get_random;eap_eke_prot", None), | |
2230 | (1, "aes_128_cbc_decrypt;eap_eke_decrypt_prot", None), | |
2231 | (1, "eap_eke_derive_key;eap_eke_process_commit", None), | |
2232 | (1, "eap_eke_dh_init;eap_eke_process_commit", None), | |
2233 | (1, "eap_eke_shared_secret;eap_eke_process_commit", None), | |
2234 | (1, "eap_eke_derive_ke_ki;eap_eke_process_commit", None), | |
2235 | (1, "eap_eke_dhcomp;eap_eke_process_commit", None), | |
2236 | (1, "os_get_random;eap_eke_process_commit", None), | |
2237 | (1, "os_get_random;=eap_eke_process_commit", None), | |
2238 | (1, "eap_eke_prot;eap_eke_process_commit", None), | |
2239 | (1, "eap_eke_decrypt_prot;eap_eke_process_confirm", None), | |
2240 | (1, "eap_eke_derive_ka;eap_eke_process_confirm", None), | |
2241 | (1, "eap_eke_auth;eap_eke_process_confirm", None), | |
2242 | (2, "eap_eke_auth;eap_eke_process_confirm", None), | |
2243 | (1, "eap_eke_prot;eap_eke_process_confirm", None), | |
2244 | (1, "eap_eke_derive_msk;eap_eke_process_confirm", None) ] | |
2245 | for count, func, phase1 in tests: | |
2246 | with fail_test(dev[0], count, func): | |
2247 | eap_eke_test_fail(dev[0], phase1) | |
2248 | ||
2249 | tests = [ (1, "=eap_eke_derive_ke_ki", None), | |
2250 | (1, "=eap_eke_derive_ka", None), | |
2251 | (1, "=eap_eke_derive_msk", None), | |
2252 | (1, "eap_eke_build_msg;eap_eke_process_id", None), | |
2253 | (1, "wpabuf_alloc;eap_eke_process_id", None), | |
2254 | (1, "=eap_eke_process_id", None), | |
491e2d26 | 2255 | (1, "wpabuf_alloc;=eap_eke_process_id", None), |
850e054c JM |
2256 | (1, "wpabuf_alloc;eap_eke_process_id", None), |
2257 | (1, "eap_eke_build_msg;eap_eke_process_commit", None), | |
2258 | (1, "wpabuf_resize;eap_eke_process_commit", None), | |
2259 | (1, "eap_eke_build_msg;eap_eke_process_confirm", None) ] | |
2260 | for count, func, phase1 in tests: | |
2261 | with alloc_fail(dev[0], count, func): | |
2262 | eap_eke_test_fail(dev[0], phase1) | |
2263 | ||
2264 | tests = [ (1, "eap_eke_getKey", None), | |
2265 | (1, "eap_eke_get_emsk", None), | |
2266 | (1, "eap_eke_get_session_id", None) ] | |
2267 | for count, func, phase1 in tests: | |
2268 | with alloc_fail(dev[0], count, func): | |
2269 | eap_eke_test_fail(dev[0], phase1, success=True) | |
2270 | ||
09544316 JM |
2271 | EAP_PAX_OP_STD_1 = 0x01 |
2272 | EAP_PAX_OP_STD_2 = 0x02 | |
2273 | EAP_PAX_OP_STD_3 = 0x03 | |
2274 | EAP_PAX_OP_SEC_1 = 0x11 | |
2275 | EAP_PAX_OP_SEC_2 = 0x12 | |
2276 | EAP_PAX_OP_SEC_3 = 0x13 | |
2277 | EAP_PAX_OP_SEC_4 = 0x14 | |
2278 | EAP_PAX_OP_SEC_5 = 0x15 | |
2279 | EAP_PAX_OP_ACK = 0x21 | |
2280 | ||
2281 | EAP_PAX_FLAGS_MF = 0x01 | |
2282 | EAP_PAX_FLAGS_CE = 0x02 | |
2283 | EAP_PAX_FLAGS_AI = 0x04 | |
2284 | ||
2285 | EAP_PAX_MAC_HMAC_SHA1_128 = 0x01 | |
2286 | EAP_PAX_HMAC_SHA256_128 = 0x02 | |
2287 | ||
2288 | EAP_PAX_DH_GROUP_NONE = 0x00 | |
2289 | EAP_PAX_DH_GROUP_2048_MODP = 0x01 | |
2290 | EAP_PAX_DH_GROUP_3072_MODP = 0x02 | |
2291 | EAP_PAX_DH_GROUP_NIST_ECC_P_256 = 0x03 | |
2292 | ||
2293 | EAP_PAX_PUBLIC_KEY_NONE = 0x00 | |
2294 | EAP_PAX_PUBLIC_KEY_RSAES_OAEP = 0x01 | |
2295 | EAP_PAX_PUBLIC_KEY_RSA_PKCS1_V1_5 = 0x02 | |
2296 | EAP_PAX_PUBLIC_KEY_EL_GAMAL_NIST_ECC = 0x03 | |
2297 | ||
2298 | EAP_PAX_ADE_VENDOR_SPECIFIC = 0x01 | |
2299 | EAP_PAX_ADE_CLIENT_CHANNEL_BINDING = 0x02 | |
2300 | EAP_PAX_ADE_SERVER_CHANNEL_BINDING = 0x03 | |
2301 | ||
2302 | def test_eap_proto_pax(dev, apdev): | |
2303 | """EAP-PAX protocol tests""" | |
2304 | def pax_std_1(ctx): | |
2305 | logger.info("Test: STD-1") | |
2306 | ctx['id'] = 10 | |
2307 | return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], | |
2308 | 4 + 1 + 5 + 2 + 32 + 16, | |
2309 | EAP_TYPE_PAX, | |
2310 | EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2311 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2312 | 32, 0, 0, 0, 0, 0, 0, 0, 0, | |
2313 | 0x16, 0xc9, 0x08, 0x9d, 0x98, 0xa5, 0x6e, 0x1f, | |
2314 | 0xf0, 0xac, 0xcf, 0xc4, 0x66, 0xcd, 0x2d, 0xbf) | |
2315 | ||
2316 | def pax_handler(ctx, req): | |
2317 | logger.info("pax_handler - RX " + req.encode("hex")) | |
2318 | if 'num' not in ctx: | |
2319 | ctx['num'] = 0 | |
2320 | ctx['num'] = ctx['num'] + 1 | |
2321 | if 'id' not in ctx: | |
2322 | ctx['id'] = 1 | |
2323 | ctx['id'] = (ctx['id'] + 1) % 256 | |
2324 | ||
2325 | idx = 0 | |
2326 | ||
2327 | idx += 1 | |
2328 | if ctx['num'] == idx: | |
2329 | logger.info("Test: Missing payload") | |
2330 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
2331 | 4 + 1, | |
2332 | EAP_TYPE_PAX) | |
2333 | ||
2334 | idx += 1 | |
2335 | if ctx['num'] == idx: | |
2336 | logger.info("Test: Minimum length payload") | |
2337 | return struct.pack(">BBHB4L", EAP_CODE_REQUEST, ctx['id'], | |
2338 | 4 + 1 + 16, | |
2339 | EAP_TYPE_PAX, | |
2340 | 0, 0, 0, 0) | |
2341 | ||
2342 | idx += 1 | |
2343 | if ctx['num'] == idx: | |
2344 | logger.info("Test: Unsupported MAC ID") | |
2345 | return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], | |
2346 | 4 + 1 + 5 + 16, | |
2347 | EAP_TYPE_PAX, | |
2348 | EAP_PAX_OP_STD_1, 0, 255, EAP_PAX_DH_GROUP_NONE, | |
2349 | EAP_PAX_PUBLIC_KEY_NONE, | |
2350 | 0, 0, 0, 0) | |
2351 | ||
2352 | idx += 1 | |
2353 | if ctx['num'] == idx: | |
2354 | logger.info("Test: Unsupported DH Group ID") | |
2355 | return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], | |
2356 | 4 + 1 + 5 + 16, | |
2357 | EAP_TYPE_PAX, | |
2358 | EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2359 | 255, EAP_PAX_PUBLIC_KEY_NONE, | |
2360 | 0, 0, 0, 0) | |
2361 | ||
2362 | idx += 1 | |
2363 | if ctx['num'] == idx: | |
2364 | logger.info("Test: Unsupported Public Key ID") | |
2365 | return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], | |
2366 | 4 + 1 + 5 + 16, | |
2367 | EAP_TYPE_PAX, | |
2368 | EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2369 | EAP_PAX_DH_GROUP_NONE, 255, | |
2370 | 0, 0, 0, 0) | |
2371 | ||
2372 | idx += 1 | |
2373 | if ctx['num'] == idx: | |
2374 | logger.info("Test: More fragments") | |
2375 | return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], | |
2376 | 4 + 1 + 5 + 16, | |
2377 | EAP_TYPE_PAX, | |
2378 | EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_MF, | |
2379 | EAP_PAX_MAC_HMAC_SHA1_128, | |
2380 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2381 | 0, 0, 0, 0) | |
2382 | ||
2383 | idx += 1 | |
2384 | if ctx['num'] == idx: | |
2385 | logger.info("Test: Invalid ICV") | |
2386 | return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], | |
2387 | 4 + 1 + 5 + 16, | |
2388 | EAP_TYPE_PAX, | |
2389 | EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2390 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2391 | 0, 0, 0, 0) | |
2392 | ||
2393 | idx += 1 | |
2394 | if ctx['num'] == idx: | |
2395 | logger.info("Test: Invalid ICV in short frame") | |
2396 | return struct.pack(">BBHBBBBBB3L", EAP_CODE_REQUEST, ctx['id'], | |
2397 | 4 + 1 + 5 + 12, | |
2398 | EAP_TYPE_PAX, | |
2399 | EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2400 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2401 | 0, 0, 0) | |
2402 | ||
2403 | idx += 1 | |
2404 | if ctx['num'] == idx: | |
2405 | logger.info("Test: Correct ICV - unsupported op_code") | |
2406 | ctx['id'] = 10 | |
2407 | return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'], | |
2408 | 4 + 1 + 5 + 16, | |
2409 | EAP_TYPE_PAX, | |
2410 | 255, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2411 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2412 | 0x90, 0x78, 0x97, 0x38, 0x29, 0x94, 0x32, 0xd4, | |
2413 | 0x81, 0x27, 0xe0, 0xf6, 0x3b, 0x0d, 0xb2, 0xb2) | |
2414 | ||
2415 | idx += 1 | |
2416 | if ctx['num'] == idx: | |
2417 | logger.info("Test: Correct ICV - CE flag in STD-1") | |
2418 | ctx['id'] = 10 | |
2419 | return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'], | |
2420 | 4 + 1 + 5 + 16, | |
2421 | EAP_TYPE_PAX, | |
2422 | EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_CE, | |
2423 | EAP_PAX_MAC_HMAC_SHA1_128, | |
2424 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2425 | 0x9c, 0x98, 0xb4, 0x0b, 0x94, 0x90, 0xde, 0x88, | |
2426 | 0xb7, 0x72, 0x63, 0x44, 0x1d, 0xe3, 0x7c, 0x5c) | |
2427 | ||
2428 | idx += 1 | |
2429 | if ctx['num'] == idx: | |
2430 | logger.info("Test: Correct ICV - too short STD-1 payload") | |
2431 | ctx['id'] = 10 | |
2432 | return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'], | |
2433 | 4 + 1 + 5 + 16, | |
2434 | EAP_TYPE_PAX, | |
2435 | EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2436 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2437 | 0xda, 0xab, 0x2c, 0xe7, 0x84, 0x41, 0xb5, 0x5c, | |
2438 | 0xee, 0xcf, 0x62, 0x03, 0xc5, 0x69, 0xcb, 0xf4) | |
2439 | ||
2440 | idx += 1 | |
2441 | if ctx['num'] == idx: | |
2442 | logger.info("Test: Correct ICV - incorrect A length in STD-1") | |
2443 | ctx['id'] = 10 | |
2444 | return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], | |
2445 | 4 + 1 + 5 + 2 + 32 + 16, | |
2446 | EAP_TYPE_PAX, | |
2447 | EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2448 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2449 | 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
2450 | 0xc4, 0xb0, 0x81, 0xe4, 0x6c, 0x8c, 0x20, 0x23, | |
2451 | 0x60, 0x46, 0x89, 0xea, 0x94, 0x60, 0xf3, 0x2a) | |
2452 | ||
2453 | idx += 1 | |
2454 | if ctx['num'] == idx: | |
2455 | logger.info("Test: Correct ICV - extra data in STD-1") | |
2456 | ctx['id'] = 10 | |
2457 | return struct.pack(">BBHBBBBBBH8LB16B", EAP_CODE_REQUEST, ctx['id'], | |
2458 | 4 + 1 + 5 + 2 + 32 + 1 + 16, | |
2459 | EAP_TYPE_PAX, | |
2460 | EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2461 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2462 | 32, 0, 0, 0, 0, 0, 0, 0, 0, | |
2463 | 1, | |
2464 | 0x61, 0x49, 0x65, 0x37, 0x21, 0xe8, 0xd8, 0xbf, | |
2465 | 0xf3, 0x02, 0x01, 0xe5, 0x42, 0x51, 0xd3, 0x34) | |
2466 | idx += 1 | |
2467 | if ctx['num'] == idx: | |
2468 | logger.info("Test: Unexpected STD-1") | |
2469 | return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], | |
2470 | 4 + 1 + 5 + 2 + 32 + 16, | |
2471 | EAP_TYPE_PAX, | |
2472 | EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2473 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2474 | 32, 0, 0, 0, 0, 0, 0, 0, 0, | |
2475 | 0xe5, 0x1d, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, | |
2476 | 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) | |
2477 | ||
2478 | idx += 1 | |
2479 | if ctx['num'] == idx: | |
2480 | return pax_std_1(ctx) | |
2481 | idx += 1 | |
2482 | if ctx['num'] == idx: | |
2483 | logger.info("Test: MAC ID changed during session") | |
2484 | return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], | |
2485 | 4 + 1 + 5 + 2 + 32 + 16, | |
2486 | EAP_TYPE_PAX, | |
2487 | EAP_PAX_OP_STD_1, 0, EAP_PAX_HMAC_SHA256_128, | |
2488 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2489 | 32, 0, 0, 0, 0, 0, 0, 0, 0, | |
2490 | 0xee, 0x00, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, | |
2491 | 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) | |
2492 | ||
2493 | idx += 1 | |
2494 | if ctx['num'] == idx: | |
2495 | return pax_std_1(ctx) | |
2496 | idx += 1 | |
2497 | if ctx['num'] == idx: | |
2498 | logger.info("Test: DH Group ID changed during session") | |
2499 | return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], | |
2500 | 4 + 1 + 5 + 2 + 32 + 16, | |
2501 | EAP_TYPE_PAX, | |
2502 | EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2503 | EAP_PAX_DH_GROUP_2048_MODP, | |
2504 | EAP_PAX_PUBLIC_KEY_NONE, | |
2505 | 32, 0, 0, 0, 0, 0, 0, 0, 0, | |
2506 | 0xee, 0x01, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, | |
2507 | 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) | |
2508 | ||
2509 | idx += 1 | |
2510 | if ctx['num'] == idx: | |
2511 | return pax_std_1(ctx) | |
2512 | idx += 1 | |
2513 | if ctx['num'] == idx: | |
2514 | logger.info("Test: Public Key ID changed during session") | |
2515 | return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], | |
2516 | 4 + 1 + 5 + 2 + 32 + 16, | |
2517 | EAP_TYPE_PAX, | |
2518 | EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2519 | EAP_PAX_DH_GROUP_NONE, | |
2520 | EAP_PAX_PUBLIC_KEY_RSAES_OAEP, | |
2521 | 32, 0, 0, 0, 0, 0, 0, 0, 0, | |
2522 | 0xee, 0x02, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, | |
2523 | 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) | |
2524 | ||
2525 | idx += 1 | |
2526 | if ctx['num'] == idx: | |
2527 | logger.info("Test: Unexpected STD-3") | |
2528 | ctx['id'] = 10 | |
2529 | return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], | |
2530 | 4 + 1 + 5 + 2 + 32 + 16, | |
2531 | EAP_TYPE_PAX, | |
2532 | EAP_PAX_OP_STD_3, 0, EAP_PAX_MAC_HMAC_SHA1_128, | |
2533 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2534 | 32, 0, 0, 0, 0, 0, 0, 0, 0, | |
2535 | 0x47, 0xbb, 0xc0, 0xf9, 0xb9, 0x69, 0xf5, 0xcb, | |
2536 | 0x3a, 0xe8, 0xe7, 0xd6, 0x80, 0x28, 0xf2, 0x59) | |
2537 | ||
2538 | idx += 1 | |
2539 | if ctx['num'] == idx: | |
2540 | return pax_std_1(ctx) | |
2541 | idx += 1 | |
2542 | if ctx['num'] == idx: | |
2543 | # TODO: MAC calculation; for now, this gets dropped due to incorrect | |
2544 | # ICV | |
2545 | logger.info("Test: STD-3 with CE flag") | |
2546 | return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], | |
2547 | 4 + 1 + 5 + 2 + 32 + 16, | |
2548 | EAP_TYPE_PAX, | |
2549 | EAP_PAX_OP_STD_3, EAP_PAX_FLAGS_CE, | |
2550 | EAP_PAX_MAC_HMAC_SHA1_128, | |
2551 | EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, | |
2552 | 32, 0, 0, 0, 0, 0, 0, 0, 0, | |
2553 | 0x8a, 0xc2, 0xf9, 0xf4, 0x8b, 0x75, 0x72, 0xa2, | |
2554 | 0x4d, 0xd3, 0x1e, 0x54, 0x77, 0x04, 0x05, 0xe2) | |
2555 | ||
2556 | idx += 1 | |
2557 | if ctx['num'] & 0x1 == idx & 0x1: | |
2558 | logger.info("Test: Default request") | |
2559 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
2560 | 4 + 1, | |
2561 | EAP_TYPE_PAX) | |
2562 | else: | |
2563 | logger.info("Test: Default EAP-Failure") | |
2564 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2565 | ||
2566 | srv = start_radius_server(pax_handler) | |
09544316 JM |
2567 | |
2568 | try: | |
2569 | hapd = start_ap(apdev[0]['ifname']) | |
2570 | ||
2571 | for i in range(0, 18): | |
2572 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
2573 | eap="PAX", identity="user", | |
2574 | password_hex="0123456789abcdef0123456789abcdef", | |
2575 | wait_connect=False) | |
2576 | logger.info("Waiting for EAP method to start") | |
2577 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
2578 | timeout=15) | |
2579 | if ev is None: | |
2580 | raise Exception("Timeout on EAP start") | |
2581 | time.sleep(0.05) | |
2582 | dev[0].request("REMOVE_NETWORK all") | |
2583 | dev[0].dump_monitor() | |
2584 | ||
2585 | logger.info("Too short password") | |
2586 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
2587 | eap="PAX", identity="user", | |
2588 | password_hex="0123456789abcdef0123456789abcd", | |
2589 | wait_connect=False) | |
2590 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
2591 | if ev is None: | |
2592 | raise Exception("Timeout on EAP start") | |
2593 | time.sleep(0.1) | |
2594 | dev[0].request("REMOVE_NETWORK all") | |
2595 | dev[0].dump_monitor() | |
2596 | ||
2597 | logger.info("No password") | |
2598 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
2599 | eap="PAX", identity="user", | |
2600 | wait_connect=False) | |
2601 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
2602 | if ev is None: | |
2603 | raise Exception("Timeout on EAP start") | |
2604 | time.sleep(0.1) | |
2605 | dev[0].request("REMOVE_NETWORK all") | |
2606 | dev[0].dump_monitor() | |
2607 | finally: | |
2608 | stop_radius_server(srv) | |
e0534ecf JM |
2609 | |
2610 | def test_eap_proto_psk(dev, apdev): | |
2611 | """EAP-PSK protocol tests""" | |
2612 | def psk_handler(ctx, req): | |
2613 | logger.info("psk_handler - RX " + req.encode("hex")) | |
2614 | if 'num' not in ctx: | |
2615 | ctx['num'] = 0 | |
2616 | ctx['num'] = ctx['num'] + 1 | |
2617 | if 'id' not in ctx: | |
2618 | ctx['id'] = 1 | |
2619 | ctx['id'] = (ctx['id'] + 1) % 256 | |
2620 | ||
2621 | idx = 0 | |
2622 | ||
2623 | idx += 1 | |
2624 | if ctx['num'] == idx: | |
2625 | logger.info("Test: Missing payload") | |
2626 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
2627 | 4 + 1, | |
2628 | EAP_TYPE_PSK) | |
2629 | ||
2630 | idx += 1 | |
2631 | if ctx['num'] == idx: | |
2632 | logger.info("Test: Non-zero T in first message") | |
2633 | return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], | |
2634 | 4 + 1 + 1 + 16, | |
2635 | EAP_TYPE_PSK, 0xc0, 0, 0, 0, 0) | |
2636 | ||
2637 | idx += 1 | |
2638 | if ctx['num'] == idx: | |
2639 | logger.info("Test: Valid first message") | |
2640 | return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], | |
2641 | 4 + 1 + 1 + 16, | |
2642 | EAP_TYPE_PSK, 0, 0, 0, 0, 0) | |
2643 | idx += 1 | |
2644 | if ctx['num'] == idx: | |
2645 | logger.info("Test: Too short third message") | |
2646 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
2647 | 4 + 1, | |
2648 | EAP_TYPE_PSK) | |
2649 | ||
2650 | idx += 1 | |
2651 | if ctx['num'] == idx: | |
2652 | logger.info("Test: Valid first message") | |
2653 | return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], | |
2654 | 4 + 1 + 1 + 16, | |
2655 | EAP_TYPE_PSK, 0, 0, 0, 0, 0) | |
2656 | idx += 1 | |
2657 | if ctx['num'] == idx: | |
2658 | logger.info("Test: Incorrect T in third message") | |
2659 | return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'], | |
2660 | 4 + 1 + 1 + 16 + 16, | |
2661 | EAP_TYPE_PSK, 0, 0, 0, 0, 0, 0, 0, 0, 0) | |
2662 | ||
2663 | idx += 1 | |
2664 | if ctx['num'] == idx: | |
2665 | logger.info("Test: Valid first message") | |
2666 | return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], | |
2667 | 4 + 1 + 1 + 16, | |
2668 | EAP_TYPE_PSK, 0, 0, 0, 0, 0) | |
2669 | idx += 1 | |
2670 | if ctx['num'] == idx: | |
2671 | logger.info("Test: Missing PCHANNEL in third message") | |
2672 | return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'], | |
2673 | 4 + 1 + 1 + 16 + 16, | |
2674 | EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0) | |
2675 | ||
2676 | idx += 1 | |
2677 | if ctx['num'] == idx: | |
2678 | logger.info("Test: Valid first message") | |
2679 | return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], | |
2680 | 4 + 1 + 1 + 16, | |
2681 | EAP_TYPE_PSK, 0, 0, 0, 0, 0) | |
2682 | idx += 1 | |
2683 | if ctx['num'] == idx: | |
2684 | logger.info("Test: Invalic MAC_S in third message") | |
2685 | return struct.pack(">BBHBB4L4L5LB", EAP_CODE_REQUEST, ctx['id'], | |
2686 | 4 + 1 + 1 + 16 + 16 + 21, | |
2687 | EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, | |
2688 | 0, 0, 0, 0, 0, 0) | |
2689 | ||
2690 | idx += 1 | |
2691 | if ctx['num'] == idx: | |
2692 | logger.info("Test: Valid first message") | |
2693 | return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], | |
2694 | 4 + 1 + 1 + 16, | |
2695 | EAP_TYPE_PSK, 0, 0, 0, 0, 0) | |
2696 | idx += 1 | |
2697 | if ctx['num'] == idx: | |
2698 | logger.info("Test: EAP-Failure") | |
2699 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2700 | ||
2701 | return None | |
2702 | ||
2703 | srv = start_radius_server(psk_handler) | |
e0534ecf JM |
2704 | |
2705 | try: | |
2706 | hapd = start_ap(apdev[0]['ifname']) | |
2707 | ||
2708 | for i in range(0, 6): | |
2709 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
2710 | eap="PSK", identity="user", | |
2711 | password_hex="0123456789abcdef0123456789abcdef", | |
2712 | wait_connect=False) | |
2713 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
2714 | timeout=15) | |
2715 | if ev is None: | |
2716 | raise Exception("Timeout on EAP start") | |
2717 | time.sleep(0.1) | |
2718 | dev[0].request("REMOVE_NETWORK all") | |
2719 | ||
2720 | logger.info("Test: Invalid PSK length") | |
2721 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
2722 | eap="PSK", identity="user", | |
2723 | password_hex="0123456789abcdef0123456789abcd", | |
2724 | wait_connect=False) | |
2725 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
2726 | timeout=15) | |
2727 | if ev is None: | |
2728 | raise Exception("Timeout on EAP start") | |
2729 | time.sleep(0.1) | |
2730 | dev[0].request("REMOVE_NETWORK all") | |
2731 | finally: | |
2732 | stop_radius_server(srv) | |
6c080dfa | 2733 | |
b4e1e995 JM |
2734 | def test_eap_proto_psk_errors(dev, apdev): |
2735 | """EAP-PSK local error cases""" | |
2736 | check_eap_capa(dev[0], "PSK") | |
2737 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
2738 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
2739 | ||
2740 | for i in range(1, 6): | |
2741 | with alloc_fail(dev[0], i, "eap_psk_init"): | |
2742 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
2743 | eap="PSK", identity="psk.user@example.com", | |
2744 | password_hex="0123456789abcdef0123456789abcdef", | |
2745 | wait_connect=False) | |
2746 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
2747 | timeout=15) | |
2748 | if ev is None: | |
2749 | raise Exception("Timeout on EAP start") | |
2750 | dev[0].request("REMOVE_NETWORK all") | |
2751 | dev[0].wait_disconnected() | |
2752 | ||
2753 | tests = [ (1, "=eap_psk_process_1"), | |
2754 | (2, "=eap_psk_process_1"), | |
2755 | (1, "eap_msg_alloc;eap_psk_process_1"), | |
2756 | (1, "=eap_psk_process_3"), | |
2757 | (2, "=eap_psk_process_3"), | |
2758 | (1, "eap_msg_alloc;eap_psk_process_3"), | |
2759 | (1, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), | |
2760 | (2, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), | |
2761 | (3, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), | |
2762 | (4, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), | |
2763 | (5, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), | |
2764 | (6, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), | |
2765 | (7, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), | |
2766 | (8, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), | |
2767 | (9, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), | |
2768 | (10, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), | |
2769 | (1, "aes_128_ctr_encrypt;aes_128_eax_decrypt;eap_psk_process_3"), | |
2770 | (1, "aes_128_ctr_encrypt;aes_128_eax_encrypt;eap_psk_process_3"), | |
2771 | (1, "eap_psk_getKey"), | |
2772 | (1, "eap_psk_get_session_id"), | |
2773 | (1, "eap_psk_get_emsk") ] | |
2774 | for count, func in tests: | |
2775 | with alloc_fail(dev[0], count, func): | |
2776 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
2777 | eap="PSK", identity="psk.user@example.com", | |
2778 | password_hex="0123456789abcdef0123456789abcdef", | |
2779 | erp="1", wait_connect=False) | |
2780 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
2781 | timeout=15) | |
2782 | if ev is None: | |
2783 | raise Exception("Timeout on EAP start") | |
2784 | ok = False | |
2785 | for j in range(10): | |
2786 | state = dev[0].request('GET_ALLOC_FAIL') | |
2787 | if state.startswith('0:'): | |
2788 | ok = True | |
2789 | break | |
2790 | time.sleep(0.1) | |
2791 | if not ok: | |
2792 | raise Exception("No allocation failure seen for %d:%s" % (count, func)) | |
2793 | dev[0].request("REMOVE_NETWORK all") | |
2794 | dev[0].wait_disconnected() | |
2795 | ||
2796 | tests = [ (1, "os_get_random;eap_psk_process_1"), | |
2797 | (1, "omac1_aes_128;eap_psk_process_3"), | |
2798 | (1, "aes_128_eax_decrypt;eap_psk_process_3"), | |
2799 | (2, "aes_128_eax_decrypt;eap_psk_process_3"), | |
2800 | (3, "aes_128_eax_decrypt;eap_psk_process_3"), | |
2801 | (1, "aes_128_eax_encrypt;eap_psk_process_3"), | |
2802 | (2, "aes_128_eax_encrypt;eap_psk_process_3"), | |
2803 | (3, "aes_128_eax_encrypt;eap_psk_process_3") ] | |
2804 | for count, func in tests: | |
2805 | with fail_test(dev[0], count, func): | |
2806 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
2807 | eap="PSK", identity="psk.user@example.com", | |
2808 | password_hex="0123456789abcdef0123456789abcdef", | |
2809 | wait_connect=False) | |
2810 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
2811 | timeout=15) | |
2812 | if ev is None: | |
2813 | raise Exception("Timeout on EAP start") | |
2814 | ok = False | |
2815 | for j in range(10): | |
2816 | state = dev[0].request('GET_FAIL') | |
2817 | if state.startswith('0:'): | |
2818 | ok = True | |
2819 | break | |
2820 | time.sleep(0.1) | |
2821 | if not ok: | |
2822 | raise Exception("No failure seen for %d:%s" % (count, func)) | |
2823 | dev[0].request("REMOVE_NETWORK all") | |
2824 | dev[0].wait_disconnected() | |
2825 | ||
6c080dfa JM |
2826 | EAP_SIM_SUBTYPE_START = 10 |
2827 | EAP_SIM_SUBTYPE_CHALLENGE = 11 | |
2828 | EAP_SIM_SUBTYPE_NOTIFICATION = 12 | |
2829 | EAP_SIM_SUBTYPE_REAUTHENTICATION = 13 | |
2830 | EAP_SIM_SUBTYPE_CLIENT_ERROR = 14 | |
2831 | ||
2832 | EAP_AKA_SUBTYPE_CHALLENGE = 1 | |
2833 | EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT = 2 | |
2834 | EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE = 4 | |
2835 | EAP_AKA_SUBTYPE_IDENTITY = 5 | |
2836 | EAP_AKA_SUBTYPE_NOTIFICATION = 12 | |
2837 | EAP_AKA_SUBTYPE_REAUTHENTICATION = 13 | |
2838 | EAP_AKA_SUBTYPE_CLIENT_ERROR = 14 | |
2839 | ||
2840 | EAP_SIM_AT_RAND = 1 | |
2841 | EAP_SIM_AT_AUTN = 2 | |
2842 | EAP_SIM_AT_RES = 3 | |
2843 | EAP_SIM_AT_AUTS = 4 | |
2844 | EAP_SIM_AT_PADDING = 6 | |
2845 | EAP_SIM_AT_NONCE_MT = 7 | |
2846 | EAP_SIM_AT_PERMANENT_ID_REQ = 10 | |
2847 | EAP_SIM_AT_MAC = 11 | |
2848 | EAP_SIM_AT_NOTIFICATION = 12 | |
2849 | EAP_SIM_AT_ANY_ID_REQ = 13 | |
2850 | EAP_SIM_AT_IDENTITY = 14 | |
2851 | EAP_SIM_AT_VERSION_LIST = 15 | |
2852 | EAP_SIM_AT_SELECTED_VERSION = 16 | |
2853 | EAP_SIM_AT_FULLAUTH_ID_REQ = 17 | |
2854 | EAP_SIM_AT_COUNTER = 19 | |
2855 | EAP_SIM_AT_COUNTER_TOO_SMALL = 20 | |
2856 | EAP_SIM_AT_NONCE_S = 21 | |
2857 | EAP_SIM_AT_CLIENT_ERROR_CODE = 22 | |
2858 | EAP_SIM_AT_KDF_INPUT = 23 | |
2859 | EAP_SIM_AT_KDF = 24 | |
2860 | EAP_SIM_AT_IV = 129 | |
2861 | EAP_SIM_AT_ENCR_DATA = 130 | |
2862 | EAP_SIM_AT_NEXT_PSEUDONYM = 132 | |
2863 | EAP_SIM_AT_NEXT_REAUTH_ID = 133 | |
2864 | EAP_SIM_AT_CHECKCODE = 134 | |
2865 | EAP_SIM_AT_RESULT_IND = 135 | |
2866 | EAP_SIM_AT_BIDDING = 136 | |
2867 | ||
2868 | def test_eap_proto_aka(dev, apdev): | |
2869 | """EAP-AKA protocol tests""" | |
2870 | def aka_handler(ctx, req): | |
2871 | logger.info("aka_handler - RX " + req.encode("hex")) | |
2872 | if 'num' not in ctx: | |
2873 | ctx['num'] = 0 | |
2874 | ctx['num'] = ctx['num'] + 1 | |
2875 | if 'id' not in ctx: | |
2876 | ctx['id'] = 1 | |
2877 | ctx['id'] = (ctx['id'] + 1) % 256 | |
2878 | ||
2879 | idx = 0 | |
2880 | ||
2881 | idx += 1 | |
2882 | if ctx['num'] == idx: | |
2883 | logger.info("Test: Missing payload") | |
2884 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
2885 | 4 + 1, | |
2886 | EAP_TYPE_AKA) | |
2887 | ||
2888 | idx += 1 | |
2889 | if ctx['num'] == idx: | |
2890 | logger.info("Test: Unknown subtype") | |
f0174bff JM |
2891 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], |
2892 | 4 + 1 + 3, | |
2893 | EAP_TYPE_AKA, 255, 0) | |
6c080dfa JM |
2894 | idx += 1 |
2895 | if ctx['num'] == idx: | |
2896 | logger.info("Test: EAP-Failure") | |
2897 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2898 | ||
2899 | idx += 1 | |
2900 | if ctx['num'] == idx: | |
2901 | logger.info("Test: Client Error") | |
f0174bff JM |
2902 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], |
2903 | 4 + 1 + 3, | |
2904 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CLIENT_ERROR, 0) | |
6c080dfa JM |
2905 | idx += 1 |
2906 | if ctx['num'] == idx: | |
2907 | logger.info("Test: EAP-Failure") | |
2908 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2909 | ||
2910 | idx += 1 | |
2911 | if ctx['num'] == idx: | |
2912 | logger.info("Test: Too short attribute header") | |
2913 | return struct.pack(">BBHBBHB", EAP_CODE_REQUEST, ctx['id'], | |
2914 | 4 + 1 + 1 + 3, | |
2915 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255) | |
2916 | idx += 1 | |
2917 | if ctx['num'] == idx: | |
2918 | logger.info("Test: EAP-Failure") | |
2919 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2920 | ||
2921 | idx += 1 | |
2922 | if ctx['num'] == idx: | |
2923 | logger.info("Test: Truncated attribute") | |
2924 | return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'], | |
2925 | 4 + 1 + 1 + 4, | |
2926 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255, | |
2927 | 255) | |
2928 | idx += 1 | |
2929 | if ctx['num'] == idx: | |
2930 | logger.info("Test: EAP-Failure") | |
2931 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2932 | ||
2933 | idx += 1 | |
2934 | if ctx['num'] == idx: | |
2935 | logger.info("Test: Too short attribute data") | |
2936 | return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'], | |
2937 | 4 + 1 + 1 + 4, | |
2938 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255, | |
2939 | 0) | |
2940 | idx += 1 | |
2941 | if ctx['num'] == idx: | |
2942 | logger.info("Test: EAP-Failure") | |
2943 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2944 | ||
2945 | idx += 1 | |
2946 | if ctx['num'] == idx: | |
2947 | logger.info("Test: Skippable/non-skippable unrecognzized attribute") | |
2948 | return struct.pack(">BBHBBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
2949 | 4 + 1 + 1 + 10, | |
2950 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
2951 | 255, 1, 0, 127, 1, 0) | |
2952 | idx += 1 | |
2953 | if ctx['num'] == idx: | |
2954 | logger.info("Test: EAP-Failure") | |
2955 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2956 | ||
2957 | idx += 1 | |
2958 | if ctx['num'] == idx: | |
2959 | logger.info("Test: Identity request without ID type") | |
2960 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
2961 | 4 + 1 + 3, | |
2962 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0) | |
2963 | idx += 1 | |
2964 | if ctx['num'] == idx: | |
2965 | logger.info("Test: Identity request ANY_ID") | |
2966 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
2967 | 4 + 1 + 3 + 4, | |
2968 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
2969 | EAP_SIM_AT_ANY_ID_REQ, 1, 0) | |
2970 | idx += 1 | |
2971 | if ctx['num'] == idx: | |
2972 | logger.info("Test: Identity request ANY_ID (duplicate)") | |
2973 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
2974 | 4 + 1 + 3 + 4, | |
2975 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
2976 | EAP_SIM_AT_ANY_ID_REQ, 1, 0) | |
2977 | idx += 1 | |
2978 | if ctx['num'] == idx: | |
2979 | logger.info("Test: EAP-Failure") | |
2980 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
2981 | ||
2982 | idx += 1 | |
2983 | if ctx['num'] == idx: | |
2984 | logger.info("Test: Identity request ANY_ID") | |
2985 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
2986 | 4 + 1 + 3 + 4, | |
2987 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
2988 | EAP_SIM_AT_ANY_ID_REQ, 1, 0) | |
2989 | idx += 1 | |
2990 | if ctx['num'] == idx: | |
2991 | logger.info("Test: Identity request FULLAUTH_ID") | |
2992 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
2993 | 4 + 1 + 3 + 4, | |
2994 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
2995 | EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) | |
2996 | idx += 1 | |
2997 | if ctx['num'] == idx: | |
2998 | logger.info("Test: Identity request FULLAUTH_ID (duplicate)") | |
2999 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3000 | 4 + 1 + 3 + 4, | |
3001 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3002 | EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) | |
3003 | idx += 1 | |
3004 | if ctx['num'] == idx: | |
3005 | logger.info("Test: EAP-Failure") | |
3006 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3007 | ||
3008 | idx += 1 | |
3009 | if ctx['num'] == idx: | |
3010 | logger.info("Test: Identity request ANY_ID") | |
3011 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3012 | 4 + 1 + 3 + 4, | |
3013 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3014 | EAP_SIM_AT_ANY_ID_REQ, 1, 0) | |
3015 | idx += 1 | |
3016 | if ctx['num'] == idx: | |
3017 | logger.info("Test: Identity request FULLAUTH_ID") | |
3018 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3019 | 4 + 1 + 3 + 4, | |
3020 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3021 | EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) | |
3022 | idx += 1 | |
3023 | if ctx['num'] == idx: | |
3024 | logger.info("Test: Identity request PERMANENT_ID") | |
3025 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3026 | 4 + 1 + 3 + 4, | |
3027 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3028 | EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) | |
3029 | idx += 1 | |
3030 | if ctx['num'] == idx: | |
3031 | logger.info("Test: Identity request PERMANENT_ID (duplicate)") | |
3032 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3033 | 4 + 1 + 3 + 4, | |
3034 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3035 | EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) | |
3036 | idx += 1 | |
3037 | if ctx['num'] == idx: | |
3038 | logger.info("Test: EAP-Failure") | |
3039 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3040 | ||
3041 | idx += 1 | |
3042 | if ctx['num'] == idx: | |
3043 | logger.info("Test: Challenge with no attributes") | |
3044 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3045 | 4 + 1 + 3, | |
3046 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0) | |
3047 | idx += 1 | |
3048 | if ctx['num'] == idx: | |
3049 | logger.info("Test: EAP-Failure") | |
3050 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3051 | ||
3052 | idx += 1 | |
3053 | if ctx['num'] == idx: | |
3054 | logger.info("Test: AKA Challenge with BIDDING") | |
3055 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3056 | 4 + 1 + 3 + 4, | |
3057 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3058 | EAP_SIM_AT_BIDDING, 1, 0x8000) | |
3059 | idx += 1 | |
3060 | if ctx['num'] == idx: | |
3061 | logger.info("Test: EAP-Failure") | |
3062 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3063 | ||
3064 | idx += 1 | |
3065 | if ctx['num'] == idx: | |
3066 | logger.info("Test: Notification with no attributes") | |
3067 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3068 | 4 + 1 + 3, | |
3069 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0) | |
3070 | idx += 1 | |
3071 | if ctx['num'] == idx: | |
3072 | logger.info("Test: EAP-Failure") | |
3073 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3074 | ||
3075 | idx += 1 | |
3076 | if ctx['num'] == idx: | |
3077 | logger.info("Test: Notification indicating success, but no MAC") | |
3078 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3079 | 4 + 1 + 3 + 4, | |
3080 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, | |
3081 | EAP_SIM_AT_NOTIFICATION, 1, 32768) | |
3082 | idx += 1 | |
3083 | if ctx['num'] == idx: | |
3084 | logger.info("Test: EAP-Failure") | |
3085 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3086 | ||
3087 | idx += 1 | |
3088 | if ctx['num'] == idx: | |
3089 | logger.info("Test: Notification indicating success, but invalid MAC value") | |
3090 | return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'], | |
3091 | 4 + 1 + 3 + 4 + 20, | |
3092 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, | |
3093 | EAP_SIM_AT_NOTIFICATION, 1, 32768, | |
3094 | EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) | |
3095 | idx += 1 | |
3096 | if ctx['num'] == idx: | |
3097 | logger.info("Test: EAP-Failure") | |
3098 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3099 | ||
3100 | idx += 1 | |
3101 | if ctx['num'] == idx: | |
3102 | logger.info("Test: Notification indicating success with zero-key MAC") | |
3103 | return struct.pack(">BBHBBHBBHBBH16B", EAP_CODE_REQUEST, | |
3104 | ctx['id'] - 2, | |
3105 | 4 + 1 + 3 + 4 + 20, | |
3106 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, | |
3107 | EAP_SIM_AT_NOTIFICATION, 1, 32768, | |
3108 | EAP_SIM_AT_MAC, 5, 0, | |
3109 | 0xbe, 0x2e, 0xbb, 0xa9, 0xfa, 0x2e, 0x82, 0x36, | |
3110 | 0x37, 0x8c, 0x32, 0x41, 0xb7, 0xc7, 0x58, 0xa3) | |
3111 | idx += 1 | |
3112 | if ctx['num'] == idx: | |
3113 | logger.info("Test: EAP-Success") | |
3114 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) | |
3115 | ||
3116 | idx += 1 | |
3117 | if ctx['num'] == idx: | |
3118 | logger.info("Test: Notification before auth") | |
3119 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3120 | 4 + 1 + 3 + 4, | |
3121 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, | |
3122 | EAP_SIM_AT_NOTIFICATION, 1, 16384) | |
3123 | idx += 1 | |
3124 | if ctx['num'] == idx: | |
3125 | logger.info("Test: EAP-Failure") | |
3126 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3127 | ||
3128 | idx += 1 | |
3129 | if ctx['num'] == idx: | |
3130 | logger.info("Test: Notification before auth") | |
3131 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3132 | 4 + 1 + 3 + 4, | |
3133 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, | |
3134 | EAP_SIM_AT_NOTIFICATION, 1, 16385) | |
3135 | idx += 1 | |
3136 | if ctx['num'] == idx: | |
3137 | logger.info("Test: EAP-Failure") | |
3138 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3139 | ||
3140 | idx += 1 | |
3141 | if ctx['num'] == idx: | |
3142 | logger.info("Test: Notification with unrecognized non-failure") | |
3143 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3144 | 4 + 1 + 3 + 4, | |
3145 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, | |
3146 | EAP_SIM_AT_NOTIFICATION, 1, 0xc000) | |
3147 | idx += 1 | |
3148 | if ctx['num'] == idx: | |
3149 | logger.info("Test: Notification before auth (duplicate)") | |
3150 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3151 | 4 + 1 + 3 + 4, | |
3152 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, | |
3153 | EAP_SIM_AT_NOTIFICATION, 1, 0xc000) | |
3154 | idx += 1 | |
3155 | if ctx['num'] == idx: | |
3156 | logger.info("Test: EAP-Failure") | |
3157 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3158 | ||
3159 | idx += 1 | |
3160 | if ctx['num'] == idx: | |
3161 | logger.info("Test: Re-authentication (unexpected) with no attributes") | |
3162 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3163 | 4 + 1 + 3, | |
3164 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION, | |
3165 | 0) | |
3166 | idx += 1 | |
3167 | if ctx['num'] == idx: | |
3168 | logger.info("Test: EAP-Failure") | |
3169 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3170 | ||
3171 | idx += 1 | |
3172 | if ctx['num'] == idx: | |
3173 | logger.info("Test: AKA Challenge with Checkcode claiming identity round was used") | |
3174 | return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], | |
3175 | 4 + 1 + 3 + 24, | |
3176 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3177 | EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0) | |
3178 | idx += 1 | |
3179 | if ctx['num'] == idx: | |
3180 | logger.info("Test: EAP-Failure") | |
3181 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3182 | ||
3183 | idx += 1 | |
3184 | if ctx['num'] == idx: | |
3185 | logger.info("Test: Identity request ANY_ID") | |
3186 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3187 | 4 + 1 + 3 + 4, | |
3188 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3189 | EAP_SIM_AT_ANY_ID_REQ, 1, 0) | |
3190 | idx += 1 | |
3191 | if ctx['num'] == idx: | |
3192 | logger.info("Test: AKA Challenge with Checkcode claiming no identity round was used") | |
3193 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3194 | 4 + 1 + 3 + 4, | |
3195 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3196 | EAP_SIM_AT_CHECKCODE, 1, 0) | |
3197 | idx += 1 | |
3198 | if ctx['num'] == idx: | |
3199 | logger.info("Test: EAP-Failure") | |
3200 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3201 | ||
3202 | idx += 1 | |
3203 | if ctx['num'] == idx: | |
3204 | logger.info("Test: Identity request ANY_ID") | |
3205 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3206 | 4 + 1 + 3 + 4, | |
3207 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3208 | EAP_SIM_AT_ANY_ID_REQ, 1, 0) | |
3209 | idx += 1 | |
3210 | if ctx['num'] == idx: | |
3211 | logger.info("Test: AKA Challenge with mismatching Checkcode value") | |
3212 | return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], | |
3213 | 4 + 1 + 3 + 24, | |
3214 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3215 | EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0) | |
3216 | idx += 1 | |
3217 | if ctx['num'] == idx: | |
3218 | logger.info("Test: EAP-Failure") | |
3219 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3220 | ||
3221 | idx += 1 | |
3222 | if ctx['num'] == idx: | |
3223 | logger.info("Test: Re-authentication (unexpected) with Checkcode claimin identity round was used") | |
3224 | return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], | |
3225 | 4 + 1 + 3 + 24, | |
3226 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION, | |
3227 | 0, | |
3228 | EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0) | |
3229 | idx += 1 | |
3230 | if ctx['num'] == idx: | |
3231 | logger.info("Test: EAP-Failure") | |
3232 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3233 | ||
3234 | idx += 1 | |
3235 | if ctx['num'] == idx: | |
3236 | logger.info("Test: Invalid AT_RAND length") | |
3237 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3238 | 4 + 1 + 3 + 4, | |
3239 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3240 | EAP_SIM_AT_RAND, 1, 0) | |
3241 | idx += 1 | |
3242 | if ctx['num'] == idx: | |
3243 | logger.info("Test: EAP-Failure") | |
3244 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3245 | ||
3246 | idx += 1 | |
3247 | if ctx['num'] == idx: | |
3248 | logger.info("Test: Invalid AT_AUTN length") | |
3249 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3250 | 4 + 1 + 3 + 4, | |
3251 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3252 | EAP_SIM_AT_AUTN, 1, 0) | |
3253 | idx += 1 | |
3254 | if ctx['num'] == idx: | |
3255 | logger.info("Test: EAP-Failure") | |
3256 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3257 | ||
3258 | idx += 1 | |
3259 | if ctx['num'] == idx: | |
3260 | logger.info("Test: Unencrypted AT_PADDING") | |
3261 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3262 | 4 + 1 + 3 + 4, | |
3263 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3264 | EAP_SIM_AT_PADDING, 1, 0) | |
3265 | idx += 1 | |
3266 | if ctx['num'] == idx: | |
3267 | logger.info("Test: EAP-Failure") | |
3268 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3269 | ||
3270 | idx += 1 | |
3271 | if ctx['num'] == idx: | |
3272 | logger.info("Test: Invalid AT_NONCE_MT length") | |
3273 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3274 | 4 + 1 + 3 + 4, | |
3275 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3276 | EAP_SIM_AT_NONCE_MT, 1, 0) | |
3277 | idx += 1 | |
3278 | if ctx['num'] == idx: | |
3279 | logger.info("Test: EAP-Failure") | |
3280 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3281 | ||
3282 | idx += 1 | |
3283 | if ctx['num'] == idx: | |
3284 | logger.info("Test: Invalid AT_MAC length") | |
3285 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3286 | 4 + 1 + 3 + 4, | |
3287 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3288 | EAP_SIM_AT_MAC, 1, 0) | |
3289 | idx += 1 | |
3290 | if ctx['num'] == idx: | |
3291 | logger.info("Test: EAP-Failure") | |
3292 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3293 | ||
3294 | idx += 1 | |
3295 | if ctx['num'] == idx: | |
3296 | logger.info("Test: Invalid AT_NOTIFICATION length") | |
3297 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3298 | 4 + 1 + 3 + 8, | |
3299 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3300 | EAP_SIM_AT_NOTIFICATION, 2, 0, 0) | |
3301 | idx += 1 | |
3302 | if ctx['num'] == idx: | |
3303 | logger.info("Test: EAP-Failure") | |
3304 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3305 | ||
3306 | idx += 1 | |
3307 | if ctx['num'] == idx: | |
3308 | logger.info("Test: AT_IDENTITY overflow") | |
3309 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3310 | 4 + 1 + 3 + 4, | |
3311 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3312 | EAP_SIM_AT_IDENTITY, 1, 0xffff) | |
3313 | idx += 1 | |
3314 | if ctx['num'] == idx: | |
3315 | logger.info("Test: EAP-Failure") | |
3316 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3317 | ||
3318 | idx += 1 | |
3319 | if ctx['num'] == idx: | |
3320 | logger.info("Test: Unexpected AT_VERSION_LIST") | |
3321 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3322 | 4 + 1 + 3 + 4, | |
3323 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3324 | EAP_SIM_AT_VERSION_LIST, 1, 0) | |
3325 | idx += 1 | |
3326 | if ctx['num'] == idx: | |
3327 | logger.info("Test: EAP-Failure") | |
3328 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3329 | ||
3330 | idx += 1 | |
3331 | if ctx['num'] == idx: | |
3332 | logger.info("Test: Invalid AT_SELECTED_VERSION length") | |
3333 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3334 | 4 + 1 + 3 + 8, | |
3335 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3336 | EAP_SIM_AT_SELECTED_VERSION, 2, 0, 0) | |
3337 | idx += 1 | |
3338 | if ctx['num'] == idx: | |
3339 | logger.info("Test: EAP-Failure") | |
3340 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3341 | ||
3342 | idx += 1 | |
3343 | if ctx['num'] == idx: | |
3344 | logger.info("Test: Unencrypted AT_COUNTER") | |
3345 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3346 | 4 + 1 + 3 + 4, | |
3347 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3348 | EAP_SIM_AT_COUNTER, 1, 0) | |
3349 | idx += 1 | |
3350 | if ctx['num'] == idx: | |
3351 | logger.info("Test: EAP-Failure") | |
3352 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3353 | ||
3354 | idx += 1 | |
3355 | if ctx['num'] == idx: | |
3356 | logger.info("Test: Unencrypted AT_COUNTER_TOO_SMALL") | |
3357 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3358 | 4 + 1 + 3 + 4, | |
3359 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3360 | EAP_SIM_AT_COUNTER_TOO_SMALL, 1, 0) | |
3361 | idx += 1 | |
3362 | if ctx['num'] == idx: | |
3363 | logger.info("Test: EAP-Failure") | |
3364 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3365 | ||
3366 | idx += 1 | |
3367 | if ctx['num'] == idx: | |
3368 | logger.info("Test: Unencrypted AT_NONCE_S") | |
3369 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3370 | 4 + 1 + 3 + 4, | |
3371 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3372 | EAP_SIM_AT_NONCE_S, 1, 0) | |
3373 | idx += 1 | |
3374 | if ctx['num'] == idx: | |
3375 | logger.info("Test: EAP-Failure") | |
3376 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3377 | ||
3378 | idx += 1 | |
3379 | if ctx['num'] == idx: | |
3380 | logger.info("Test: Invalid AT_CLIENT_ERROR_CODE length") | |
3381 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3382 | 4 + 1 + 3 + 8, | |
3383 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3384 | EAP_SIM_AT_CLIENT_ERROR_CODE, 2, 0, 0) | |
3385 | idx += 1 | |
3386 | if ctx['num'] == idx: | |
3387 | logger.info("Test: EAP-Failure") | |
3388 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3389 | ||
3390 | idx += 1 | |
3391 | if ctx['num'] == idx: | |
3392 | logger.info("Test: Invalid AT_IV length") | |
3393 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3394 | 4 + 1 + 3 + 4, | |
3395 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3396 | EAP_SIM_AT_IV, 1, 0) | |
3397 | idx += 1 | |
3398 | if ctx['num'] == idx: | |
3399 | logger.info("Test: EAP-Failure") | |
3400 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3401 | ||
3402 | idx += 1 | |
3403 | if ctx['num'] == idx: | |
3404 | logger.info("Test: Invalid AT_ENCR_DATA length") | |
3405 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3406 | 4 + 1 + 3 + 8, | |
3407 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3408 | EAP_SIM_AT_ENCR_DATA, 2, 0, 0) | |
3409 | idx += 1 | |
3410 | if ctx['num'] == idx: | |
3411 | logger.info("Test: EAP-Failure") | |
3412 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3413 | ||
3414 | idx += 1 | |
3415 | if ctx['num'] == idx: | |
3416 | logger.info("Test: Unencrypted AT_NEXT_PSEUDONYM") | |
3417 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3418 | 4 + 1 + 3 + 4, | |
3419 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3420 | EAP_SIM_AT_NEXT_PSEUDONYM, 1, 0) | |
3421 | idx += 1 | |
3422 | if ctx['num'] == idx: | |
3423 | logger.info("Test: EAP-Failure") | |
3424 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3425 | ||
3426 | idx += 1 | |
3427 | if ctx['num'] == idx: | |
3428 | logger.info("Test: Unencrypted AT_NEXT_REAUTH_ID") | |
3429 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3430 | 4 + 1 + 3 + 4, | |
3431 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3432 | EAP_SIM_AT_NEXT_REAUTH_ID, 1, 0) | |
3433 | idx += 1 | |
3434 | if ctx['num'] == idx: | |
3435 | logger.info("Test: EAP-Failure") | |
3436 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3437 | ||
3438 | idx += 1 | |
3439 | if ctx['num'] == idx: | |
3440 | logger.info("Test: Invalid AT_RES length") | |
3441 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3442 | 4 + 1 + 3 + 4, | |
3443 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3444 | EAP_SIM_AT_RES, 1, 0) | |
3445 | idx += 1 | |
3446 | if ctx['num'] == idx: | |
3447 | logger.info("Test: EAP-Failure") | |
3448 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3449 | ||
3450 | idx += 1 | |
3451 | if ctx['num'] == idx: | |
3452 | logger.info("Test: Invalid AT_RES length") | |
3453 | return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], | |
3454 | 4 + 1 + 3 + 24, | |
3455 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3456 | EAP_SIM_AT_RES, 6, 0xffff, 0, 0, 0, 0, 0) | |
3457 | idx += 1 | |
3458 | if ctx['num'] == idx: | |
3459 | logger.info("Test: EAP-Failure") | |
3460 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3461 | ||
3462 | idx += 1 | |
3463 | if ctx['num'] == idx: | |
3464 | logger.info("Test: Invalid AT_AUTS length") | |
3465 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3466 | 4 + 1 + 3 + 8, | |
3467 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3468 | EAP_SIM_AT_AUTS, 2, 0, 0) | |
3469 | idx += 1 | |
3470 | if ctx['num'] == idx: | |
3471 | logger.info("Test: EAP-Failure") | |
3472 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3473 | ||
3474 | idx += 1 | |
3475 | if ctx['num'] == idx: | |
3476 | logger.info("Test: Invalid AT_CHECKCODE length") | |
3477 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3478 | 4 + 1 + 3 + 8, | |
3479 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3480 | EAP_SIM_AT_CHECKCODE, 2, 0, 0) | |
3481 | idx += 1 | |
3482 | if ctx['num'] == idx: | |
3483 | logger.info("Test: EAP-Failure") | |
3484 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3485 | ||
3486 | idx += 1 | |
3487 | if ctx['num'] == idx: | |
3488 | logger.info("Test: Invalid AT_RESULT_IND length") | |
3489 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3490 | 4 + 1 + 3 + 8, | |
3491 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3492 | EAP_SIM_AT_RESULT_IND, 2, 0, 0) | |
3493 | idx += 1 | |
3494 | if ctx['num'] == idx: | |
3495 | logger.info("Test: EAP-Failure") | |
3496 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3497 | ||
3498 | idx += 1 | |
3499 | if ctx['num'] == idx: | |
3500 | logger.info("Test: Unexpected AT_KDF_INPUT") | |
3501 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3502 | 4 + 1 + 3 + 8, | |
3503 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3504 | EAP_SIM_AT_KDF_INPUT, 2, 0, 0) | |
3505 | idx += 1 | |
3506 | if ctx['num'] == idx: | |
3507 | logger.info("Test: EAP-Failure") | |
3508 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3509 | ||
3510 | idx += 1 | |
3511 | if ctx['num'] == idx: | |
3512 | logger.info("Test: Unexpected AT_KDF") | |
3513 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3514 | 4 + 1 + 3 + 8, | |
3515 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3516 | EAP_SIM_AT_KDF, 2, 0, 0) | |
3517 | idx += 1 | |
3518 | if ctx['num'] == idx: | |
3519 | logger.info("Test: EAP-Failure") | |
3520 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3521 | ||
3522 | idx += 1 | |
3523 | if ctx['num'] == idx: | |
3524 | logger.info("Test: Invalid AT_BIDDING length") | |
3525 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3526 | 4 + 1 + 3 + 8, | |
3527 | EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3528 | EAP_SIM_AT_BIDDING, 2, 0, 0) | |
3529 | idx += 1 | |
3530 | if ctx['num'] == idx: | |
3531 | logger.info("Test: EAP-Failure") | |
3532 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3533 | ||
3534 | return None | |
3535 | ||
3536 | srv = start_radius_server(aka_handler) | |
6c080dfa JM |
3537 | |
3538 | try: | |
3539 | hapd = start_ap(apdev[0]['ifname']) | |
3540 | ||
3541 | for i in range(0, 49): | |
3542 | eap = "AKA AKA'" if i == 11 else "AKA" | |
3543 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
3544 | eap=eap, identity="0232010000000000", | |
3545 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123", | |
3546 | wait_connect=False) | |
3547 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
3548 | timeout=15) | |
3549 | if ev is None: | |
3550 | raise Exception("Timeout on EAP start") | |
3551 | if i in [ 0, 15 ]: | |
3552 | time.sleep(0.1) | |
3553 | else: | |
3554 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], | |
3555 | timeout=10) | |
3556 | if ev is None: | |
3557 | raise Exception("Timeout on EAP failure") | |
3558 | dev[0].request("REMOVE_NETWORK all") | |
f0174bff | 3559 | dev[0].dump_monitor() |
6c080dfa JM |
3560 | finally: |
3561 | stop_radius_server(srv) | |
3562 | ||
3563 | def test_eap_proto_aka_prime(dev, apdev): | |
3564 | """EAP-AKA' protocol tests""" | |
3565 | def aka_prime_handler(ctx, req): | |
3566 | logger.info("aka_prime_handler - RX " + req.encode("hex")) | |
3567 | if 'num' not in ctx: | |
3568 | ctx['num'] = 0 | |
3569 | ctx['num'] = ctx['num'] + 1 | |
3570 | if 'id' not in ctx: | |
3571 | ctx['id'] = 1 | |
3572 | ctx['id'] = (ctx['id'] + 1) % 256 | |
3573 | ||
3574 | idx = 0 | |
3575 | ||
3576 | idx += 1 | |
3577 | if ctx['num'] == idx: | |
3578 | logger.info("Test: Missing payload") | |
3579 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
3580 | 4 + 1, | |
3581 | EAP_TYPE_AKA_PRIME) | |
3582 | ||
3583 | idx += 1 | |
3584 | if ctx['num'] == idx: | |
3585 | logger.info("Test: Challenge with no attributes") | |
3586 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3587 | 4 + 1 + 3, | |
3588 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0) | |
3589 | idx += 1 | |
3590 | if ctx['num'] == idx: | |
3591 | logger.info("Test: EAP-Failure") | |
3592 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3593 | ||
3594 | idx += 1 | |
3595 | if ctx['num'] == idx: | |
3596 | logger.info("Test: Challenge with empty AT_KDF_INPUT") | |
3597 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3598 | 4 + 1 + 3 + 4, | |
3599 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3600 | EAP_SIM_AT_KDF_INPUT, 1, 0) | |
3601 | idx += 1 | |
3602 | if ctx['num'] == idx: | |
3603 | logger.info("Test: EAP-Failure") | |
3604 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3605 | ||
3606 | idx += 1 | |
3607 | if ctx['num'] == idx: | |
3608 | logger.info("Test: Challenge with AT_KDF_INPUT") | |
3609 | return struct.pack(">BBHBBHBBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
3610 | 4 + 1 + 3 + 8, | |
3611 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3612 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3613 | ord('c'), ord('d')) | |
3614 | idx += 1 | |
3615 | if ctx['num'] == idx: | |
3616 | logger.info("Test: EAP-Failure") | |
3617 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3618 | ||
3619 | idx += 1 | |
3620 | if ctx['num'] == idx: | |
3621 | logger.info("Test: Challenge with duplicated KDF") | |
3622 | return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", | |
3623 | EAP_CODE_REQUEST, ctx['id'], | |
3624 | 4 + 1 + 3 + 8 + 3 * 4, | |
3625 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3626 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3627 | ord('c'), ord('d'), | |
3628 | EAP_SIM_AT_KDF, 1, 1, | |
3629 | EAP_SIM_AT_KDF, 1, 2, | |
3630 | EAP_SIM_AT_KDF, 1, 1) | |
3631 | idx += 1 | |
3632 | if ctx['num'] == idx: | |
3633 | logger.info("Test: EAP-Failure") | |
3634 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3635 | ||
3636 | idx += 1 | |
3637 | if ctx['num'] == idx: | |
3638 | logger.info("Test: Challenge with multiple KDF proposals") | |
3639 | return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", | |
3640 | EAP_CODE_REQUEST, ctx['id'], | |
3641 | 4 + 1 + 3 + 8 + 3 * 4, | |
3642 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3643 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3644 | ord('c'), ord('d'), | |
3645 | EAP_SIM_AT_KDF, 1, 255, | |
3646 | EAP_SIM_AT_KDF, 1, 254, | |
3647 | EAP_SIM_AT_KDF, 1, 1) | |
3648 | idx += 1 | |
3649 | if ctx['num'] == idx: | |
3650 | logger.info("Test: Challenge with incorrect KDF selected") | |
3651 | return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH", | |
3652 | EAP_CODE_REQUEST, ctx['id'], | |
3653 | 4 + 1 + 3 + 8 + 4 * 4, | |
3654 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3655 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3656 | ord('c'), ord('d'), | |
3657 | EAP_SIM_AT_KDF, 1, 255, | |
3658 | EAP_SIM_AT_KDF, 1, 255, | |
3659 | EAP_SIM_AT_KDF, 1, 254, | |
3660 | EAP_SIM_AT_KDF, 1, 1) | |
3661 | idx += 1 | |
3662 | if ctx['num'] == idx: | |
3663 | logger.info("Test: EAP-Failure") | |
3664 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3665 | ||
3666 | idx += 1 | |
3667 | if ctx['num'] == idx: | |
3668 | logger.info("Test: Challenge with multiple KDF proposals") | |
3669 | return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", | |
3670 | EAP_CODE_REQUEST, ctx['id'], | |
3671 | 4 + 1 + 3 + 8 + 3 * 4, | |
3672 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3673 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3674 | ord('c'), ord('d'), | |
3675 | EAP_SIM_AT_KDF, 1, 255, | |
3676 | EAP_SIM_AT_KDF, 1, 254, | |
3677 | EAP_SIM_AT_KDF, 1, 1) | |
3678 | idx += 1 | |
3679 | if ctx['num'] == idx: | |
3680 | logger.info("Test: Challenge with selected KDF not duplicated") | |
3681 | return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", | |
3682 | EAP_CODE_REQUEST, ctx['id'], | |
3683 | 4 + 1 + 3 + 8 + 3 * 4, | |
3684 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3685 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3686 | ord('c'), ord('d'), | |
3687 | EAP_SIM_AT_KDF, 1, 1, | |
3688 | EAP_SIM_AT_KDF, 1, 255, | |
3689 | EAP_SIM_AT_KDF, 1, 254) | |
3690 | idx += 1 | |
3691 | if ctx['num'] == idx: | |
3692 | logger.info("Test: EAP-Failure") | |
3693 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3694 | ||
3695 | idx += 1 | |
3696 | if ctx['num'] == idx: | |
3697 | logger.info("Test: Challenge with multiple KDF proposals") | |
3698 | return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", | |
3699 | EAP_CODE_REQUEST, ctx['id'], | |
3700 | 4 + 1 + 3 + 8 + 3 * 4, | |
3701 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3702 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3703 | ord('c'), ord('d'), | |
3704 | EAP_SIM_AT_KDF, 1, 255, | |
3705 | EAP_SIM_AT_KDF, 1, 254, | |
3706 | EAP_SIM_AT_KDF, 1, 1) | |
3707 | idx += 1 | |
3708 | if ctx['num'] == idx: | |
3709 | logger.info("Test: Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)") | |
3710 | return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH", | |
3711 | EAP_CODE_REQUEST, ctx['id'], | |
3712 | 4 + 1 + 3 + 8 + 4 * 4, | |
3713 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3714 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3715 | ord('c'), ord('d'), | |
3716 | EAP_SIM_AT_KDF, 1, 1, | |
3717 | EAP_SIM_AT_KDF, 1, 255, | |
3718 | EAP_SIM_AT_KDF, 1, 254, | |
3719 | EAP_SIM_AT_KDF, 1, 1) | |
3720 | idx += 1 | |
3721 | if ctx['num'] == idx: | |
3722 | logger.info("Test: EAP-Failure") | |
3723 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3724 | ||
3725 | idx += 1 | |
3726 | if ctx['num'] == idx: | |
3727 | logger.info("Test: Challenge with multiple unsupported KDF proposals") | |
3728 | return struct.pack(">BBHBBHBBHBBBBBBHBBH", | |
3729 | EAP_CODE_REQUEST, ctx['id'], | |
3730 | 4 + 1 + 3 + 8 + 2 * 4, | |
3731 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3732 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3733 | ord('c'), ord('d'), | |
3734 | EAP_SIM_AT_KDF, 1, 255, | |
3735 | EAP_SIM_AT_KDF, 1, 254) | |
3736 | idx += 1 | |
3737 | if ctx['num'] == idx: | |
3738 | logger.info("Test: EAP-Failure") | |
3739 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3740 | ||
3741 | idx += 1 | |
3742 | if ctx['num'] == idx: | |
3743 | logger.info("Test: Challenge with multiple KDF proposals") | |
3744 | return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", | |
3745 | EAP_CODE_REQUEST, ctx['id'], | |
3746 | 4 + 1 + 3 + 8 + 3 * 4, | |
3747 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3748 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3749 | ord('c'), ord('d'), | |
3750 | EAP_SIM_AT_KDF, 1, 255, | |
3751 | EAP_SIM_AT_KDF, 1, 254, | |
3752 | EAP_SIM_AT_KDF, 1, 1) | |
3753 | idx += 1 | |
3754 | if ctx['num'] == idx: | |
3755 | logger.info("Test: Challenge with invalid MAC, RAND, AUTN values)") | |
3756 | return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBHBBH4LBBH4LBBH4L", | |
3757 | EAP_CODE_REQUEST, ctx['id'], | |
3758 | 4 + 1 + 3 + 8 + 4 * 4 + 20 + 20 + 20, | |
3759 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3760 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3761 | ord('c'), ord('d'), | |
3762 | EAP_SIM_AT_KDF, 1, 1, | |
3763 | EAP_SIM_AT_KDF, 1, 255, | |
3764 | EAP_SIM_AT_KDF, 1, 254, | |
3765 | EAP_SIM_AT_KDF, 1, 1, | |
3766 | EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0, | |
3767 | EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0, | |
3768 | EAP_SIM_AT_AUTN, 5, 0, 0, 0, 0, 0) | |
3769 | idx += 1 | |
3770 | if ctx['num'] == idx: | |
3771 | logger.info("Test: EAP-Failure") | |
3772 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3773 | ||
3774 | idx += 1 | |
3775 | if ctx['num'] == idx: | |
3776 | logger.info("Test: Challenge - AMF separation bit not set)") | |
3777 | return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L", | |
3778 | EAP_CODE_REQUEST, ctx['id'], | |
3779 | 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20, | |
3780 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3781 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3782 | ord('c'), ord('d'), | |
3783 | EAP_SIM_AT_KDF, 1, 1, | |
3784 | EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4, | |
3785 | EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8, | |
3786 | EAP_SIM_AT_AUTN, 5, 0, 9, 10, | |
3787 | 0x2fda8ef7, 0xbba518cc) | |
3788 | idx += 1 | |
3789 | if ctx['num'] == idx: | |
3790 | logger.info("Test: EAP-Failure") | |
3791 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3792 | ||
3793 | idx += 1 | |
3794 | if ctx['num'] == idx: | |
3795 | logger.info("Test: Challenge - Invalid MAC") | |
3796 | return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L", | |
3797 | EAP_CODE_REQUEST, ctx['id'], | |
3798 | 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20, | |
3799 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3800 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3801 | ord('c'), ord('d'), | |
3802 | EAP_SIM_AT_KDF, 1, 1, | |
3803 | EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4, | |
3804 | EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8, | |
3805 | EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff, | |
3806 | 0xd1f90322, 0x40514cb4) | |
3807 | idx += 1 | |
3808 | if ctx['num'] == idx: | |
3809 | logger.info("Test: EAP-Failure") | |
3810 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3811 | ||
3812 | idx += 1 | |
3813 | if ctx['num'] == idx: | |
3814 | logger.info("Test: Challenge - Valid MAC") | |
3815 | return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L", | |
3816 | EAP_CODE_REQUEST, ctx['id'], | |
3817 | 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20, | |
3818 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3819 | EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), | |
3820 | ord('c'), ord('d'), | |
3821 | EAP_SIM_AT_KDF, 1, 1, | |
3822 | EAP_SIM_AT_MAC, 5, 0, | |
3823 | 0xf4a3c1d3, 0x7c901401, 0x34bd8b01, 0x6f7fa32f, | |
3824 | EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8, | |
3825 | EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff, | |
3826 | 0xd1f90322, 0x40514cb4) | |
3827 | idx += 1 | |
3828 | if ctx['num'] == idx: | |
3829 | logger.info("Test: EAP-Failure") | |
3830 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3831 | ||
3832 | idx += 1 | |
3833 | if ctx['num'] == idx: | |
3834 | logger.info("Test: Invalid AT_KDF_INPUT length") | |
3835 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3836 | 4 + 1 + 3 + 8, | |
3837 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3838 | EAP_SIM_AT_KDF_INPUT, 2, 0xffff, 0) | |
3839 | idx += 1 | |
3840 | if ctx['num'] == idx: | |
3841 | logger.info("Test: EAP-Failure") | |
3842 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3843 | ||
3844 | idx += 1 | |
3845 | if ctx['num'] == idx: | |
3846 | logger.info("Test: Invalid AT_KDF length") | |
3847 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3848 | 4 + 1 + 3 + 8, | |
3849 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0, | |
3850 | EAP_SIM_AT_KDF, 2, 0, 0) | |
3851 | idx += 1 | |
3852 | if ctx['num'] == idx: | |
3853 | logger.info("Test: EAP-Failure") | |
3854 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3855 | ||
3856 | idx += 1 | |
3857 | if ctx['num'] == idx: | |
3858 | logger.info("Test: Challenge with large number of KDF proposals") | |
3859 | return struct.pack(">BBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH", | |
3860 | EAP_CODE_REQUEST, ctx['id'], | |
3861 | 4 + 1 + 3 + 12 * 4, | |
3862 | EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, | |
3863 | EAP_SIM_AT_KDF, 1, 255, | |
3864 | EAP_SIM_AT_KDF, 1, 254, | |
3865 | EAP_SIM_AT_KDF, 1, 253, | |
3866 | EAP_SIM_AT_KDF, 1, 252, | |
3867 | EAP_SIM_AT_KDF, 1, 251, | |
3868 | EAP_SIM_AT_KDF, 1, 250, | |
3869 | EAP_SIM_AT_KDF, 1, 249, | |
3870 | EAP_SIM_AT_KDF, 1, 248, | |
3871 | EAP_SIM_AT_KDF, 1, 247, | |
3872 | EAP_SIM_AT_KDF, 1, 246, | |
3873 | EAP_SIM_AT_KDF, 1, 245, | |
3874 | EAP_SIM_AT_KDF, 1, 244) | |
3875 | idx += 1 | |
3876 | if ctx['num'] == idx: | |
3877 | logger.info("Test: EAP-Failure") | |
3878 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3879 | ||
3880 | return None | |
3881 | ||
3882 | srv = start_radius_server(aka_prime_handler) | |
6c080dfa JM |
3883 | |
3884 | try: | |
3885 | hapd = start_ap(apdev[0]['ifname']) | |
3886 | ||
3887 | for i in range(0, 16): | |
3888 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
3889 | eap="AKA'", identity="6555444333222111", | |
3890 | password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123", | |
3891 | wait_connect=False) | |
3892 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
3893 | timeout=15) | |
3894 | if ev is None: | |
3895 | raise Exception("Timeout on EAP start") | |
3896 | if i in [ 0 ]: | |
3897 | time.sleep(0.1) | |
3898 | else: | |
3899 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], | |
3900 | timeout=10) | |
3901 | if ev is None: | |
3902 | raise Exception("Timeout on EAP failure") | |
3903 | dev[0].request("REMOVE_NETWORK all") | |
f0174bff | 3904 | dev[0].dump_monitor() |
6c080dfa JM |
3905 | finally: |
3906 | stop_radius_server(srv) | |
3907 | ||
3908 | def test_eap_proto_sim(dev, apdev): | |
3909 | """EAP-SIM protocol tests""" | |
3910 | def sim_handler(ctx, req): | |
3911 | logger.info("sim_handler - RX " + req.encode("hex")) | |
3912 | if 'num' not in ctx: | |
3913 | ctx['num'] = 0 | |
3914 | ctx['num'] = ctx['num'] + 1 | |
3915 | if 'id' not in ctx: | |
3916 | ctx['id'] = 1 | |
3917 | ctx['id'] = (ctx['id'] + 1) % 256 | |
3918 | ||
3919 | idx = 0 | |
3920 | ||
3921 | idx += 1 | |
3922 | if ctx['num'] == idx: | |
3923 | logger.info("Test: Missing payload") | |
3924 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
3925 | 4 + 1, | |
3926 | EAP_TYPE_SIM) | |
3927 | ||
3928 | idx += 1 | |
3929 | if ctx['num'] == idx: | |
3930 | logger.info("Test: Unexpected AT_AUTN") | |
3931 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3932 | 4 + 1 + 3 + 8, | |
3933 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
3934 | EAP_SIM_AT_AUTN, 2, 0, 0) | |
3935 | idx += 1 | |
3936 | if ctx['num'] == idx: | |
3937 | logger.info("Test: EAP-Failure") | |
3938 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3939 | ||
3940 | idx += 1 | |
3941 | if ctx['num'] == idx: | |
3942 | logger.info("Test: Too short AT_VERSION_LIST") | |
3943 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3944 | 4 + 1 + 3 + 4, | |
3945 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
3946 | EAP_SIM_AT_VERSION_LIST, 1, 0) | |
3947 | idx += 1 | |
3948 | if ctx['num'] == idx: | |
3949 | logger.info("Test: EAP-Failure") | |
3950 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3951 | ||
3952 | idx += 1 | |
3953 | if ctx['num'] == idx: | |
3954 | logger.info("Test: AT_VERSION_LIST overflow") | |
3955 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3956 | 4 + 1 + 3 + 4, | |
3957 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
3958 | EAP_SIM_AT_VERSION_LIST, 1, 0xffff) | |
3959 | idx += 1 | |
3960 | if ctx['num'] == idx: | |
3961 | logger.info("Test: EAP-Failure") | |
3962 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3963 | ||
3964 | idx += 1 | |
3965 | if ctx['num'] == idx: | |
3966 | logger.info("Test: Unexpected AT_AUTS") | |
3967 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3968 | 4 + 1 + 3 + 8, | |
3969 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
3970 | EAP_SIM_AT_AUTS, 2, 0, 0) | |
3971 | idx += 1 | |
3972 | if ctx['num'] == idx: | |
3973 | logger.info("Test: EAP-Failure") | |
3974 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3975 | ||
3976 | idx += 1 | |
3977 | if ctx['num'] == idx: | |
3978 | logger.info("Test: Unexpected AT_CHECKCODE") | |
3979 | return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], | |
3980 | 4 + 1 + 3 + 8, | |
3981 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
3982 | EAP_SIM_AT_CHECKCODE, 2, 0, 0) | |
3983 | idx += 1 | |
3984 | if ctx['num'] == idx: | |
3985 | logger.info("Test: EAP-Failure") | |
3986 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3987 | ||
3988 | idx += 1 | |
3989 | if ctx['num'] == idx: | |
3990 | logger.info("Test: No AT_VERSION_LIST in Start") | |
3991 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
3992 | 4 + 1 + 3, | |
3993 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0) | |
3994 | idx += 1 | |
3995 | if ctx['num'] == idx: | |
3996 | logger.info("Test: EAP-Failure") | |
3997 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
3998 | ||
3999 | idx += 1 | |
4000 | if ctx['num'] == idx: | |
4001 | logger.info("Test: No support version in AT_VERSION_LIST") | |
4002 | return struct.pack(">BBHBBHBBH4B", EAP_CODE_REQUEST, ctx['id'], | |
4003 | 4 + 1 + 3 + 8, | |
4004 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
4005 | EAP_SIM_AT_VERSION_LIST, 2, 3, 2, 3, 4, 5) | |
4006 | idx += 1 | |
4007 | if ctx['num'] == idx: | |
4008 | logger.info("Test: EAP-Failure") | |
4009 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4010 | ||
4011 | ||
4012 | idx += 1 | |
4013 | if ctx['num'] == idx: | |
4014 | logger.info("Test: Identity request without ID type") | |
4015 | return struct.pack(">BBHBBHBBH2H", EAP_CODE_REQUEST, ctx['id'], | |
4016 | 4 + 1 + 3 + 8, | |
4017 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
4018 | EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0) | |
4019 | idx += 1 | |
4020 | if ctx['num'] == idx: | |
4021 | logger.info("Test: Identity request ANY_ID") | |
4022 | return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], | |
4023 | 4 + 1 + 3 + 8 + 4, | |
4024 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
4025 | EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, | |
4026 | EAP_SIM_AT_ANY_ID_REQ, 1, 0) | |
4027 | idx += 1 | |
4028 | if ctx['num'] == idx: | |
4029 | logger.info("Test: Identity request ANY_ID (duplicate)") | |
4030 | return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], | |
4031 | 4 + 1 + 3 + 8 + 4, | |
4032 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
4033 | EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, | |
4034 | EAP_SIM_AT_ANY_ID_REQ, 1, 0) | |
4035 | idx += 1 | |
4036 | if ctx['num'] == idx: | |
4037 | logger.info("Test: EAP-Failure") | |
4038 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4039 | ||
4040 | idx += 1 | |
4041 | if ctx['num'] == idx: | |
4042 | logger.info("Test: Identity request ANY_ID") | |
4043 | return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], | |
4044 | 4 + 1 + 3 + 8 + 4, | |
4045 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
4046 | EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, | |
4047 | EAP_SIM_AT_ANY_ID_REQ, 1, 0) | |
4048 | idx += 1 | |
4049 | if ctx['num'] == idx: | |
4050 | logger.info("Test: Identity request FULLAUTH_ID") | |
4051 | return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], | |
4052 | 4 + 1 + 3 + 8 + 4, | |
4053 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
4054 | EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, | |
4055 | EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) | |
4056 | idx += 1 | |
4057 | if ctx['num'] == idx: | |
4058 | logger.info("Test: Identity request FULLAUTH_ID (duplicate)") | |
4059 | return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], | |
4060 | 4 + 1 + 3 + 8 + 4, | |
4061 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
4062 | EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, | |
4063 | EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) | |
4064 | idx += 1 | |
4065 | if ctx['num'] == idx: | |
4066 | logger.info("Test: EAP-Failure") | |
4067 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4068 | ||
4069 | idx += 1 | |
4070 | if ctx['num'] == idx: | |
4071 | logger.info("Test: Identity request ANY_ID") | |
4072 | return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], | |
4073 | 4 + 1 + 3 + 8 + 4, | |
4074 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
4075 | EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, | |
4076 | EAP_SIM_AT_ANY_ID_REQ, 1, 0) | |
4077 | idx += 1 | |
4078 | if ctx['num'] == idx: | |
4079 | logger.info("Test: Identity request FULLAUTH_ID") | |
4080 | return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], | |
4081 | 4 + 1 + 3 + 8 + 4, | |
4082 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
4083 | EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, | |
4084 | EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) | |
4085 | idx += 1 | |
4086 | if ctx['num'] == idx: | |
4087 | logger.info("Test: Identity request PERMANENT_ID") | |
4088 | return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], | |
4089 | 4 + 1 + 3 + 8 + 4, | |
4090 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
4091 | EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, | |
4092 | EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) | |
4093 | idx += 1 | |
4094 | if ctx['num'] == idx: | |
4095 | logger.info("Test: Identity request PERMANENT_ID (duplicate)") | |
4096 | return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], | |
4097 | 4 + 1 + 3 + 8 + 4, | |
4098 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, | |
4099 | EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, | |
4100 | EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) | |
4101 | idx += 1 | |
4102 | if ctx['num'] == idx: | |
4103 | logger.info("Test: EAP-Failure") | |
4104 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4105 | ||
4106 | idx += 1 | |
4107 | if ctx['num'] == idx: | |
4108 | logger.info("Test: No AT_MAC and AT_RAND in Challenge") | |
4109 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
4110 | 4 + 1 + 3, | |
4111 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0) | |
4112 | idx += 1 | |
4113 | if ctx['num'] == idx: | |
4114 | logger.info("Test: EAP-Failure") | |
4115 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4116 | ||
4117 | idx += 1 | |
4118 | if ctx['num'] == idx: | |
4119 | logger.info("Test: No AT_RAND in Challenge") | |
4120 | return struct.pack(">BBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'], | |
4121 | 4 + 1 + 3 + 20, | |
4122 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, | |
4123 | EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) | |
4124 | idx += 1 | |
4125 | if ctx['num'] == idx: | |
4126 | logger.info("Test: EAP-Failure") | |
4127 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4128 | ||
4129 | idx += 1 | |
4130 | if ctx['num'] == idx: | |
4131 | logger.info("Test: Insufficient number of challenges in Challenge") | |
4132 | return struct.pack(">BBHBBHBBH4LBBH4L", EAP_CODE_REQUEST, ctx['id'], | |
4133 | 4 + 1 + 3 + 20 + 20, | |
4134 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, | |
4135 | EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0, | |
4136 | EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) | |
4137 | idx += 1 | |
4138 | if ctx['num'] == idx: | |
4139 | logger.info("Test: EAP-Failure") | |
4140 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4141 | ||
4142 | idx += 1 | |
4143 | if ctx['num'] == idx: | |
4144 | logger.info("Test: Too many challenges in Challenge") | |
4145 | return struct.pack(">BBHBBHBBH4L4L4L4LBBH4L", EAP_CODE_REQUEST, | |
4146 | ctx['id'], | |
4147 | 4 + 1 + 3 + 4 + 4 * 16 + 20, | |
4148 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, | |
4149 | EAP_SIM_AT_RAND, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
4150 | 0, 0, 0, 0, 0, 0, 0, 0, | |
4151 | EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) | |
4152 | idx += 1 | |
4153 | if ctx['num'] == idx: | |
4154 | logger.info("Test: EAP-Failure") | |
4155 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4156 | ||
4157 | idx += 1 | |
4158 | if ctx['num'] == idx: | |
4159 | logger.info("Test: Same RAND multiple times in Challenge") | |
4160 | return struct.pack(">BBHBBHBBH4L4L4LBBH4L", EAP_CODE_REQUEST, | |
4161 | ctx['id'], | |
4162 | 4 + 1 + 3 + 4 + 3 * 16 + 20, | |
4163 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, | |
4164 | EAP_SIM_AT_RAND, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1, | |
4165 | 0, 0, 0, 0, | |
4166 | EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) | |
4167 | idx += 1 | |
4168 | if ctx['num'] == idx: | |
4169 | logger.info("Test: EAP-Failure") | |
4170 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4171 | ||
4172 | idx += 1 | |
4173 | if ctx['num'] == idx: | |
4174 | logger.info("Test: Notification with no attributes") | |
4175 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
4176 | 4 + 1 + 3, | |
4177 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0) | |
4178 | idx += 1 | |
4179 | if ctx['num'] == idx: | |
4180 | logger.info("Test: EAP-Failure") | |
4181 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4182 | ||
4183 | idx += 1 | |
4184 | if ctx['num'] == idx: | |
4185 | logger.info("Test: Notification indicating success, but no MAC") | |
4186 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
4187 | 4 + 1 + 3 + 4, | |
4188 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, | |
4189 | EAP_SIM_AT_NOTIFICATION, 1, 32768) | |
4190 | idx += 1 | |
4191 | if ctx['num'] == idx: | |
4192 | logger.info("Test: EAP-Failure") | |
4193 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4194 | ||
4195 | idx += 1 | |
4196 | if ctx['num'] == idx: | |
4197 | logger.info("Test: Notification indicating success, but invalid MAC value") | |
4198 | return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'], | |
4199 | 4 + 1 + 3 + 4 + 20, | |
4200 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, | |
4201 | EAP_SIM_AT_NOTIFICATION, 1, 32768, | |
4202 | EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) | |
4203 | idx += 1 | |
4204 | if ctx['num'] == idx: | |
4205 | logger.info("Test: EAP-Failure") | |
4206 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4207 | ||
4208 | idx += 1 | |
4209 | if ctx['num'] == idx: | |
4210 | logger.info("Test: Notification before auth") | |
4211 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
4212 | 4 + 1 + 3 + 4, | |
4213 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, | |
4214 | EAP_SIM_AT_NOTIFICATION, 1, 16384) | |
4215 | idx += 1 | |
4216 | if ctx['num'] == idx: | |
4217 | logger.info("Test: EAP-Failure") | |
4218 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4219 | ||
4220 | idx += 1 | |
4221 | if ctx['num'] == idx: | |
4222 | logger.info("Test: Notification before auth") | |
4223 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
4224 | 4 + 1 + 3 + 4, | |
4225 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, | |
4226 | EAP_SIM_AT_NOTIFICATION, 1, 16385) | |
4227 | idx += 1 | |
4228 | if ctx['num'] == idx: | |
4229 | logger.info("Test: EAP-Failure") | |
4230 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4231 | ||
4232 | idx += 1 | |
4233 | if ctx['num'] == idx: | |
4234 | logger.info("Test: Notification with unrecognized non-failure") | |
4235 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
4236 | 4 + 1 + 3 + 4, | |
4237 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, | |
4238 | EAP_SIM_AT_NOTIFICATION, 1, 0xc000) | |
4239 | idx += 1 | |
4240 | if ctx['num'] == idx: | |
4241 | logger.info("Test: Notification before auth (duplicate)") | |
4242 | return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
4243 | 4 + 1 + 3 + 4, | |
4244 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, | |
4245 | EAP_SIM_AT_NOTIFICATION, 1, 0xc000) | |
4246 | idx += 1 | |
4247 | if ctx['num'] == idx: | |
4248 | logger.info("Test: EAP-Failure") | |
4249 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4250 | ||
4251 | idx += 1 | |
4252 | if ctx['num'] == idx: | |
4253 | logger.info("Test: Re-authentication (unexpected) with no attributes") | |
4254 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], | |
4255 | 4 + 1 + 3, | |
4256 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_REAUTHENTICATION, | |
4257 | 0) | |
4258 | idx += 1 | |
4259 | if ctx['num'] == idx: | |
4260 | logger.info("Test: EAP-Failure") | |
4261 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4262 | ||
4263 | idx += 1 | |
4264 | if ctx['num'] == idx: | |
4265 | logger.info("Test: Client Error") | |
f0174bff JM |
4266 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], |
4267 | 4 + 1 + 3, | |
4268 | EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CLIENT_ERROR, 0) | |
6c080dfa JM |
4269 | idx += 1 |
4270 | if ctx['num'] == idx: | |
4271 | logger.info("Test: EAP-Failure") | |
4272 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4273 | ||
4274 | idx += 1 | |
4275 | if ctx['num'] == idx: | |
4276 | logger.info("Test: Unknown subtype") | |
f0174bff JM |
4277 | return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], |
4278 | 4 + 1 + 3, | |
4279 | EAP_TYPE_SIM, 255, 0) | |
6c080dfa JM |
4280 | idx += 1 |
4281 | if ctx['num'] == idx: | |
4282 | logger.info("Test: EAP-Failure") | |
4283 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4284 | ||
4285 | return None | |
4286 | ||
4287 | srv = start_radius_server(sim_handler) | |
6c080dfa JM |
4288 | |
4289 | try: | |
4290 | hapd = start_ap(apdev[0]['ifname']) | |
4291 | ||
4292 | for i in range(0, 25): | |
4293 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4294 | eap="SIM", identity="1232010000000000", | |
4295 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", | |
4296 | wait_connect=False) | |
4297 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
4298 | timeout=15) | |
4299 | if ev is None: | |
4300 | raise Exception("Timeout on EAP start") | |
4301 | if i in [ 0 ]: | |
4302 | time.sleep(0.1) | |
4303 | else: | |
4304 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], | |
4305 | timeout=10) | |
4306 | if ev is None: | |
4307 | raise Exception("Timeout on EAP failure") | |
4308 | dev[0].request("REMOVE_NETWORK all") | |
f0174bff | 4309 | dev[0].dump_monitor() |
6c080dfa JM |
4310 | finally: |
4311 | stop_radius_server(srv) | |
cb0555f7 | 4312 | |
d36ae376 JM |
4313 | def test_eap_proto_sim_errors(dev, apdev): |
4314 | """EAP-SIM protocol tests (error paths)""" | |
4315 | check_hlr_auc_gw_support() | |
4316 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
4317 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
4318 | ||
4319 | with alloc_fail(dev[0], 1, "eap_sim_init"): | |
4320 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4321 | eap="SIM", identity="1232010000000000", | |
4322 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", | |
4323 | wait_connect=False) | |
4324 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
4325 | timeout=15) | |
4326 | if ev is None: | |
4327 | raise Exception("Timeout on EAP start") | |
4328 | dev[0].request("REMOVE_NETWORK all") | |
4329 | dev[0].wait_disconnected() | |
4330 | ||
4331 | with fail_test(dev[0], 1, "os_get_random;eap_sim_init"): | |
4332 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4333 | eap="SIM", identity="1232010000000000", | |
4334 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", | |
4335 | wait_connect=False) | |
4336 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
4337 | timeout=15) | |
4338 | if ev is None: | |
4339 | raise Exception("Timeout on EAP start") | |
4340 | dev[0].request("REMOVE_NETWORK all") | |
4341 | dev[0].wait_disconnected() | |
4342 | ||
4343 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4344 | eap="SIM", identity="1232010000000000", | |
4345 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") | |
4346 | ||
4347 | with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_sim_response_reauth"): | |
4348 | hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) | |
4349 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) | |
4350 | if ev is None: | |
4351 | raise Exception("EAP re-authentication did not start") | |
4352 | wait_fail_trigger(dev[0], "GET_FAIL") | |
4353 | dev[0].request("REMOVE_NETWORK all") | |
4354 | dev[0].dump_monitor() | |
4355 | ||
4356 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4357 | eap="SIM", identity="1232010000000000", | |
4358 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") | |
4359 | ||
4360 | with fail_test(dev[0], 1, "os_get_random;eap_sim_msg_add_encr_start"): | |
4361 | hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) | |
4362 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) | |
4363 | if ev is None: | |
4364 | raise Exception("EAP re-authentication did not start") | |
4365 | wait_fail_trigger(dev[0], "GET_FAIL") | |
4366 | dev[0].request("REMOVE_NETWORK all") | |
4367 | dev[0].dump_monitor() | |
4368 | ||
4369 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4370 | eap="SIM", identity="1232010000000000", | |
4371 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") | |
4372 | ||
4373 | with fail_test(dev[0], 1, "os_get_random;eap_sim_init_for_reauth"): | |
4374 | hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) | |
4375 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) | |
4376 | if ev is None: | |
4377 | raise Exception("EAP re-authentication did not start") | |
4378 | wait_fail_trigger(dev[0], "GET_FAIL") | |
4379 | dev[0].request("REMOVE_NETWORK all") | |
4380 | dev[0].dump_monitor() | |
4381 | ||
4382 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4383 | eap="SIM", identity="1232010000000000", | |
4384 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") | |
4385 | ||
4386 | with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_sim_process_reauthentication"): | |
4387 | hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) | |
4388 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) | |
4389 | if ev is None: | |
4390 | raise Exception("EAP re-authentication did not start") | |
4391 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
4392 | dev[0].request("REMOVE_NETWORK all") | |
4393 | dev[0].dump_monitor() | |
4394 | ||
4395 | tests = [ (1, "eap_sim_verify_mac;eap_sim_process_challenge"), | |
4396 | (1, "eap_sim_parse_encr;eap_sim_process_challenge"), | |
4397 | (1, "eap_sim_msg_init;eap_sim_response_start"), | |
4398 | (1, "wpabuf_alloc;eap_sim_msg_init;eap_sim_response_start"), | |
4399 | (1, "=eap_sim_learn_ids"), | |
4400 | (2, "=eap_sim_learn_ids"), | |
4401 | (2, "eap_sim_learn_ids"), | |
4402 | (3, "eap_sim_learn_ids"), | |
4403 | (1, "eap_sim_process_start"), | |
4404 | (1, "eap_sim_getKey"), | |
4405 | (1, "eap_sim_get_emsk"), | |
4406 | (1, "eap_sim_get_session_id") ] | |
4407 | for count, func in tests: | |
4408 | with alloc_fail(dev[0], count, func): | |
4409 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4410 | eap="SIM", identity="1232010000000000", | |
4411 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", | |
4412 | erp="1", wait_connect=False) | |
4413 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
4414 | dev[0].request("REMOVE_NETWORK all") | |
4415 | dev[0].dump_monitor() | |
4416 | ||
4417 | tests = [ (1, "aes_128_cbc_decrypt;eap_sim_parse_encr") ] | |
4418 | for count, func in tests: | |
4419 | with fail_test(dev[0], count, func): | |
4420 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4421 | eap="SIM", identity="1232010000000000", | |
4422 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", | |
4423 | wait_connect=False) | |
4424 | wait_fail_trigger(dev[0], "GET_FAIL") | |
4425 | dev[0].request("REMOVE_NETWORK all") | |
4426 | dev[0].dump_monitor() | |
4427 | ||
4428 | def test_eap_proto_aka_errors(dev, apdev): | |
4429 | """EAP-AKA protocol tests (error paths)""" | |
4430 | check_hlr_auc_gw_support() | |
4431 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
4432 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
4433 | ||
4434 | with alloc_fail(dev[0], 1, "eap_aka_init"): | |
4435 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4436 | eap="AKA", identity="0232010000000000", | |
4437 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123", | |
4438 | wait_connect=False) | |
4439 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
4440 | timeout=15) | |
4441 | if ev is None: | |
4442 | raise Exception("Timeout on EAP start") | |
4443 | dev[0].request("REMOVE_NETWORK all") | |
4444 | dev[0].wait_disconnected() | |
4445 | ||
4446 | tests = [ (1, "=eap_aka_learn_ids"), | |
4447 | (2, "=eap_aka_learn_ids"), | |
4448 | (1, "eap_sim_parse_encr;eap_aka_process_challenge"), | |
4449 | (1, "eap_aka_getKey"), | |
4450 | (1, "eap_aka_get_emsk"), | |
4451 | (1, "eap_aka_get_session_id") ] | |
4452 | for count, func in tests: | |
4453 | with alloc_fail(dev[0], count, func): | |
4454 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4455 | eap="AKA", identity="0232010000000000", | |
4456 | password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123", | |
4457 | erp="1", wait_connect=False) | |
4458 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
4459 | dev[0].request("REMOVE_NETWORK all") | |
4460 | dev[0].dump_monitor() | |
4461 | ||
4462 | def test_eap_proto_aka_prime_errors(dev, apdev): | |
4463 | """EAP-AKA' protocol tests (error paths)""" | |
4464 | check_hlr_auc_gw_support() | |
4465 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
4466 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
4467 | ||
4468 | with alloc_fail(dev[0], 1, "eap_aka_init"): | |
4469 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4470 | eap="AKA'", identity="6555444333222111", | |
4471 | password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123", | |
4472 | wait_connect=False) | |
4473 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
4474 | timeout=15) | |
4475 | if ev is None: | |
4476 | raise Exception("Timeout on EAP start") | |
4477 | dev[0].request("REMOVE_NETWORK all") | |
4478 | dev[0].wait_disconnected() | |
4479 | ||
4480 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4481 | eap="AKA'", identity="6555444333222111", | |
4482 | password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123") | |
4483 | ||
4484 | with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_aka_response_reauth"): | |
4485 | hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) | |
4486 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) | |
4487 | if ev is None: | |
4488 | raise Exception("EAP re-authentication did not start") | |
4489 | wait_fail_trigger(dev[0], "GET_FAIL") | |
4490 | dev[0].request("REMOVE_NETWORK all") | |
4491 | dev[0].dump_monitor() | |
4492 | ||
4493 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4494 | eap="AKA'", identity="6555444333222111", | |
4495 | password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123") | |
4496 | ||
4497 | with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_aka_process_reauthentication"): | |
4498 | hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) | |
4499 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) | |
4500 | if ev is None: | |
4501 | raise Exception("EAP re-authentication did not start") | |
4502 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
4503 | dev[0].request("REMOVE_NETWORK all") | |
4504 | dev[0].dump_monitor() | |
4505 | ||
4506 | tests = [ (1, "eap_sim_verify_mac_sha256"), | |
4507 | (1, "=eap_aka_process_challenge") ] | |
4508 | for count, func in tests: | |
4509 | with alloc_fail(dev[0], count, func): | |
4510 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4511 | eap="AKA'", identity="6555444333222111", | |
4512 | password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123", | |
4513 | erp="1", wait_connect=False) | |
4514 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
4515 | dev[0].request("REMOVE_NETWORK all") | |
4516 | dev[0].dump_monitor() | |
4517 | ||
cb0555f7 JM |
4518 | def test_eap_proto_ikev2(dev, apdev): |
4519 | """EAP-IKEv2 protocol tests""" | |
c8e82c94 | 4520 | check_eap_capa(dev[0], "IKEV2") |
cb0555f7 JM |
4521 | def ikev2_handler(ctx, req): |
4522 | logger.info("ikev2_handler - RX " + req.encode("hex")) | |
4523 | if 'num' not in ctx: | |
4524 | ctx['num'] = 0 | |
4525 | ctx['num'] = ctx['num'] + 1 | |
4526 | if 'id' not in ctx: | |
4527 | ctx['id'] = 1 | |
4528 | ctx['id'] = (ctx['id'] + 1) % 256 | |
4529 | ||
4530 | idx = 0 | |
4531 | ||
4532 | idx += 1 | |
4533 | if ctx['num'] == idx: | |
4534 | logger.info("Test: Missing payload") | |
4535 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
4536 | 4 + 1, | |
4537 | EAP_TYPE_IKEV2) | |
4538 | ||
4539 | idx += 1 | |
4540 | if ctx['num'] == idx: | |
4541 | logger.info("Test: Truncated Message Length field") | |
4542 | return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'], | |
4543 | 4 + 1 + 1 + 3, | |
4544 | EAP_TYPE_IKEV2, 0x80, 0, 0, 0) | |
4545 | ||
4546 | idx += 1 | |
4547 | if ctx['num'] == idx: | |
4548 | logger.info("Test: Too short Message Length value") | |
4549 | return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], | |
4550 | 4 + 1 + 1 + 4 + 1, | |
4551 | EAP_TYPE_IKEV2, 0x80, 0, 1) | |
4552 | ||
4553 | idx += 1 | |
4554 | if ctx['num'] == idx: | |
4555 | logger.info("Test: Truncated message") | |
4556 | return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], | |
4557 | 4 + 1 + 1 + 4, | |
4558 | EAP_TYPE_IKEV2, 0x80, 1) | |
4559 | ||
4560 | idx += 1 | |
4561 | if ctx['num'] == idx: | |
4562 | logger.info("Test: Truncated message(2)") | |
4563 | return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], | |
4564 | 4 + 1 + 1 + 4, | |
4565 | EAP_TYPE_IKEV2, 0x80, 0xffffffff) | |
4566 | ||
4567 | idx += 1 | |
4568 | if ctx['num'] == idx: | |
4569 | logger.info("Test: Truncated message(3)") | |
4570 | return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], | |
4571 | 4 + 1 + 1 + 4, | |
4572 | EAP_TYPE_IKEV2, 0xc0, 0xffffffff) | |
4573 | ||
4574 | idx += 1 | |
4575 | if ctx['num'] == idx: | |
4576 | logger.info("Test: Truncated message(4)") | |
4577 | return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], | |
4578 | 4 + 1 + 1 + 4, | |
4579 | EAP_TYPE_IKEV2, 0xc0, 10000000) | |
4580 | ||
4581 | idx += 1 | |
4582 | if ctx['num'] == idx: | |
4583 | logger.info("Test: Too long fragments (first fragment)") | |
4584 | return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], | |
4585 | 4 + 1 + 1 + 4 + 1, | |
4586 | EAP_TYPE_IKEV2, 0xc0, 2, 1) | |
4587 | ||
4588 | idx += 1 | |
4589 | if ctx['num'] == idx: | |
4590 | logger.info("Test: Too long fragments (second fragment)") | |
4591 | return struct.pack(">BBHBB2B", EAP_CODE_REQUEST, ctx['id'], | |
4592 | 4 + 1 + 1 + 2, | |
4593 | EAP_TYPE_IKEV2, 0x00, 2, 3) | |
4594 | ||
4595 | idx += 1 | |
4596 | if ctx['num'] == idx: | |
4597 | logger.info("Test: No Message Length field in first fragment") | |
4598 | return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], | |
4599 | 4 + 1 + 1 + 1, | |
4600 | EAP_TYPE_IKEV2, 0x40, 1) | |
4601 | ||
4602 | idx += 1 | |
4603 | if ctx['num'] == idx: | |
4604 | logger.info("Test: ICV before keys") | |
4605 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
4606 | 4 + 1 + 1, | |
4607 | EAP_TYPE_IKEV2, 0x20) | |
4608 | ||
4609 | idx += 1 | |
4610 | if ctx['num'] == idx: | |
4611 | logger.info("Test: Unsupported IKEv2 header version") | |
4612 | return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
4613 | 4 + 1 + 1 + 28, | |
4614 | EAP_TYPE_IKEV2, 0x00, | |
4615 | 0, 0, 0, 0, | |
4616 | 0, 0, 0, 0, 0, 0) | |
4617 | ||
4618 | idx += 1 | |
4619 | if ctx['num'] == idx: | |
4620 | logger.info("Test: Incorrect IKEv2 header Length") | |
4621 | return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
4622 | 4 + 1 + 1 + 28, | |
4623 | EAP_TYPE_IKEV2, 0x00, | |
4624 | 0, 0, 0, 0, | |
4625 | 0, 0x20, 0, 0, 0, 0) | |
4626 | ||
4627 | idx += 1 | |
4628 | if ctx['num'] == idx: | |
4629 | logger.info("Test: Unexpected IKEv2 Exchange Type in SA_INIT state") | |
4630 | return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
4631 | 4 + 1 + 1 + 28, | |
4632 | EAP_TYPE_IKEV2, 0x00, | |
4633 | 0, 0, 0, 0, | |
4634 | 0, 0x20, 0, 0, 0, 28) | |
4635 | ||
4636 | idx += 1 | |
4637 | if ctx['num'] == idx: | |
4638 | logger.info("Test: Unexpected IKEv2 Message ID in SA_INIT state") | |
4639 | return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
4640 | 4 + 1 + 1 + 28, | |
4641 | EAP_TYPE_IKEV2, 0x00, | |
4642 | 0, 0, 0, 0, | |
4643 | 0, 0x20, 34, 0, 1, 28) | |
4644 | ||
4645 | idx += 1 | |
4646 | if ctx['num'] == idx: | |
4647 | logger.info("Test: Unexpected IKEv2 Flags value") | |
4648 | return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
4649 | 4 + 1 + 1 + 28, | |
4650 | EAP_TYPE_IKEV2, 0x00, | |
4651 | 0, 0, 0, 0, | |
4652 | 0, 0x20, 34, 0, 0, 28) | |
4653 | ||
4654 | idx += 1 | |
4655 | if ctx['num'] == idx: | |
4656 | logger.info("Test: Unexpected IKEv2 Flags value(2)") | |
4657 | return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
4658 | 4 + 1 + 1 + 28, | |
4659 | EAP_TYPE_IKEV2, 0x00, | |
4660 | 0, 0, 0, 0, | |
4661 | 0, 0x20, 34, 0x20, 0, 28) | |
4662 | ||
4663 | idx += 1 | |
4664 | if ctx['num'] == idx: | |
4665 | logger.info("Test: No SAi1 in SA_INIT") | |
4666 | return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], | |
4667 | 4 + 1 + 1 + 28, | |
4668 | EAP_TYPE_IKEV2, 0x00, | |
4669 | 0, 0, 0, 0, | |
4670 | 0, 0x20, 34, 0x08, 0, 28) | |
4671 | ||
4672 | def build_ike(id, next=0, exch_type=34, flags=0x00, ike=''): | |
4673 | return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, id, | |
4674 | 4 + 1 + 1 + 28 + len(ike), | |
4675 | EAP_TYPE_IKEV2, flags, | |
4676 | 0, 0, 0, 0, | |
4677 | next, 0x20, exch_type, 0x08, 0, | |
4678 | 28 + len(ike)) + ike | |
4679 | ||
4680 | idx += 1 | |
4681 | if ctx['num'] == idx: | |
4682 | logger.info("Test: Unexpected extra data after payloads") | |
4683 | return build_ike(ctx['id'], ike=struct.pack(">B", 1)) | |
4684 | ||
4685 | idx += 1 | |
4686 | if ctx['num'] == idx: | |
4687 | logger.info("Test: Truncated payload header") | |
4688 | return build_ike(ctx['id'], next=128, ike=struct.pack(">B", 1)) | |
4689 | ||
4690 | idx += 1 | |
4691 | if ctx['num'] == idx: | |
4692 | logger.info("Test: Too small payload header length") | |
4693 | ike = struct.pack(">BBH", 0, 0, 3) | |
4694 | return build_ike(ctx['id'], next=128, ike=ike) | |
4695 | ||
4696 | idx += 1 | |
4697 | if ctx['num'] == idx: | |
4698 | logger.info("Test: Too large payload header length") | |
4699 | ike = struct.pack(">BBH", 0, 0, 5) | |
4700 | return build_ike(ctx['id'], next=128, ike=ike) | |
4701 | ||
4702 | idx += 1 | |
4703 | if ctx['num'] == idx: | |
4704 | logger.info("Test: Unsupported payload (non-critical and critical)") | |
4705 | ike = struct.pack(">BBHBBH", 129, 0, 4, 0, 0x01, 4) | |
4706 | return build_ike(ctx['id'], next=128, ike=ike) | |
4707 | ||
4708 | idx += 1 | |
4709 | if ctx['num'] == idx: | |
4710 | logger.info("Test: Certificate and empty SAi1") | |
4711 | ike = struct.pack(">BBHBBH", 33, 0, 4, 0, 0, 4) | |
4712 | return build_ike(ctx['id'], next=37, ike=ike) | |
4713 | ||
4714 | idx += 1 | |
4715 | if ctx['num'] == idx: | |
4716 | logger.info("Test: Too short proposal") | |
4717 | ike = struct.pack(">BBHBBHBBB", 0, 0, 4 + 7, | |
4718 | 0, 0, 7, 0, 0, 0) | |
4719 | return build_ike(ctx['id'], next=33, ike=ike) | |
4720 | ||
4721 | idx += 1 | |
4722 | if ctx['num'] == idx: | |
4723 | logger.info("Test: Too small proposal length in SAi1") | |
4724 | ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, | |
4725 | 0, 0, 7, 0, 0, 0, 0) | |
4726 | return build_ike(ctx['id'], next=33, ike=ike) | |
4727 | ||
4728 | idx += 1 | |
4729 | if ctx['num'] == idx: | |
4730 | logger.info("Test: Too large proposal length in SAi1") | |
4731 | ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, | |
4732 | 0, 0, 9, 0, 0, 0, 0) | |
4733 | return build_ike(ctx['id'], next=33, ike=ike) | |
4734 | ||
4735 | idx += 1 | |
4736 | if ctx['num'] == idx: | |
4737 | logger.info("Test: Unexpected proposal type in SAi1") | |
4738 | ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, | |
4739 | 1, 0, 8, 0, 0, 0, 0) | |
4740 | return build_ike(ctx['id'], next=33, ike=ike) | |
4741 | ||
4742 | idx += 1 | |
4743 | if ctx['num'] == idx: | |
4744 | logger.info("Test: Unexpected Protocol ID in SAi1") | |
4745 | ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, | |
4746 | 0, 0, 8, 0, 0, 0, 0) | |
4747 | return build_ike(ctx['id'], next=33, ike=ike) | |
4748 | ||
4749 | idx += 1 | |
4750 | if ctx['num'] == idx: | |
4751 | logger.info("Test: Unexpected proposal number in SAi1") | |
4752 | ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, | |
4753 | 0, 0, 8, 0, 1, 0, 0) | |
4754 | return build_ike(ctx['id'], next=33, ike=ike) | |
4755 | ||
4756 | idx += 1 | |
4757 | if ctx['num'] == idx: | |
4758 | logger.info("Test: Not enough room for SPI in SAi1") | |
4759 | ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, | |
4760 | 0, 0, 8, 1, 1, 1, 0) | |
4761 | return build_ike(ctx['id'], next=33, ike=ike) | |
4762 | ||
4763 | idx += 1 | |
4764 | if ctx['num'] == idx: | |
4765 | logger.info("Test: Unexpected SPI in SAi1") | |
4766 | ike = struct.pack(">BBHBBHBBBBB", 0, 0, 4 + 9, | |
4767 | 0, 0, 9, 1, 1, 1, 0, 1) | |
4768 | return build_ike(ctx['id'], next=33, ike=ike) | |
4769 | ||
4770 | idx += 1 | |
4771 | if ctx['num'] == idx: | |
4772 | logger.info("Test: No transforms in SAi1") | |
4773 | ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, | |
4774 | 0, 0, 8, 1, 1, 0, 0) | |
4775 | return build_ike(ctx['id'], next=33, ike=ike) | |
4776 | ||
4777 | idx += 1 | |
4778 | if ctx['num'] == idx: | |
4779 | logger.info("Test: Too short transform in SAi1") | |
4780 | ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, | |
4781 | 0, 0, 8, 1, 1, 0, 1) | |
4782 | return build_ike(ctx['id'], next=33, ike=ike) | |
4783 | ||
4784 | idx += 1 | |
4785 | if ctx['num'] == idx: | |
4786 | logger.info("Test: Too small transform length in SAi1") | |
4787 | ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, | |
4788 | 0, 0, 8 + 8, 1, 1, 0, 1, | |
4789 | 0, 0, 7, 0, 0, 0) | |
4790 | return build_ike(ctx['id'], next=33, ike=ike) | |
4791 | ||
4792 | idx += 1 | |
4793 | if ctx['num'] == idx: | |
4794 | logger.info("Test: Too large transform length in SAi1") | |
4795 | ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, | |
4796 | 0, 0, 8 + 8, 1, 1, 0, 1, | |
4797 | 0, 0, 9, 0, 0, 0) | |
4798 | return build_ike(ctx['id'], next=33, ike=ike) | |
4799 | ||
4800 | idx += 1 | |
4801 | if ctx['num'] == idx: | |
4802 | logger.info("Test: Unexpected Transform type in SAi1") | |
4803 | ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, | |
4804 | 0, 0, 8 + 8, 1, 1, 0, 1, | |
4805 | 1, 0, 8, 0, 0, 0) | |
4806 | return build_ike(ctx['id'], next=33, ike=ike) | |
4807 | ||
4808 | idx += 1 | |
4809 | if ctx['num'] == idx: | |
4810 | logger.info("Test: No transform attributes in SAi1") | |
4811 | ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, | |
4812 | 0, 0, 8 + 8, 1, 1, 0, 1, | |
4813 | 0, 0, 8, 0, 0, 0) | |
4814 | return build_ike(ctx['id'], next=33, ike=ike) | |
4815 | ||
4816 | idx += 1 | |
4817 | if ctx['num'] == idx: | |
4818 | logger.info("Test: No transform attr for AES and unexpected data after transforms in SAi1") | |
4819 | tlen1 = 8 + 3 | |
4820 | tlen2 = 8 + 4 | |
4821 | tlen3 = 8 + 4 | |
4822 | tlen = tlen1 + tlen2 + tlen3 | |
4823 | ike = struct.pack(">BBHBBHBBBBBBHBBH3BBBHBBHHHBBHBBHHHB", | |
4824 | 0, 0, 4 + 8 + tlen + 1, | |
4825 | 0, 0, 8 + tlen + 1, 1, 1, 0, 3, | |
4826 | 3, 0, tlen1, 1, 0, 12, 1, 2, 3, | |
4827 | 3, 0, tlen2, 1, 0, 12, 0, 128, | |
4828 | 0, 0, tlen3, 1, 0, 12, 0x8000 | 14, 127, | |
4829 | 1) | |
4830 | return build_ike(ctx['id'], next=33, ike=ike) | |
4831 | ||
4832 | def build_sa(next=0): | |
4833 | tlen = 5 * 8 | |
4834 | return struct.pack(">BBHBBHBBBBBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH", | |
4835 | next, 0, 4 + 8 + tlen, | |
4836 | 0, 0, 8 + tlen, 1, 1, 0, 5, | |
4837 | 3, 0, 8, 1, 0, 3, | |
4838 | 3, 0, 8, 2, 0, 1, | |
4839 | 3, 0, 8, 3, 0, 1, | |
4840 | 3, 0, 8, 4, 0, 5, | |
4841 | 0, 0, 8, 241, 0, 0) | |
4842 | ||
4843 | idx += 1 | |
4844 | if ctx['num'] == idx: | |
4845 | logger.info("Test: Valid proposal, but no KEi in SAi1") | |
4846 | ike = build_sa() | |
4847 | return build_ike(ctx['id'], next=33, ike=ike) | |
4848 | ||
4849 | idx += 1 | |
4850 | if ctx['num'] == idx: | |
4851 | logger.info("Test: Empty KEi in SAi1") | |
4852 | ike = build_sa(next=34) + struct.pack(">BBH", 0, 0, 4) | |
4853 | return build_ike(ctx['id'], next=33, ike=ike) | |
4854 | ||
4855 | idx += 1 | |
4856 | if ctx['num'] == idx: | |
4857 | logger.info("Test: Mismatch in DH Group in SAi1") | |
4858 | ike = build_sa(next=34) | |
4859 | ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 12345, 0) | |
4860 | ike += 96*'\x00' | |
4861 | return build_ike(ctx['id'], next=33, ike=ike) | |
4862 | idx += 1 | |
4863 | if ctx['num'] == idx: | |
4864 | logger.info("Test: EAP-Failure") | |
4865 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4866 | ||
4867 | idx += 1 | |
4868 | if ctx['num'] == idx: | |
4869 | logger.info("Test: Invalid DH public value length in SAi1") | |
4870 | ike = build_sa(next=34) | |
4871 | ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 5, 0) | |
4872 | ike += 96*'\x00' | |
4873 | return build_ike(ctx['id'], next=33, ike=ike) | |
4874 | ||
4875 | def build_ke(next=0): | |
4876 | ke = struct.pack(">BBHHH", next, 0, 4 + 4 + 192, 5, 0) | |
4877 | ke += 192*'\x00' | |
4878 | return ke | |
4879 | ||
4880 | idx += 1 | |
4881 | if ctx['num'] == idx: | |
4882 | logger.info("Test: Valid proposal and KEi, but no Ni in SAi1") | |
4883 | ike = build_sa(next=34) | |
4884 | ike += build_ke() | |
4885 | return build_ike(ctx['id'], next=33, ike=ike) | |
4886 | ||
4887 | idx += 1 | |
4888 | if ctx['num'] == idx: | |
4889 | logger.info("Test: Too short Ni in SAi1") | |
4890 | ike = build_sa(next=34) | |
4891 | ike += build_ke(next=40) | |
4892 | ike += struct.pack(">BBH", 0, 0, 4) | |
4893 | return build_ike(ctx['id'], next=33, ike=ike) | |
4894 | ||
4895 | idx += 1 | |
4896 | if ctx['num'] == idx: | |
4897 | logger.info("Test: Too long Ni in SAi1") | |
4898 | ike = build_sa(next=34) | |
4899 | ike += build_ke(next=40) | |
4900 | ike += struct.pack(">BBH", 0, 0, 4 + 257) + 257*'\x00' | |
4901 | return build_ike(ctx['id'], next=33, ike=ike) | |
4902 | ||
4903 | def build_ni(next=0): | |
4904 | return struct.pack(">BBH", next, 0, 4 + 256) + 256*'\x00' | |
4905 | ||
4906 | def build_sai1(id): | |
4907 | ike = build_sa(next=34) | |
4908 | ike += build_ke(next=40) | |
4909 | ike += build_ni() | |
4910 | return build_ike(ctx['id'], next=33, ike=ike) | |
4911 | ||
4912 | idx += 1 | |
4913 | if ctx['num'] == idx: | |
4914 | logger.info("Test: Valid proposal, KEi, and Ni in SAi1") | |
4915 | return build_sai1(ctx['id']) | |
4916 | idx += 1 | |
4917 | if ctx['num'] == idx: | |
4918 | logger.info("Test: EAP-Failure") | |
4919 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
4920 | ||
4921 | idx += 1 | |
4922 | if ctx['num'] == idx: | |
4923 | logger.info("Test: Valid proposal, KEi, and Ni in SAi1") | |
4924 | return build_sai1(ctx['id']) | |
4925 | idx += 1 | |
4926 | if ctx['num'] == idx: | |
4927 | logger.info("Test: No integrity checksum") | |
4928 | ike = '' | |
4929 | return build_ike(ctx['id'], next=37, ike=ike) | |
4930 | ||
4931 | idx += 1 | |
4932 | if ctx['num'] == idx: | |
4933 | logger.info("Test: Valid proposal, KEi, and Ni in SAi1") | |
4934 | return build_sai1(ctx['id']) | |
4935 | idx += 1 | |
4936 | if ctx['num'] == idx: | |
4937 | logger.info("Test: Truncated integrity checksum") | |
4938 | return struct.pack(">BBHBB", | |
4939 | EAP_CODE_REQUEST, ctx['id'], | |
4940 | 4 + 1 + 1, | |
4941 | EAP_TYPE_IKEV2, 0x20) | |
4942 | ||
4943 | idx += 1 | |
4944 | if ctx['num'] == idx: | |
4945 | logger.info("Test: Valid proposal, KEi, and Ni in SAi1") | |
4946 | return build_sai1(ctx['id']) | |
4947 | idx += 1 | |
4948 | if ctx['num'] == idx: | |
4949 | logger.info("Test: Invalid integrity checksum") | |
4950 | ike = '' | |
4951 | return build_ike(ctx['id'], next=37, flags=0x20, ike=ike) | |
4952 | ||
4953 | return None | |
4954 | ||
4955 | srv = start_radius_server(ikev2_handler) | |
cb0555f7 JM |
4956 | |
4957 | try: | |
4958 | hapd = start_ap(apdev[0]['ifname']) | |
4959 | ||
4960 | for i in range(49): | |
4961 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
4962 | eap="IKEV2", identity="user", | |
4963 | password="password", | |
4964 | wait_connect=False) | |
4965 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
4966 | timeout=15) | |
4967 | if ev is None: | |
4968 | raise Exception("Timeout on EAP start") | |
4969 | if i in [ 40, 45 ]: | |
4970 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], | |
4971 | timeout=10) | |
4972 | if ev is None: | |
4973 | raise Exception("Timeout on EAP failure") | |
4974 | else: | |
4975 | time.sleep(0.05) | |
4976 | dev[0].request("REMOVE_NETWORK all") | |
4977 | finally: | |
4978 | stop_radius_server(srv) | |
37211e15 JM |
4979 | |
4980 | def NtPasswordHash(password): | |
4981 | pw = password.encode('utf_16_le') | |
4982 | return hashlib.new('md4', pw).digest() | |
4983 | ||
4984 | def HashNtPasswordHash(password_hash): | |
4985 | return hashlib.new('md4', password_hash).digest() | |
4986 | ||
4987 | def ChallengeHash(peer_challenge, auth_challenge, username): | |
4988 | data = peer_challenge + auth_challenge + username | |
4989 | return hashlib.sha1(data).digest()[0:8] | |
4990 | ||
4991 | def GenerateAuthenticatorResponse(password, nt_response, peer_challenge, | |
4992 | auth_challenge, username): | |
4993 | magic1 = binascii.unhexlify("4D616769632073657276657220746F20636C69656E74207369676E696E6720636F6E7374616E74") | |
4994 | magic2 = binascii.unhexlify("50616420746F206D616B6520697420646F206D6F7265207468616E206F6E6520697465726174696F6E") | |
4995 | ||
4996 | password_hash = NtPasswordHash(password) | |
4997 | password_hash_hash = HashNtPasswordHash(password_hash) | |
4998 | data = password_hash_hash + nt_response + magic1 | |
4999 | digest = hashlib.sha1(data).digest() | |
5000 | ||
5001 | challenge = ChallengeHash(peer_challenge, auth_challenge, username) | |
5002 | ||
5003 | data = digest + challenge + magic2 | |
5004 | resp = hashlib.sha1(data).digest() | |
5005 | return resp | |
5006 | ||
4073ef22 JM |
5007 | def test_eap_proto_ikev2_errors(dev, apdev): |
5008 | """EAP-IKEv2 local error cases""" | |
5009 | check_eap_capa(dev[0], "IKEV2") | |
5010 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
5011 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
5012 | ||
5013 | for i in range(1, 5): | |
5014 | with alloc_fail(dev[0], i, "eap_ikev2_init"): | |
5015 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5016 | eap="IKEV2", identity="ikev2 user", | |
5017 | password="ike password", | |
5018 | wait_connect=False) | |
5019 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
5020 | timeout=15) | |
5021 | if ev is None: | |
5022 | raise Exception("Timeout on EAP start") | |
5023 | dev[0].request("REMOVE_NETWORK all") | |
5024 | dev[0].wait_disconnected() | |
5025 | ||
5026 | tests = [ (1, "ikev2_encr_encrypt"), | |
5027 | (1, "ikev2_encr_decrypt"), | |
5028 | (1, "ikev2_derive_auth_data"), | |
5029 | (2, "ikev2_derive_auth_data"), | |
5030 | (1, "=ikev2_decrypt_payload"), | |
5031 | (1, "ikev2_encr_decrypt;ikev2_decrypt_payload"), | |
5032 | (1, "ikev2_encr_encrypt;ikev2_build_encrypted"), | |
5033 | (1, "ikev2_derive_sk_keys"), | |
5034 | (2, "ikev2_derive_sk_keys"), | |
5035 | (3, "ikev2_derive_sk_keys"), | |
5036 | (4, "ikev2_derive_sk_keys"), | |
5037 | (5, "ikev2_derive_sk_keys"), | |
5038 | (6, "ikev2_derive_sk_keys"), | |
5039 | (7, "ikev2_derive_sk_keys"), | |
5040 | (8, "ikev2_derive_sk_keys"), | |
5041 | (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"), | |
5042 | (1, "eap_msg_alloc;eap_ikev2_build_msg"), | |
5043 | (1, "eap_ikev2_getKey"), | |
5044 | (1, "eap_ikev2_get_emsk"), | |
5045 | (1, "eap_ikev2_get_session_id"), | |
5046 | (1, "=ikev2_derive_keys"), | |
5047 | (2, "=ikev2_derive_keys"), | |
5048 | (1, "wpabuf_alloc;ikev2_process_kei"), | |
5049 | (1, "=ikev2_process_idi"), | |
5050 | (1, "ikev2_derive_auth_data;ikev2_build_auth"), | |
5051 | (1, "wpabuf_alloc;ikev2_build_sa_init"), | |
5052 | (2, "wpabuf_alloc;ikev2_build_sa_init"), | |
5053 | (3, "wpabuf_alloc;ikev2_build_sa_init"), | |
5054 | (4, "wpabuf_alloc;ikev2_build_sa_init"), | |
5055 | (5, "wpabuf_alloc;ikev2_build_sa_init"), | |
5056 | (6, "wpabuf_alloc;ikev2_build_sa_init"), | |
5057 | (1, "wpabuf_alloc;ikev2_build_sa_auth"), | |
5058 | (2, "wpabuf_alloc;ikev2_build_sa_auth"), | |
5059 | (1, "ikev2_build_auth;ikev2_build_sa_auth") ] | |
5060 | for count, func in tests: | |
5061 | with alloc_fail(dev[0], count, func): | |
5062 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5063 | eap="IKEV2", identity="ikev2 user", | |
5064 | password="ike password", erp="1", wait_connect=False) | |
5065 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
5066 | timeout=15) | |
5067 | if ev is None: | |
5068 | raise Exception("Timeout on EAP start") | |
5069 | ok = False | |
5070 | for j in range(10): | |
5071 | state = dev[0].request('GET_ALLOC_FAIL') | |
5072 | if state.startswith('0:'): | |
5073 | ok = True | |
5074 | break | |
5075 | time.sleep(0.1) | |
5076 | if not ok: | |
5077 | raise Exception("No allocation failure seen for %d:%s" % (count, func)) | |
5078 | dev[0].request("REMOVE_NETWORK all") | |
5079 | dev[0].wait_disconnected() | |
5080 | ||
5081 | tests = [ (1, "wpabuf_alloc;ikev2_build_notify"), | |
5082 | (2, "wpabuf_alloc;ikev2_build_notify"), | |
5083 | (1, "ikev2_build_encrypted;ikev2_build_notify") ] | |
5084 | for count, func in tests: | |
5085 | with alloc_fail(dev[0], count, func): | |
5086 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5087 | eap="IKEV2", identity="ikev2 user", | |
5088 | password="wrong password", erp="1", | |
5089 | wait_connect=False) | |
5090 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
5091 | timeout=15) | |
5092 | if ev is None: | |
5093 | raise Exception("Timeout on EAP start") | |
5094 | ok = False | |
5095 | for j in range(10): | |
5096 | state = dev[0].request('GET_ALLOC_FAIL') | |
5097 | if state.startswith('0:'): | |
5098 | ok = True | |
5099 | break | |
5100 | time.sleep(0.1) | |
5101 | if not ok: | |
5102 | raise Exception("No allocation failure seen for %d:%s" % (count, func)) | |
5103 | dev[0].request("REMOVE_NETWORK all") | |
5104 | dev[0].wait_disconnected() | |
5105 | ||
5106 | tests = [ (1, "ikev2_integ_hash"), | |
5107 | (1, "ikev2_integ_hash;ikev2_decrypt_payload"), | |
5108 | (1, "os_get_random;ikev2_build_encrypted"), | |
5109 | (1, "ikev2_prf_plus;ikev2_derive_sk_keys"), | |
5110 | (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"), | |
5111 | (1, "os_get_random;ikev2_build_sa_init"), | |
5112 | (2, "os_get_random;ikev2_build_sa_init"), | |
5113 | (1, "ikev2_integ_hash;eap_ikev2_validate_icv"), | |
5114 | (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_keys"), | |
5115 | (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"), | |
5116 | (2, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"), | |
5117 | (3, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data") ] | |
5118 | for count, func in tests: | |
5119 | with fail_test(dev[0], count, func): | |
5120 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5121 | eap="IKEV2", identity="ikev2 user", | |
5122 | password="ike password", wait_connect=False) | |
5123 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
5124 | timeout=15) | |
5125 | if ev is None: | |
5126 | raise Exception("Timeout on EAP start") | |
5127 | ok = False | |
5128 | for j in range(10): | |
5129 | state = dev[0].request('GET_FAIL') | |
5130 | if state.startswith('0:'): | |
5131 | ok = True | |
5132 | break | |
5133 | time.sleep(0.1) | |
5134 | if not ok: | |
5135 | raise Exception("No failure seen for %d:%s" % (count, func)) | |
5136 | dev[0].request("REMOVE_NETWORK all") | |
5137 | dev[0].wait_disconnected() | |
5138 | ||
5139 | params = { "ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP", | |
5140 | "rsn_pairwise": "CCMP", "ieee8021x": "1", | |
5141 | "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf", | |
5142 | "fragment_size": "50" } | |
5143 | hostapd.add_ap(apdev[1]['ifname'], params) | |
5144 | ||
5145 | tests = [ (1, "eap_ikev2_build_frag_ack"), | |
5146 | (1, "wpabuf_alloc;eap_ikev2_process_fragment") ] | |
5147 | for count, func in tests: | |
5148 | with alloc_fail(dev[0], count, func): | |
5149 | dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412", | |
5150 | eap="IKEV2", identity="ikev2 user", | |
5151 | password="ike password", erp="1", wait_connect=False) | |
5152 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
5153 | timeout=15) | |
5154 | if ev is None: | |
5155 | raise Exception("Timeout on EAP start") | |
5156 | ok = False | |
5157 | for j in range(10): | |
5158 | state = dev[0].request('GET_ALLOC_FAIL') | |
5159 | if state.startswith('0:'): | |
5160 | ok = True | |
5161 | break | |
5162 | time.sleep(0.1) | |
5163 | if not ok: | |
5164 | raise Exception("No allocation failure seen for %d:%s" % (count, func)) | |
5165 | dev[0].request("REMOVE_NETWORK all") | |
5166 | dev[0].wait_disconnected() | |
5167 | ||
37211e15 JM |
5168 | def test_eap_proto_mschapv2(dev, apdev): |
5169 | """EAP-MSCHAPv2 protocol tests""" | |
5170 | check_eap_capa(dev[0], "MSCHAPV2") | |
5171 | ||
5172 | def mschapv2_handler(ctx, req): | |
5173 | logger.info("mschapv2_handler - RX " + req.encode("hex")) | |
5174 | if 'num' not in ctx: | |
5175 | ctx['num'] = 0 | |
5176 | ctx['num'] = ctx['num'] + 1 | |
5177 | if 'id' not in ctx: | |
5178 | ctx['id'] = 1 | |
5179 | ctx['id'] = (ctx['id'] + 1) % 256 | |
5180 | idx = 0 | |
5181 | ||
5182 | idx += 1 | |
5183 | if ctx['num'] == idx: | |
5184 | logger.info("Test: Missing payload") | |
5185 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5186 | 4 + 1, | |
5187 | EAP_TYPE_MSCHAPV2) | |
5188 | ||
5189 | idx += 1 | |
5190 | if ctx['num'] == idx: | |
5191 | logger.info("Test: Unknown MSCHAPv2 op_code") | |
5192 | return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], | |
5193 | 4 + 1 + 4 + 1, | |
5194 | EAP_TYPE_MSCHAPV2, | |
5195 | 0, 0, 5, 0) | |
5196 | ||
5197 | idx += 1 | |
5198 | if ctx['num'] == idx: | |
5199 | logger.info("Test: Invalid ms_len and unknown MSCHAPv2 op_code") | |
5200 | return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], | |
5201 | 4 + 1 + 4 + 1, | |
5202 | EAP_TYPE_MSCHAPV2, | |
5203 | 255, 0, 0, 0) | |
5204 | ||
5205 | idx += 1 | |
5206 | if ctx['num'] == idx: | |
5207 | logger.info("Test: Success before challenge") | |
5208 | return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], | |
5209 | 4 + 1 + 4 + 1, | |
5210 | EAP_TYPE_MSCHAPV2, | |
5211 | 3, 0, 5, 0) | |
5212 | ||
5213 | idx += 1 | |
5214 | if ctx['num'] == idx: | |
5215 | logger.info("Test: Failure before challenge - required challenge field not present") | |
5216 | return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], | |
5217 | 4 + 1 + 4 + 1, | |
5218 | EAP_TYPE_MSCHAPV2, | |
5219 | 4, 0, 5, 0) | |
5220 | idx += 1 | |
5221 | if ctx['num'] == idx: | |
5222 | logger.info("Test: Failure") | |
5223 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
5224 | ||
5225 | idx += 1 | |
5226 | if ctx['num'] == idx: | |
5227 | logger.info("Test: Failure before challenge - invalid failure challenge len") | |
5228 | payload = 'C=12' | |
5229 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5230 | 4 + 1 + 4 + len(payload), | |
5231 | EAP_TYPE_MSCHAPV2, | |
5232 | 4, 0, 4 + len(payload)) + payload | |
5233 | idx += 1 | |
5234 | if ctx['num'] == idx: | |
5235 | logger.info("Test: Failure") | |
5236 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
5237 | ||
5238 | idx += 1 | |
5239 | if ctx['num'] == idx: | |
5240 | logger.info("Test: Failure before challenge - invalid failure challenge len") | |
5241 | payload = 'C=12 V=3' | |
5242 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5243 | 4 + 1 + 4 + len(payload), | |
5244 | EAP_TYPE_MSCHAPV2, | |
5245 | 4, 0, 4 + len(payload)) + payload | |
5246 | idx += 1 | |
5247 | if ctx['num'] == idx: | |
5248 | logger.info("Test: Failure") | |
5249 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
5250 | ||
5251 | idx += 1 | |
5252 | if ctx['num'] == idx: | |
5253 | logger.info("Test: Failure before challenge - invalid failure challenge") | |
5254 | payload = 'C=00112233445566778899aabbccddeefQ ' | |
5255 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5256 | 4 + 1 + 4 + len(payload), | |
5257 | EAP_TYPE_MSCHAPV2, | |
5258 | 4, 0, 4 + len(payload)) + payload | |
5259 | idx += 1 | |
5260 | if ctx['num'] == idx: | |
5261 | logger.info("Test: Failure") | |
5262 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
5263 | ||
5264 | idx += 1 | |
5265 | if ctx['num'] == idx: | |
5266 | logger.info("Test: Failure before challenge - password expired") | |
5267 | payload = 'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' | |
5268 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5269 | 4 + 1 + 4 + len(payload), | |
5270 | EAP_TYPE_MSCHAPV2, | |
5271 | 4, 0, 4 + len(payload)) + payload | |
5272 | idx += 1 | |
5273 | if ctx['num'] == idx: | |
5274 | logger.info("Test: Success after password change") | |
5275 | payload = "S=1122334455667788990011223344556677889900" | |
5276 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5277 | 4 + 1 + 4 + len(payload), | |
5278 | EAP_TYPE_MSCHAPV2, | |
5279 | 3, 0, 4 + len(payload)) + payload | |
5280 | ||
5281 | idx += 1 | |
5282 | if ctx['num'] == idx: | |
5283 | logger.info("Test: Invalid challenge length") | |
5284 | return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], | |
5285 | 4 + 1 + 4 + 1, | |
5286 | EAP_TYPE_MSCHAPV2, | |
5287 | 1, 0, 4 + 1, 0) | |
5288 | ||
5289 | idx += 1 | |
5290 | if ctx['num'] == idx: | |
5291 | logger.info("Test: Too short challenge packet") | |
5292 | return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], | |
5293 | 4 + 1 + 4 + 1, | |
5294 | EAP_TYPE_MSCHAPV2, | |
5295 | 1, 0, 4 + 1, 16) | |
5296 | ||
5297 | idx += 1 | |
5298 | if ctx['num'] == idx: | |
5299 | logger.info("Test: Challenge") | |
5300 | return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], | |
5301 | 4 + 1 + 4 + 1 + 16 + 6, | |
5302 | EAP_TYPE_MSCHAPV2, | |
5303 | 1, 0, 4 + 1 + 16 + 6, 16) + 16*'A' + 'foobar' | |
5304 | idx += 1 | |
5305 | if ctx['num'] == idx: | |
5306 | logger.info("Test: Failure - password expired") | |
5307 | payload = 'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' | |
5308 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5309 | 4 + 1 + 4 + len(payload), | |
5310 | EAP_TYPE_MSCHAPV2, | |
5311 | 4, 0, 4 + len(payload)) + payload | |
5312 | idx += 1 | |
5313 | if ctx['num'] == idx: | |
5314 | logger.info("Test: Success after password change") | |
5315 | if len(req) != 591: | |
5316 | logger.info("Unexpected Change-Password packet length: %s" % len(req)) | |
5317 | return None | |
5318 | data = req[9:] | |
5319 | enc_pw = data[0:516] | |
5320 | data = data[516:] | |
5321 | enc_hash = data[0:16] | |
5322 | data = data[16:] | |
5323 | peer_challenge = data[0:16] | |
5324 | data = data[16:] | |
5325 | # Reserved | |
5326 | data = data[8:] | |
5327 | nt_response = data[0:24] | |
5328 | data = data[24:] | |
5329 | flags = data | |
5330 | logger.info("enc_hash: " + enc_hash.encode("hex")) | |
5331 | logger.info("peer_challenge: " + peer_challenge.encode("hex")) | |
5332 | logger.info("nt_response: " + nt_response.encode("hex")) | |
5333 | logger.info("flags: " + flags.encode("hex")) | |
5334 | ||
5335 | auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff") | |
5336 | logger.info("auth_challenge: " + auth_challenge.encode("hex")) | |
5337 | ||
5338 | auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response, | |
5339 | peer_challenge, | |
5340 | auth_challenge, "user") | |
5341 | payload = "S=" + auth_resp.encode('hex').upper() | |
5342 | logger.info("Success message payload: " + payload) | |
5343 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5344 | 4 + 1 + 4 + len(payload), | |
5345 | EAP_TYPE_MSCHAPV2, | |
5346 | 3, 0, 4 + len(payload)) + payload | |
5347 | idx += 1 | |
5348 | if ctx['num'] == idx: | |
5349 | logger.info("Test: EAP-Success") | |
5350 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) | |
5351 | ||
5352 | idx += 1 | |
5353 | if ctx['num'] == idx: | |
5354 | logger.info("Test: Failure - password expired") | |
5355 | payload = 'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' | |
5356 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5357 | 4 + 1 + 4 + len(payload), | |
5358 | EAP_TYPE_MSCHAPV2, | |
5359 | 4, 0, 4 + len(payload)) + payload | |
5360 | idx += 1 | |
5361 | if ctx['num'] == idx: | |
5362 | logger.info("Test: Success after password change") | |
5363 | if len(req) != 591: | |
5364 | logger.info("Unexpected Change-Password packet length: %s" % len(req)) | |
5365 | return None | |
5366 | data = req[9:] | |
5367 | enc_pw = data[0:516] | |
5368 | data = data[516:] | |
5369 | enc_hash = data[0:16] | |
5370 | data = data[16:] | |
5371 | peer_challenge = data[0:16] | |
5372 | data = data[16:] | |
5373 | # Reserved | |
5374 | data = data[8:] | |
5375 | nt_response = data[0:24] | |
5376 | data = data[24:] | |
5377 | flags = data | |
5378 | logger.info("enc_hash: " + enc_hash.encode("hex")) | |
5379 | logger.info("peer_challenge: " + peer_challenge.encode("hex")) | |
5380 | logger.info("nt_response: " + nt_response.encode("hex")) | |
5381 | logger.info("flags: " + flags.encode("hex")) | |
5382 | ||
5383 | auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff") | |
5384 | logger.info("auth_challenge: " + auth_challenge.encode("hex")) | |
5385 | ||
5386 | auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response, | |
5387 | peer_challenge, | |
5388 | auth_challenge, "user") | |
5389 | payload = "S=" + auth_resp.encode('hex').upper() | |
5390 | logger.info("Success message payload: " + payload) | |
5391 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5392 | 4 + 1 + 4 + len(payload), | |
5393 | EAP_TYPE_MSCHAPV2, | |
5394 | 3, 0, 4 + len(payload)) + payload | |
5395 | idx += 1 | |
5396 | if ctx['num'] == idx: | |
5397 | logger.info("Test: EAP-Success") | |
5398 | return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) | |
5399 | ||
5400 | idx += 1 | |
5401 | if ctx['num'] == idx: | |
5402 | logger.info("Test: Challenge") | |
5403 | return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], | |
5404 | 4 + 1 + 4 + 1 + 16 + 6, | |
5405 | EAP_TYPE_MSCHAPV2, | |
5406 | 1, 0, 4 + 1 + 16 + 6, 16) + 16*'A' + 'foobar' | |
5407 | idx += 1 | |
5408 | if ctx['num'] == idx: | |
5409 | logger.info("Test: Failure - authentication failure") | |
5410 | payload = 'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed' | |
5411 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5412 | 4 + 1 + 4 + len(payload), | |
5413 | EAP_TYPE_MSCHAPV2, | |
5414 | 4, 0, 4 + len(payload)) + payload | |
5415 | ||
5416 | idx += 1 | |
5417 | if ctx['num'] == idx: | |
5418 | logger.info("Test: Challenge") | |
5419 | return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], | |
5420 | 4 + 1 + 4 + 1 + 16 + 6, | |
5421 | EAP_TYPE_MSCHAPV2, | |
5422 | 1, 0, 4 + 1 + 16 + 6, 16) + 16*'A' + 'foobar' | |
5423 | idx += 1 | |
5424 | if ctx['num'] == idx: | |
5425 | logger.info("Test: Failure - authentication failure") | |
5426 | payload = 'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed (2)' | |
5427 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5428 | 4 + 1 + 4 + len(payload), | |
5429 | EAP_TYPE_MSCHAPV2, | |
5430 | 4, 0, 4 + len(payload)) + payload | |
5431 | idx += 1 | |
5432 | if ctx['num'] == idx: | |
5433 | logger.info("Test: Failure") | |
5434 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
5435 | ||
5436 | return None | |
5437 | ||
5438 | srv = start_radius_server(mschapv2_handler) | |
5439 | ||
5440 | try: | |
5441 | hapd = start_ap(apdev[0]['ifname']) | |
5442 | ||
5443 | for i in range(0, 15): | |
5444 | logger.info("RUN: %d" % i) | |
5445 | if i == 12: | |
5446 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5447 | eap="MSCHAPV2", identity="user", | |
5448 | password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", | |
5449 | wait_connect=False) | |
5450 | elif i == 14: | |
5451 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5452 | eap="MSCHAPV2", identity="user", | |
5453 | phase2="mschapv2_retry=0", | |
5454 | password="password", wait_connect=False) | |
5455 | else: | |
5456 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5457 | eap="MSCHAPV2", identity="user", | |
5458 | password="password", wait_connect=False) | |
5459 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) | |
5460 | if ev is None: | |
5461 | raise Exception("Timeout on EAP start") | |
5462 | ||
5463 | if i in [ 8, 11, 12 ]: | |
5464 | ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], | |
5465 | timeout=10) | |
5466 | if ev is None: | |
5467 | raise Exception("Timeout on new password request") | |
5468 | id = ev.split(':')[0].split('-')[-1] | |
5469 | dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw") | |
5470 | if i in [ 11, 12 ]: | |
5471 | ev = dev[0].wait_event(["CTRL-EVENT-PASSWORD-CHANGED"], | |
5472 | timeout=10) | |
5473 | if ev is None: | |
5474 | raise Exception("Timeout on password change") | |
5475 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], | |
5476 | timeout=10) | |
5477 | if ev is None: | |
5478 | raise Exception("Timeout on EAP success") | |
5479 | else: | |
5480 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], | |
5481 | timeout=10) | |
5482 | if ev is None: | |
5483 | raise Exception("Timeout on EAP failure") | |
5484 | ||
5485 | if i in [ 13 ]: | |
5486 | ev = dev[0].wait_event(["CTRL-REQ-IDENTITY"], | |
5487 | timeout=10) | |
5488 | if ev is None: | |
5489 | raise Exception("Timeout on identity request") | |
5490 | id = ev.split(':')[0].split('-')[-1] | |
5491 | dev[0].request("CTRL-RSP-IDENTITY-" + id + ":user") | |
5492 | ||
5493 | ev = dev[0].wait_event(["CTRL-REQ-PASSWORD"], | |
5494 | timeout=10) | |
5495 | if ev is None: | |
5496 | raise Exception("Timeout on password request") | |
5497 | id = ev.split(':')[0].split('-')[-1] | |
5498 | dev[0].request("CTRL-RSP-PASSWORD-" + id + ":password") | |
5499 | ||
5500 | # TODO: Does this work correctly? | |
5501 | ||
5502 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], | |
5503 | timeout=10) | |
5504 | if ev is None: | |
5505 | raise Exception("Timeout on EAP failure") | |
5506 | ||
5507 | if i in [ 4, 5, 6, 7, 14 ]: | |
5508 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], | |
5509 | timeout=10) | |
5510 | if ev is None: | |
5511 | raise Exception("Timeout on EAP failure") | |
5512 | else: | |
5513 | time.sleep(0.05) | |
5514 | dev[0].request("REMOVE_NETWORK all") | |
5515 | dev[0].wait_disconnected(timeout=1) | |
5516 | finally: | |
5517 | stop_radius_server(srv) | |
7c0d66cf JM |
5518 | |
5519 | def test_eap_proto_mschapv2_errors(dev, apdev): | |
5520 | """EAP-MSCHAPv2 protocol tests (error paths)""" | |
5521 | check_eap_capa(dev[0], "MSCHAPV2") | |
5522 | ||
5523 | def mschapv2_handler(ctx, req): | |
5524 | logger.info("mschapv2_handler - RX " + req.encode("hex")) | |
5525 | if 'num' not in ctx: | |
5526 | ctx['num'] = 0 | |
5527 | ctx['num'] = ctx['num'] + 1 | |
5528 | if 'id' not in ctx: | |
5529 | ctx['id'] = 1 | |
5530 | ctx['id'] = (ctx['id'] + 1) % 256 | |
5531 | idx = 0 | |
5532 | ||
5533 | idx += 1 | |
5534 | if ctx['num'] == idx: | |
5535 | logger.info("Test: Failure before challenge - password expired") | |
5536 | payload = 'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' | |
5537 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5538 | 4 + 1 + 4 + len(payload), | |
5539 | EAP_TYPE_MSCHAPV2, | |
5540 | 4, 0, 4 + len(payload)) + payload | |
5541 | idx += 1 | |
5542 | if ctx['num'] == idx: | |
5543 | logger.info("Test: Success after password change") | |
5544 | payload = "S=1122334455667788990011223344556677889900" | |
5545 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5546 | 4 + 1 + 4 + len(payload), | |
5547 | EAP_TYPE_MSCHAPV2, | |
5548 | 3, 0, 4 + len(payload)) + payload | |
5549 | ||
5550 | idx += 1 | |
5551 | if ctx['num'] == idx: | |
5552 | logger.info("Test: Failure before challenge - password expired") | |
5553 | payload = 'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' | |
5554 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5555 | 4 + 1 + 4 + len(payload), | |
5556 | EAP_TYPE_MSCHAPV2, | |
5557 | 4, 0, 4 + len(payload)) + payload | |
5558 | idx += 1 | |
5559 | if ctx['num'] == idx: | |
5560 | logger.info("Test: Success after password change") | |
5561 | payload = "S=1122334455667788990011223344556677889900" | |
5562 | return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], | |
5563 | 4 + 1 + 4 + len(payload), | |
5564 | EAP_TYPE_MSCHAPV2, | |
5565 | 3, 0, 4 + len(payload)) + payload | |
5566 | ||
5567 | return None | |
5568 | ||
5569 | srv = start_radius_server(mschapv2_handler) | |
5570 | ||
5571 | try: | |
5572 | hapd = start_ap(apdev[0]['ifname']) | |
5573 | ||
5574 | with fail_test(dev[0], 1, "eap_mschapv2_change_password"): | |
5575 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5576 | eap="MSCHAPV2", identity="user", | |
5577 | password="password", wait_connect=False) | |
5578 | ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10) | |
5579 | if ev is None: | |
5580 | raise Exception("Timeout on new password request") | |
5581 | id = ev.split(':')[0].split('-')[-1] | |
5582 | dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw") | |
5583 | wait_fail_trigger(dev[0], "GET_FAIL") | |
5584 | dev[0].request("REMOVE_NETWORK all") | |
5585 | dev[0].wait_disconnected(timeout=1) | |
5586 | ||
5587 | with fail_test(dev[0], 1, "get_master_key;eap_mschapv2_change_password"): | |
5588 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5589 | eap="MSCHAPV2", identity="user", | |
5590 | password="password", wait_connect=False) | |
5591 | ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10) | |
5592 | if ev is None: | |
5593 | raise Exception("Timeout on new password request") | |
5594 | id = ev.split(':')[0].split('-')[-1] | |
5595 | dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw") | |
5596 | wait_fail_trigger(dev[0], "GET_FAIL") | |
5597 | dev[0].request("REMOVE_NETWORK all") | |
5598 | dev[0].wait_disconnected(timeout=1) | |
5599 | finally: | |
5600 | stop_radius_server(srv) | |
8a848fae JM |
5601 | |
5602 | def test_eap_proto_pwd(dev, apdev): | |
5603 | """EAP-pwd protocol tests""" | |
5604 | check_eap_capa(dev[0], "PWD") | |
5605 | ||
5606 | global eap_proto_pwd_test_done, eap_proto_pwd_test_wait | |
5607 | eap_proto_pwd_test_done = False | |
5608 | eap_proto_pwd_test_wait = False | |
5609 | ||
5610 | def pwd_handler(ctx, req): | |
5611 | logger.info("pwd_handler - RX " + req.encode("hex")) | |
5612 | if 'num' not in ctx: | |
5613 | ctx['num'] = 0 | |
5614 | ctx['num'] = ctx['num'] + 1 | |
5615 | if 'id' not in ctx: | |
5616 | ctx['id'] = 1 | |
5617 | ctx['id'] = (ctx['id'] + 1) % 256 | |
5618 | idx = 0 | |
5619 | ||
5620 | global eap_proto_pwd_test_wait | |
5621 | eap_proto_pwd_test_wait = False | |
5622 | ||
5623 | idx += 1 | |
5624 | if ctx['num'] == idx: | |
5625 | logger.info("Test: Missing payload") | |
5626 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1, | |
5627 | EAP_TYPE_PWD) | |
5628 | ||
5629 | idx += 1 | |
5630 | if ctx['num'] == idx: | |
5631 | logger.info("Test: Missing Total-Length field") | |
5632 | payload = struct.pack("B", 0x80) | |
5633 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5634 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5635 | ||
5636 | idx += 1 | |
5637 | if ctx['num'] == idx: | |
5638 | logger.info("Test: Too large Total-Length") | |
5639 | payload = struct.pack(">BH", 0x80, 65535) | |
5640 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5641 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5642 | ||
5643 | idx += 1 | |
5644 | if ctx['num'] == idx: | |
5645 | eap_proto_pwd_test_wait = True | |
5646 | logger.info("Test: First fragment") | |
5647 | payload = struct.pack(">BH", 0xc0, 10) | |
5648 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5649 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5650 | idx += 1 | |
5651 | if ctx['num'] == idx: | |
5652 | logger.info("Test: Unexpected Total-Length value in the second fragment") | |
5653 | payload = struct.pack(">BH", 0x80, 0) | |
5654 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5655 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5656 | ||
5657 | idx += 1 | |
5658 | if ctx['num'] == idx: | |
5659 | logger.info("Test: First and only fragment") | |
5660 | payload = struct.pack(">BH", 0x80, 0) | |
5661 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5662 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5663 | ||
5664 | idx += 1 | |
5665 | if ctx['num'] == idx: | |
5666 | logger.info("Test: First and only fragment with extra data") | |
5667 | payload = struct.pack(">BHB", 0x80, 0, 0) | |
5668 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5669 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5670 | ||
5671 | idx += 1 | |
5672 | if ctx['num'] == idx: | |
5673 | eap_proto_pwd_test_wait = True | |
5674 | logger.info("Test: First fragment") | |
5675 | payload = struct.pack(">BHB", 0xc0, 2, 1) | |
5676 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5677 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5678 | idx += 1 | |
5679 | if ctx['num'] == idx: | |
5680 | logger.info("Test: Extra data in the second fragment") | |
5681 | payload = struct.pack(">BBB", 0x0, 2, 3) | |
5682 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5683 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5684 | ||
5685 | idx += 1 | |
5686 | if ctx['num'] == idx: | |
5687 | logger.info("Test: Too short id exchange") | |
5688 | payload = struct.pack(">B", 0x01) | |
5689 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5690 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5691 | ||
5692 | idx += 1 | |
5693 | if ctx['num'] == idx: | |
5694 | logger.info("Test: Unsupported rand func in id exchange") | |
5695 | payload = struct.pack(">BHBBLB", 0x01, 0, 0, 0, 0, 0) | |
5696 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5697 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5698 | ||
5699 | idx += 1 | |
5700 | if ctx['num'] == idx: | |
5701 | logger.info("Test: Unsupported prf in id exchange") | |
5702 | payload = struct.pack(">BHBBLB", 0x01, 19, 1, 0, 0, 0) | |
5703 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5704 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5705 | ||
5706 | idx += 1 | |
5707 | if ctx['num'] == idx: | |
5708 | logger.info("Test: Unsupported password pre-processing technique in id exchange") | |
5709 | payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 255) | |
5710 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5711 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5712 | ||
5713 | idx += 1 | |
5714 | if ctx['num'] == idx: | |
5715 | eap_proto_pwd_test_wait = True | |
5716 | logger.info("Test: Valid id exchange") | |
5717 | payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) | |
5718 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5719 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5720 | idx += 1 | |
5721 | if ctx['num'] == idx: | |
5722 | logger.info("Test: Unexpected id exchange") | |
5723 | payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) | |
5724 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5725 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5726 | ||
5727 | idx += 1 | |
5728 | if ctx['num'] == idx: | |
5729 | logger.info("Test: Unexpected commit exchange") | |
5730 | payload = struct.pack(">B", 0x02) | |
5731 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5732 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5733 | ||
5734 | idx += 1 | |
5735 | if ctx['num'] == idx: | |
5736 | eap_proto_pwd_test_wait = True | |
5737 | logger.info("Test: Valid id exchange") | |
5738 | payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) | |
5739 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5740 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5741 | idx += 1 | |
5742 | if ctx['num'] == idx: | |
5743 | logger.info("Test: Unexpected Commit payload length") | |
5744 | payload = struct.pack(">B", 0x02) | |
5745 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5746 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5747 | ||
5748 | idx += 1 | |
5749 | if ctx['num'] == idx: | |
5750 | eap_proto_pwd_test_wait = True | |
5751 | logger.info("Test: Valid id exchange") | |
5752 | payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) | |
5753 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5754 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5755 | idx += 1 | |
5756 | if ctx['num'] == idx: | |
5757 | logger.info("Test: Commit payload with all zeros values --> Shared key at infinity") | |
5758 | payload = struct.pack(">B", 0x02) + 96*'\0' | |
5759 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5760 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5761 | ||
5762 | idx += 1 | |
5763 | if ctx['num'] == idx: | |
5764 | eap_proto_pwd_test_wait = True | |
5765 | logger.info("Test: Valid id exchange") | |
5766 | payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) | |
5767 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5768 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5769 | idx += 1 | |
5770 | if ctx['num'] == idx: | |
5771 | eap_proto_pwd_test_wait = True | |
5772 | logger.info("Test: Commit payload with valid values") | |
5773 | element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f") | |
5774 | scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd") | |
5775 | payload = struct.pack(">B", 0x02) + element + scalar | |
5776 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5777 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5778 | idx += 1 | |
5779 | if ctx['num'] == idx: | |
5780 | logger.info("Test: Unexpected Confirm payload length 0") | |
5781 | payload = struct.pack(">B", 0x03) | |
5782 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5783 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5784 | ||
5785 | idx += 1 | |
5786 | if ctx['num'] == idx: | |
5787 | eap_proto_pwd_test_wait = True | |
5788 | logger.info("Test: Valid id exchange") | |
5789 | payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) | |
5790 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5791 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5792 | idx += 1 | |
5793 | if ctx['num'] == idx: | |
5794 | eap_proto_pwd_test_wait = True | |
5795 | logger.info("Test: Commit payload with valid values") | |
5796 | element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f") | |
5797 | scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd") | |
5798 | payload = struct.pack(">B", 0x02) + element + scalar | |
5799 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5800 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5801 | idx += 1 | |
5802 | if ctx['num'] == idx: | |
5803 | logger.info("Test: Confirm payload with incorrect value") | |
5804 | payload = struct.pack(">B", 0x03) + 32*'\0' | |
5805 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5806 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5807 | ||
5808 | idx += 1 | |
5809 | if ctx['num'] == idx: | |
5810 | logger.info("Test: Unexpected confirm exchange") | |
5811 | payload = struct.pack(">B", 0x03) | |
5812 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
5813 | 4 + 1 + len(payload), EAP_TYPE_PWD) + payload | |
5814 | ||
5815 | logger.info("No more test responses available - test case completed") | |
5816 | global eap_proto_pwd_test_done | |
5817 | eap_proto_pwd_test_done = True | |
5818 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
5819 | ||
5820 | srv = start_radius_server(pwd_handler) | |
5821 | ||
5822 | try: | |
5823 | hapd = start_ap(apdev[0]['ifname']) | |
5824 | ||
5825 | i = 0 | |
5826 | while not eap_proto_pwd_test_done: | |
5827 | i += 1 | |
5828 | logger.info("Running connection iteration %d" % i) | |
5829 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5830 | eap="PWD", identity="pwd user", | |
5831 | password="secret password", | |
5832 | wait_connect=False) | |
5833 | ok = False | |
5834 | for j in range(5): | |
5835 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STATUS", | |
5836 | "CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
5837 | timeout=5) | |
5838 | if ev is None: | |
5839 | raise Exception("Timeout on EAP start") | |
5840 | if "CTRL-EVENT-EAP-PROPOSED-METHOD" in ev: | |
5841 | ok = True | |
5842 | break | |
5843 | if "CTRL-EVENT-EAP-STATUS" in ev and "status='completion' parameter='failure'" in ev: | |
5844 | ok = True | |
5845 | break | |
5846 | if not ok: | |
5847 | raise Exception("Expected EAP event not seen") | |
5848 | if eap_proto_pwd_test_wait: | |
5849 | for k in range(10): | |
5850 | time.sleep(0.1) | |
5851 | if not eap_proto_pwd_test_wait: | |
5852 | break | |
5853 | dev[0].request("REMOVE_NETWORK all") | |
5854 | dev[0].wait_disconnected(timeout=1) | |
5855 | dev[0].dump_monitor() | |
5856 | finally: | |
5857 | stop_radius_server(srv) | |
fe5aa8cb JM |
5858 | |
5859 | def test_eap_proto_pwd_errors(dev, apdev): | |
5860 | """EAP-pwd local error cases""" | |
5861 | check_eap_capa(dev[0], "PWD") | |
5862 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
5863 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
5864 | ||
5865 | for i in range(1, 4): | |
5866 | with alloc_fail(dev[0], i, "eap_pwd_init"): | |
5867 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5868 | eap="PWD", identity="pwd user", | |
5869 | password="secret password", | |
5870 | wait_connect=False) | |
5871 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
5872 | timeout=15) | |
5873 | if ev is None: | |
5874 | raise Exception("Timeout on EAP start") | |
5875 | dev[0].request("REMOVE_NETWORK all") | |
5876 | dev[0].wait_disconnected() | |
5877 | ||
5878 | with alloc_fail(dev[0], 1, "eap_pwd_get_session_id"): | |
5879 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5880 | eap="PWD", identity="pwd user", | |
5881 | password="secret password") | |
5882 | dev[0].request("REMOVE_NETWORK all") | |
5883 | dev[0].wait_disconnected() | |
5884 | ||
5885 | for i in range(1, 7): | |
5886 | with alloc_fail(dev[0], i, "eap_pwd_perform_id_exchange"): | |
5887 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5888 | eap="PWD", identity="pwd user", | |
5889 | password="secret password", | |
5890 | wait_connect=False) | |
5891 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
5892 | timeout=15) | |
5893 | if ev is None: | |
5894 | raise Exception("Timeout on EAP start") | |
5895 | ok = False | |
5896 | for j in range(10): | |
5897 | state = dev[0].request('GET_ALLOC_FAIL') | |
5898 | if state.startswith('0:'): | |
5899 | ok = True | |
5900 | break | |
5901 | time.sleep(0.1) | |
5902 | if not ok: | |
5903 | raise Exception("No allocation failure seen") | |
5904 | dev[0].request("REMOVE_NETWORK all") | |
5905 | dev[0].wait_disconnected() | |
5906 | ||
5907 | with alloc_fail(dev[0], 1, "wpabuf_alloc;eap_pwd_perform_id_exchange"): | |
5908 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5909 | eap="PWD", identity="pwd user", | |
5910 | password="secret password", | |
5911 | wait_connect=False) | |
5912 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
5913 | timeout=15) | |
5914 | if ev is None: | |
5915 | raise Exception("Timeout on EAP start") | |
5916 | dev[0].request("REMOVE_NETWORK all") | |
5917 | dev[0].wait_disconnected() | |
5918 | ||
5919 | for i in range(1, 4): | |
5920 | with alloc_fail(dev[0], i, "eap_pwd_perform_commit_exchange"): | |
5921 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5922 | eap="PWD", identity="pwd user", | |
5923 | password="secret password", | |
5924 | wait_connect=False) | |
5925 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
5926 | timeout=15) | |
5927 | if ev is None: | |
5928 | raise Exception("Timeout on EAP start") | |
5929 | ok = False | |
5930 | for j in range(10): | |
5931 | state = dev[0].request('GET_ALLOC_FAIL') | |
5932 | if state.startswith('0:'): | |
5933 | ok = True | |
5934 | break | |
5935 | time.sleep(0.1) | |
5936 | if not ok: | |
5937 | raise Exception("No allocation failure seen") | |
5938 | dev[0].request("REMOVE_NETWORK all") | |
5939 | dev[0].wait_disconnected() | |
5940 | ||
5941 | for i in range(1, 12): | |
5942 | with alloc_fail(dev[0], i, "eap_pwd_perform_confirm_exchange"): | |
5943 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5944 | eap="PWD", identity="pwd user", | |
5945 | password="secret password", | |
5946 | wait_connect=False) | |
5947 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
5948 | timeout=15) | |
5949 | if ev is None: | |
5950 | raise Exception("Timeout on EAP start") | |
5951 | ok = False | |
5952 | for j in range(10): | |
5953 | state = dev[0].request('GET_ALLOC_FAIL') | |
5954 | if state.startswith('0:'): | |
5955 | ok = True | |
5956 | break | |
5957 | time.sleep(0.1) | |
5958 | if not ok: | |
5959 | raise Exception("No allocation failure seen") | |
5960 | dev[0].request("REMOVE_NETWORK all") | |
5961 | dev[0].wait_disconnected() | |
5962 | ||
5963 | for i in range(1, 4): | |
5964 | with alloc_fail(dev[0], i, "eap_msg_alloc;=eap_pwd_process"): | |
5965 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5966 | eap="PWD", identity="pwd user", | |
5967 | password="secret password", | |
5968 | wait_connect=False) | |
5969 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
5970 | timeout=15) | |
5971 | if ev is None: | |
5972 | raise Exception("Timeout on EAP start") | |
5973 | ok = False | |
5974 | for j in range(10): | |
5975 | state = dev[0].request('GET_ALLOC_FAIL') | |
5976 | if state.startswith('0:'): | |
5977 | ok = True | |
5978 | break | |
5979 | time.sleep(0.1) | |
5980 | if not ok: | |
5981 | raise Exception("No allocation failure seen") | |
5982 | dev[0].request("REMOVE_NETWORK all") | |
5983 | dev[0].wait_disconnected() | |
5984 | ||
5985 | # No password configured | |
5986 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
5987 | eap="PWD", identity="pwd user", | |
5988 | wait_connect=False) | |
5989 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=52"], | |
5990 | timeout=15) | |
5991 | if ev is None: | |
5992 | raise Exception("EAP-pwd not started") | |
5993 | dev[0].request("REMOVE_NETWORK all") | |
5994 | dev[0].wait_disconnected() | |
b6f17f2f JM |
5995 | |
5996 | def test_eap_proto_erp(dev, apdev): | |
5997 | """ERP protocol tests""" | |
5998 | check_erp_capa(dev[0]) | |
5999 | ||
6000 | global eap_proto_erp_test_done | |
6001 | eap_proto_erp_test_done = False | |
6002 | ||
6003 | def erp_handler(ctx, req): | |
6004 | logger.info("erp_handler - RX " + req.encode("hex")) | |
6005 | if 'num' not in ctx: | |
6006 | ctx['num'] = 0 | |
6007 | ctx['num'] += 1 | |
6008 | if 'id' not in ctx: | |
6009 | ctx['id'] = 1 | |
6010 | ctx['id'] = (ctx['id'] + 1) % 256 | |
6011 | idx = 0 | |
6012 | ||
6013 | idx += 1 | |
6014 | if ctx['num'] == idx: | |
6015 | logger.info("Test: Missing type") | |
6016 | return struct.pack(">BBH", EAP_CODE_INITIATE, ctx['id'], 4) | |
6017 | ||
6018 | idx += 1 | |
6019 | if ctx['num'] == idx: | |
6020 | logger.info("Test: Unexpected type") | |
6021 | return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1, | |
6022 | 255) | |
6023 | ||
6024 | idx += 1 | |
6025 | if ctx['num'] == idx: | |
6026 | logger.info("Test: Missing Reserved field") | |
6027 | return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1, | |
6028 | EAP_ERP_TYPE_REAUTH_START) | |
6029 | ||
6030 | idx += 1 | |
6031 | if ctx['num'] == idx: | |
6032 | logger.info("Test: Zero-length TVs/TLVs") | |
6033 | payload = "" | |
6034 | return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], | |
6035 | 4 + 1 + 1 + len(payload), | |
6036 | EAP_ERP_TYPE_REAUTH_START, 0) + payload | |
6037 | ||
6038 | idx += 1 | |
6039 | if ctx['num'] == idx: | |
6040 | logger.info("Test: Too short TLV") | |
6041 | payload = struct.pack("B", 191) | |
6042 | return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], | |
6043 | 4 + 1 + 1 + len(payload), | |
6044 | EAP_ERP_TYPE_REAUTH_START, 0) + payload | |
6045 | ||
6046 | idx += 1 | |
6047 | if ctx['num'] == idx: | |
6048 | logger.info("Test: Truncated TLV") | |
6049 | payload = struct.pack("BB", 191, 1) | |
6050 | return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], | |
6051 | 4 + 1 + 1 + len(payload), | |
6052 | EAP_ERP_TYPE_REAUTH_START, 0) + payload | |
6053 | ||
6054 | idx += 1 | |
6055 | if ctx['num'] == idx: | |
6056 | logger.info("Test: Ignored unknown TLV and unknown TV/TLV terminating parsing") | |
6057 | payload = struct.pack("BBB", 191, 0, 192) | |
6058 | return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], | |
6059 | 4 + 1 + 1 + len(payload), | |
6060 | EAP_ERP_TYPE_REAUTH_START, 0) + payload | |
6061 | ||
6062 | idx += 1 | |
6063 | if ctx['num'] == idx: | |
6064 | logger.info("Test: More than one keyName-NAI") | |
6065 | payload = struct.pack("BBBB", EAP_ERP_TLV_KEYNAME_NAI, 0, | |
6066 | EAP_ERP_TLV_KEYNAME_NAI, 0) | |
6067 | return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], | |
6068 | 4 + 1 + 1 + len(payload), | |
6069 | EAP_ERP_TYPE_REAUTH_START, 0) + payload | |
6070 | ||
6071 | idx += 1 | |
6072 | if ctx['num'] == idx: | |
6073 | logger.info("Test: Too short TLV keyName-NAI") | |
6074 | payload = struct.pack("B", EAP_ERP_TLV_KEYNAME_NAI) | |
6075 | return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], | |
6076 | 4 + 1 + 1 + len(payload), | |
6077 | EAP_ERP_TYPE_REAUTH_START, 0) + payload | |
6078 | ||
6079 | idx += 1 | |
6080 | if ctx['num'] == idx: | |
6081 | logger.info("Test: Truncated TLV keyName-NAI") | |
6082 | payload = struct.pack("BB", EAP_ERP_TLV_KEYNAME_NAI, 1) | |
6083 | return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], | |
6084 | 4 + 1 + 1 + len(payload), | |
6085 | EAP_ERP_TYPE_REAUTH_START, 0) + payload | |
6086 | ||
6087 | idx += 1 | |
6088 | if ctx['num'] == idx: | |
6089 | logger.info("Test: Valid rRK lifetime TV followed by too short rMSK lifetime TV") | |
6090 | payload = struct.pack(">BLBH", EAP_ERP_TV_RRK_LIFETIME, 0, | |
6091 | EAP_ERP_TV_RMSK_LIFETIME, 0) | |
6092 | return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], | |
6093 | 4 + 1 + 1 + len(payload), | |
6094 | EAP_ERP_TYPE_REAUTH_START, 0) + payload | |
6095 | ||
6096 | idx += 1 | |
6097 | if ctx['num'] == idx: | |
6098 | logger.info("Test: Missing type (Finish)") | |
6099 | return struct.pack(">BBH", EAP_CODE_FINISH, ctx['id'], 4) | |
6100 | ||
6101 | idx += 1 | |
6102 | if ctx['num'] == idx: | |
6103 | logger.info("Test: Unexpected type (Finish)") | |
6104 | return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1, | |
6105 | 255) | |
6106 | ||
6107 | idx += 1 | |
6108 | if ctx['num'] == idx: | |
6109 | logger.info("Test: Missing fields (Finish)") | |
6110 | return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1, | |
6111 | EAP_ERP_TYPE_REAUTH) | |
6112 | ||
6113 | idx += 1 | |
6114 | if ctx['num'] == idx: | |
6115 | logger.info("Test: Unexpected SEQ (Finish)") | |
6116 | return struct.pack(">BBHBBHB", EAP_CODE_FINISH, ctx['id'], | |
6117 | 4 + 1 + 4, | |
6118 | EAP_ERP_TYPE_REAUTH, 0, 0xffff, 0) | |
6119 | ||
6120 | logger.info("No more test responses available - test case completed") | |
6121 | global eap_proto_erp_test_done | |
6122 | eap_proto_erp_test_done = True | |
6123 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6124 | ||
6125 | srv = start_radius_server(erp_handler) | |
6126 | ||
6127 | try: | |
6128 | hapd = start_ap(apdev[0]['ifname']) | |
6129 | ||
6130 | i = 0 | |
6131 | while not eap_proto_erp_test_done: | |
6132 | i += 1 | |
6133 | logger.info("Running connection iteration %d" % i) | |
6134 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6135 | eap="PAX", identity="pax.user@example.com", | |
6136 | password_hex="0123456789abcdef0123456789abcdef", | |
6137 | wait_connect=False) | |
6138 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) | |
6139 | if ev is None: | |
6140 | raise Exception("Timeout on EAP start") | |
6141 | time.sleep(0.1) | |
6142 | dev[0].request("REMOVE_NETWORK all") | |
6143 | dev[0].wait_disconnected(timeout=1) | |
6144 | dev[0].dump_monitor() | |
6145 | finally: | |
6146 | stop_radius_server(srv) | |
5b7784a8 JM |
6147 | |
6148 | def test_eap_proto_fast_errors(dev, apdev): | |
6149 | """EAP-FAST local error cases""" | |
6150 | check_eap_capa(dev[0], "FAST") | |
6151 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
6152 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
6153 | ||
6154 | for i in range(1, 5): | |
6155 | with alloc_fail(dev[0], i, "eap_fast_init"): | |
6156 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6157 | eap="FAST", anonymous_identity="FAST", | |
6158 | identity="user", password="password", | |
6159 | ca_cert="auth_serv/ca.pem", phase2="auth=GTC", | |
6160 | phase1="fast_provisioning=2", | |
6161 | pac_file="blob://fast_pac_auth", | |
6162 | wait_connect=False) | |
6163 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
6164 | timeout=5) | |
6165 | if ev is None: | |
6166 | raise Exception("Timeout on EAP start") | |
6167 | dev[0].request("REMOVE_NETWORK all") | |
6168 | dev[0].wait_disconnected() | |
6169 | ||
6170 | tests = [ (1, "wpabuf_alloc;eap_fast_tlv_eap_payload"), | |
6171 | (1, "eap_fast_derive_key;eap_fast_derive_key_auth"), | |
6172 | (1, "eap_msg_alloc;eap_peer_tls_phase2_nak"), | |
6173 | (1, "wpabuf_alloc;eap_fast_tlv_result"), | |
6174 | (1, "wpabuf_alloc;eap_fast_tlv_pac_ack"), | |
6175 | (1, "=eap_peer_tls_derive_session_id;eap_fast_process_crypto_binding"), | |
6176 | (1, "eap_peer_tls_decrypt;eap_fast_decrypt"), | |
6177 | (1, "eap_fast_getKey"), | |
6178 | (1, "eap_fast_get_session_id"), | |
6179 | (1, "eap_fast_get_emsk") ] | |
6180 | for count, func in tests: | |
6181 | dev[0].request("SET blob fast_pac_auth_errors ") | |
6182 | with alloc_fail(dev[0], count, func): | |
6183 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6184 | eap="FAST", anonymous_identity="FAST", | |
6185 | identity="user", password="password", | |
6186 | ca_cert="auth_serv/ca.pem", phase2="auth=GTC", | |
6187 | phase1="fast_provisioning=2", | |
6188 | pac_file="blob://fast_pac_auth_errors", | |
6189 | erp="1", | |
6190 | wait_connect=False) | |
6191 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
6192 | timeout=15) | |
6193 | if ev is None: | |
6194 | raise Exception("Timeout on EAP start") | |
6195 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
6196 | dev[0].request("REMOVE_NETWORK all") | |
6197 | dev[0].wait_disconnected() | |
6198 | ||
6199 | tests = [ (1, "eap_fast_derive_key;eap_fast_derive_key_provisioning"), | |
6200 | (1, "eap_mschapv2_getKey;eap_fast_get_phase2_key"), | |
6201 | (1, "=eap_fast_use_pac_opaque"), | |
6202 | (1, "eap_fast_copy_buf"), | |
6203 | (1, "=eap_fast_add_pac"), | |
6204 | (1, "=eap_fast_init_pac_data"), | |
6205 | (1, "=eap_fast_write_pac"), | |
6206 | (2, "=eap_fast_write_pac") ] | |
6207 | for count, func in tests: | |
6208 | dev[0].request("SET blob fast_pac_errors ") | |
6209 | with alloc_fail(dev[0], count, func): | |
6210 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6211 | eap="FAST", anonymous_identity="FAST", | |
6212 | identity="user", password="password", | |
6213 | ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", | |
6214 | phase1="fast_provisioning=1", | |
6215 | pac_file="blob://fast_pac_errors", | |
6216 | erp="1", | |
6217 | wait_connect=False) | |
6218 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
6219 | timeout=15) | |
6220 | if ev is None: | |
6221 | raise Exception("Timeout on EAP start") | |
6222 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
6223 | dev[0].request("REMOVE_NETWORK all") | |
6224 | dev[0].wait_disconnected() | |
6225 | ||
6226 | tests = [ (1, "eap_fast_get_cmk;eap_fast_process_crypto_binding"), | |
6227 | (1, "eap_fast_derive_eap_msk;eap_fast_process_crypto_binding"), | |
6228 | (1, "eap_fast_derive_eap_emsk;eap_fast_process_crypto_binding") ] | |
6229 | for count, func in tests: | |
6230 | dev[0].request("SET blob fast_pac_auth_errors ") | |
6231 | with fail_test(dev[0], count, func): | |
6232 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6233 | eap="FAST", anonymous_identity="FAST", | |
6234 | identity="user", password="password", | |
6235 | ca_cert="auth_serv/ca.pem", phase2="auth=GTC", | |
6236 | phase1="fast_provisioning=2", | |
6237 | pac_file="blob://fast_pac_auth_errors", | |
6238 | erp="1", | |
6239 | wait_connect=False) | |
6240 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
6241 | timeout=15) | |
6242 | if ev is None: | |
6243 | raise Exception("Timeout on EAP start") | |
6244 | wait_fail_trigger(dev[0], "GET_FAIL") | |
6245 | dev[0].request("REMOVE_NETWORK all") | |
6246 | dev[0].wait_disconnected() | |
6247 | ||
6248 | dev[0].request("SET blob fast_pac_errors ") | |
6249 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6250 | eap="FAST", anonymous_identity="FAST", | |
6251 | identity="user", password="password", | |
6252 | ca_cert="auth_serv/ca.pem", phase2="auth=GTC", | |
6253 | phase1="fast_provisioning=1", | |
6254 | pac_file="blob://fast_pac_errors", | |
6255 | wait_connect=False) | |
6256 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) | |
6257 | if ev is None: | |
6258 | raise Exception("Timeout on EAP start") | |
6259 | # EAP-FAST: Only EAP-MSCHAPv2 is allowed during unauthenticated | |
6260 | # provisioning; reject phase2 type 6 | |
6261 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) | |
6262 | if ev is None: | |
6263 | raise Exception("Timeout on EAP failure") | |
6264 | dev[0].request("REMOVE_NETWORK all") | |
6265 | dev[0].wait_disconnected() | |
6266 | ||
6267 | logger.info("Wrong password in Phase 2") | |
6268 | dev[0].request("SET blob fast_pac_errors ") | |
6269 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6270 | eap="FAST", anonymous_identity="FAST", | |
6271 | identity="user", password="wrong password", | |
6272 | ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", | |
6273 | phase1="fast_provisioning=1", | |
6274 | pac_file="blob://fast_pac_errors", | |
6275 | wait_connect=False) | |
6276 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) | |
6277 | if ev is None: | |
6278 | raise Exception("Timeout on EAP start") | |
6279 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) | |
6280 | if ev is None: | |
6281 | raise Exception("Timeout on EAP failure") | |
6282 | dev[0].request("REMOVE_NETWORK all") | |
6283 | dev[0].wait_disconnected() | |
6284 | ||
6285 | tests = [ "FOOBAR\n", | |
6286 | "wpa_supplicant EAP-FAST PAC file - version 1\nFOOBAR\n", | |
6287 | "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\n", | |
6288 | "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nSTART\n", | |
6289 | "wpa_supplicant EAP-FAST PAC file - version 1\nEND\n", | |
6290 | "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Type=12345\nEND\n" | |
6291 | "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=12\nEND\n", | |
6292 | "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1\nEND\n", | |
6293 | "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1q\nEND\n", | |
6294 | "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Opaque=1\nEND\n", | |
6295 | "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID=1\nEND\n", | |
6296 | "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nI-ID=1\nEND\n", | |
6297 | "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID-Info=1\nEND\n" ] | |
6298 | for pac in tests: | |
6299 | blob = binascii.hexlify(pac) | |
6300 | dev[0].request("SET blob fast_pac_errors " + blob) | |
6301 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6302 | eap="FAST", anonymous_identity="FAST", | |
6303 | identity="user", password="password", | |
6304 | ca_cert="auth_serv/ca.pem", phase2="auth=GTC", | |
6305 | phase1="fast_provisioning=2", | |
6306 | pac_file="blob://fast_pac_errors", | |
6307 | wait_connect=False) | |
6308 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
6309 | timeout=5) | |
6310 | if ev is None: | |
6311 | raise Exception("Timeout on EAP start") | |
6312 | dev[0].request("REMOVE_NETWORK all") | |
6313 | dev[0].wait_disconnected() | |
6314 | ||
6315 | tests = [ "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\n", | |
6316 | "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\nSTART\nEND\nSTART\nEND\n" ] | |
6317 | for pac in tests: | |
6318 | blob = binascii.hexlify(pac) | |
6319 | dev[0].request("SET blob fast_pac_errors " + blob) | |
6320 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6321 | eap="FAST", anonymous_identity="FAST", | |
6322 | identity="user", password="password", | |
6323 | ca_cert="auth_serv/ca.pem", phase2="auth=GTC", | |
6324 | phase1="fast_provisioning=2", | |
6325 | pac_file="blob://fast_pac_errors") | |
6326 | dev[0].request("REMOVE_NETWORK all") | |
6327 | dev[0].wait_disconnected() | |
6328 | ||
6329 | dev[0].request("SET blob fast_pac_errors ") | |
a551da6a JM |
6330 | |
6331 | def test_eap_proto_peap_errors(dev, apdev): | |
6332 | """EAP-PEAP local error cases""" | |
6333 | check_eap_capa(dev[0], "PEAP") | |
6334 | check_eap_capa(dev[0], "MSCHAPV2") | |
6335 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
6336 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
6337 | ||
6338 | for i in range(1, 5): | |
6339 | with alloc_fail(dev[0], i, "eap_peap_init"): | |
6340 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6341 | eap="PEAP", anonymous_identity="peap", | |
6342 | identity="user", password="password", | |
6343 | ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", | |
6344 | wait_connect=False) | |
6345 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
6346 | timeout=5) | |
6347 | if ev is None: | |
6348 | raise Exception("Timeout on EAP start") | |
6349 | dev[0].request("REMOVE_NETWORK all") | |
6350 | dev[0].wait_disconnected() | |
6351 | ||
6352 | tests = [ (1, "eap_mschapv2_getKey;eap_peap_get_isk;eap_peap_derive_cmk"), | |
6353 | (1, "eap_msg_alloc;eap_tlv_build_result"), | |
6354 | (1, "eap_mschapv2_init;eap_peap_phase2_request"), | |
6355 | (1, "eap_peer_tls_decrypt;eap_peap_decrypt"), | |
6356 | (1, "wpabuf_alloc;=eap_peap_decrypt"), | |
6357 | (1, "eap_peer_tls_encrypt;eap_peap_decrypt"), | |
6358 | (1, "eap_peer_tls_process_helper;eap_peap_process"), | |
6359 | (1, "eap_peer_tls_derive_key;eap_peap_process"), | |
6360 | (1, "eap_peer_tls_derive_session_id;eap_peap_process"), | |
6361 | (1, "eap_peap_getKey"), | |
6362 | (1, "eap_peap_get_session_id") ] | |
6363 | for count, func in tests: | |
6364 | with alloc_fail(dev[0], count, func): | |
6365 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6366 | eap="PEAP", anonymous_identity="peap", | |
6367 | identity="user", password="password", | |
6368 | phase1="peapver=0 crypto_binding=2", | |
6369 | ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", | |
6370 | erp="1", wait_connect=False) | |
6371 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
6372 | timeout=15) | |
6373 | if ev is None: | |
6374 | raise Exception("Timeout on EAP start") | |
6375 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
6376 | dev[0].request("REMOVE_NETWORK all") | |
6377 | dev[0].wait_disconnected() | |
6378 | ||
6379 | tests = [ (1, "peap_prfplus;eap_peap_derive_cmk"), | |
6380 | (1, "eap_tlv_add_cryptobinding;eap_tlv_build_result"), | |
6381 | (1, "peap_prfplus;eap_peap_getKey") ] | |
6382 | for count, func in tests: | |
6383 | with fail_test(dev[0], count, func): | |
6384 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6385 | eap="PEAP", anonymous_identity="peap", | |
6386 | identity="user", password="password", | |
6387 | phase1="peapver=0 crypto_binding=2", | |
6388 | ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", | |
6389 | erp="1", wait_connect=False) | |
6390 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
6391 | timeout=15) | |
6392 | if ev is None: | |
6393 | raise Exception("Timeout on EAP start") | |
6394 | wait_fail_trigger(dev[0], "GET_FAIL") | |
6395 | dev[0].request("REMOVE_NETWORK all") | |
6396 | dev[0].wait_disconnected() | |
6397 | ||
6398 | with alloc_fail(dev[0], 1, | |
6399 | "eap_peer_tls_phase2_nak;eap_peap_phase2_request"): | |
6400 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6401 | eap="PEAP", anonymous_identity="peap", | |
6402 | identity="cert user", password="password", | |
6403 | ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", | |
6404 | wait_connect=False) | |
6405 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
6406 | dev[0].request("REMOVE_NETWORK all") | |
6407 | dev[0].wait_disconnected() | |
c44e4994 JM |
6408 | |
6409 | def test_eap_proto_ttls_errors(dev, apdev): | |
6410 | """EAP-TTLS local error cases""" | |
6411 | check_eap_capa(dev[0], "TTLS") | |
6412 | check_eap_capa(dev[0], "MSCHAPV2") | |
6413 | params = hostapd.wpa2_eap_params(ssid="eap-test") | |
6414 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
6415 | ||
6416 | for i in range(1, 5): | |
6417 | with alloc_fail(dev[0], i, "eap_ttls_init"): | |
6418 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6419 | eap="TTLS", anonymous_identity="ttls", | |
6420 | identity="user", password="password", | |
6421 | ca_cert="auth_serv/ca.pem", | |
6422 | phase2="autheap=MSCHAPV2", | |
6423 | wait_connect=False) | |
6424 | ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], | |
6425 | timeout=5) | |
6426 | if ev is None: | |
6427 | raise Exception("Timeout on EAP start") | |
6428 | dev[0].request("REMOVE_NETWORK all") | |
6429 | dev[0].wait_disconnected() | |
6430 | ||
6431 | tests = [ (1, "eap_peer_tls_derive_key;eap_ttls_v0_derive_key", | |
6432 | "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), | |
6433 | (1, "eap_peer_tls_derive_session_id;eap_ttls_v0_derive_key", | |
6434 | "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), | |
6435 | (1, "wpabuf_alloc;eap_ttls_phase2_request_mschapv2", | |
6436 | "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), | |
6437 | (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschapv2", | |
6438 | "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), | |
6439 | (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_implicit_identity_request", | |
6440 | "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), | |
6441 | (1, "eap_peer_tls_decrypt;eap_ttls_decrypt", | |
6442 | "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), | |
6443 | (1, "eap_ttls_getKey", | |
6444 | "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), | |
6445 | (1, "eap_ttls_get_session_id", | |
6446 | "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), | |
6447 | (1, "eap_ttls_get_emsk", | |
6448 | "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), | |
6449 | (1, "wpabuf_alloc;eap_ttls_phase2_request_mschap", | |
6450 | "mschap user", "auth=MSCHAP"), | |
6451 | (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschap", | |
6452 | "mschap user", "auth=MSCHAP"), | |
6453 | (1, "wpabuf_alloc;eap_ttls_phase2_request_chap", | |
6454 | "chap user", "auth=CHAP"), | |
6455 | (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_chap", | |
6456 | "chap user", "auth=CHAP"), | |
6457 | (1, "wpabuf_alloc;eap_ttls_phase2_request_pap", | |
6458 | "pap user", "auth=PAP"), | |
6459 | (1, "wpabuf_alloc;eap_ttls_avp_encapsulate", | |
6460 | "user", "autheap=MSCHAPV2"), | |
6461 | (1, "eap_mschapv2_init;eap_ttls_phase2_request_eap_method", | |
6462 | "user", "autheap=MSCHAPV2"), | |
6463 | (1, "eap_sm_buildIdentity;eap_ttls_phase2_request_eap", | |
6464 | "user", "autheap=MSCHAPV2"), | |
6465 | (1, "eap_ttls_avp_encapsulate;eap_ttls_phase2_request_eap", | |
6466 | "user", "autheap=MSCHAPV2"), | |
6467 | (1, "eap_ttls_parse_attr_eap", | |
6468 | "user", "autheap=MSCHAPV2"), | |
6469 | (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_process_decrypted", | |
6470 | "user", "autheap=MSCHAPV2"), | |
6471 | (1, "eap_ttls_fake_identity_request", | |
6472 | "user", "autheap=MSCHAPV2"), | |
6473 | (1, "eap_msg_alloc;eap_tls_process_output", | |
6474 | "user", "autheap=MSCHAPV2"), | |
6475 | (1, "eap_msg_alloc;eap_peer_tls_build_ack", | |
6476 | "user", "autheap=MSCHAPV2"), | |
6477 | (1, "tls_connection_decrypt;eap_peer_tls_decrypt", | |
6478 | "user", "autheap=MSCHAPV2"), | |
6479 | (1, "eap_peer_tls_phase2_nak;eap_ttls_phase2_request_eap_method", | |
6480 | "cert user", "autheap=MSCHAPV2") ] | |
6481 | for count, func, identity, phase2 in tests: | |
6482 | with alloc_fail(dev[0], count, func): | |
6483 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6484 | eap="TTLS", anonymous_identity="ttls", | |
6485 | identity=identity, password="password", | |
6486 | ca_cert="auth_serv/ca.pem", phase2=phase2, | |
6487 | erp="1", wait_connect=False) | |
6488 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
6489 | timeout=15) | |
6490 | if ev is None: | |
6491 | raise Exception("Timeout on EAP start") | |
6492 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL", | |
6493 | note="Allocation failure not triggered for: %d:%s" % (count, func)) | |
6494 | dev[0].request("REMOVE_NETWORK all") | |
6495 | dev[0].wait_disconnected() | |
6496 | ||
6497 | tests = [ (1, "os_get_random;eap_ttls_phase2_request_mschapv2"), | |
6498 | (1, "mschapv2_derive_response;eap_ttls_phase2_request_mschapv2") ] | |
6499 | for count, func in tests: | |
6500 | with fail_test(dev[0], count, func): | |
6501 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6502 | eap="TTLS", anonymous_identity="ttls", | |
6503 | identity="DOMAIN\mschapv2 user", password="password", | |
6504 | ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", | |
6505 | erp="1", wait_connect=False) | |
6506 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
6507 | timeout=15) | |
6508 | if ev is None: | |
6509 | raise Exception("Timeout on EAP start") | |
6510 | wait_fail_trigger(dev[0], "GET_FAIL", | |
6511 | note="Test failure not triggered for: %d:%s" % (count, func)) | |
6512 | dev[0].request("REMOVE_NETWORK all") | |
6513 | dev[0].wait_disconnected() | |
2fd377de JM |
6514 | |
6515 | def test_eap_proto_expanded(dev, apdev): | |
6516 | """EAP protocol tests with expanded header""" | |
6517 | global eap_proto_expanded_test_done | |
6518 | eap_proto_expanded_test_done = False | |
6519 | ||
6520 | def expanded_handler(ctx, req): | |
6521 | logger.info("expanded_handler - RX " + req.encode("hex")) | |
6522 | if 'num' not in ctx: | |
6523 | ctx['num'] = 0 | |
6524 | ctx['num'] += 1 | |
6525 | if 'id' not in ctx: | |
6526 | ctx['id'] = 1 | |
6527 | ctx['id'] = (ctx['id'] + 1) % 256 | |
6528 | idx = 0 | |
6529 | ||
6530 | idx += 1 | |
6531 | if ctx['num'] == idx: | |
6532 | logger.info("Test: MD5 challenge in expanded header") | |
6533 | return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'], | |
6534 | 4 + 1 + 3 + 4 + 3, | |
6535 | EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5, | |
6536 | 1, 0xaa, ord('n')) | |
6537 | idx += 1 | |
6538 | if ctx['num'] == idx: | |
6539 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6540 | ||
6541 | idx += 1 | |
6542 | if ctx['num'] == idx: | |
6543 | logger.info("Test: Invalid expanded EAP length") | |
6544 | return struct.pack(">BBHB3BH", EAP_CODE_REQUEST, ctx['id'], | |
6545 | 4 + 1 + 3 + 2, | |
6546 | EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5) | |
6547 | idx += 1 | |
6548 | if ctx['num'] == idx: | |
6549 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6550 | ||
6551 | idx += 1 | |
6552 | if ctx['num'] == idx: | |
6553 | logger.info("Test: Invalid expanded frame type") | |
6554 | return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'], | |
6555 | 4 + 1 + 3 + 4, | |
6556 | EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MD5) | |
6557 | idx += 1 | |
6558 | if ctx['num'] == idx: | |
6559 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6560 | ||
6561 | idx += 1 | |
6562 | if ctx['num'] == idx: | |
6563 | logger.info("Test: MSCHAPv2 Challenge") | |
6564 | return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], | |
6565 | 4 + 1 + 4 + 1 + 16 + 6, | |
6566 | EAP_TYPE_MSCHAPV2, | |
6567 | 1, 0, 4 + 1 + 16 + 6, 16) + 16*'A' + 'foobar' | |
6568 | idx += 1 | |
6569 | if ctx['num'] == idx: | |
6570 | logger.info("Test: Invalid expanded frame type") | |
6571 | return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'], | |
6572 | 4 + 1 + 3 + 4, | |
6573 | EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MSCHAPV2) | |
6574 | ||
6575 | logger.info("No more test responses available - test case completed") | |
6576 | global eap_proto_expanded_test_done | |
6577 | eap_proto_expanded_test_done = True | |
6578 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6579 | ||
6580 | srv = start_radius_server(expanded_handler) | |
6581 | ||
6582 | try: | |
6583 | hapd = start_ap(apdev[0]['ifname']) | |
6584 | ||
6585 | i = 0 | |
6586 | while not eap_proto_expanded_test_done: | |
6587 | i += 1 | |
6588 | logger.info("Running connection iteration %d" % i) | |
6589 | if i == 4: | |
6590 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6591 | eap="MSCHAPV2", identity="user", | |
6592 | password="password", | |
6593 | wait_connect=False) | |
6594 | else: | |
6595 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6596 | eap="MD5", identity="user", password="password", | |
6597 | wait_connect=False) | |
6598 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) | |
6599 | if ev is None: | |
6600 | raise Exception("Timeout on EAP start") | |
6601 | if i in [ 1 ]: | |
6602 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) | |
6603 | if ev is None: | |
6604 | raise Exception("Timeout on EAP method start") | |
6605 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) | |
6606 | if ev is None: | |
6607 | raise Exception("Timeout on EAP failure") | |
6608 | elif i in [ 2, 3 ]: | |
6609 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], | |
6610 | timeout=5) | |
6611 | if ev is None: | |
6612 | raise Exception("Timeout on EAP proposed method") | |
6613 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) | |
6614 | if ev is None: | |
6615 | raise Exception("Timeout on EAP failure") | |
6616 | else: | |
6617 | time.sleep(0.1) | |
6618 | dev[0].request("REMOVE_NETWORK all") | |
6619 | dev[0].wait_disconnected(timeout=1) | |
6620 | dev[0].dump_monitor() | |
6621 | finally: | |
6622 | stop_radius_server(srv) | |
0c8eacd1 JM |
6623 | |
6624 | def test_eap_proto_tnc(dev, apdev): | |
6625 | """EAP-TNC protocol tests""" | |
6626 | check_eap_capa(dev[0], "TNC") | |
6627 | global eap_proto_tnc_test_done | |
6628 | eap_proto_tnc_test_done = False | |
6629 | ||
6630 | def tnc_handler(ctx, req): | |
6631 | logger.info("tnc_handler - RX " + req.encode("hex")) | |
6632 | if 'num' not in ctx: | |
6633 | ctx['num'] = 0 | |
6634 | ctx['num'] += 1 | |
6635 | if 'id' not in ctx: | |
6636 | ctx['id'] = 1 | |
6637 | ctx['id'] = (ctx['id'] + 1) % 256 | |
6638 | idx = 0 | |
6639 | ||
6640 | idx += 1 | |
6641 | if ctx['num'] == idx: | |
6642 | logger.info("Test: TNC start with unsupported version") | |
6643 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6644 | 4 + 1 + 1, | |
6645 | EAP_TYPE_TNC, 0x20) | |
6646 | ||
6647 | idx += 1 | |
6648 | if ctx['num'] == idx: | |
6649 | logger.info("Test: TNC without Flags field") | |
6650 | return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], | |
6651 | 4 + 1, | |
6652 | EAP_TYPE_TNC) | |
6653 | ||
6654 | idx += 1 | |
6655 | if ctx['num'] == idx: | |
6656 | logger.info("Test: Message underflow due to missing Message Length") | |
6657 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6658 | 4 + 1 + 1, | |
6659 | EAP_TYPE_TNC, 0xa1) | |
6660 | ||
6661 | idx += 1 | |
6662 | if ctx['num'] == idx: | |
6663 | logger.info("Test: Invalid Message Length") | |
6664 | return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], | |
6665 | 4 + 1 + 1 + 4 + 1, | |
6666 | EAP_TYPE_TNC, 0xa1, 0, 0) | |
6667 | ||
6668 | idx += 1 | |
6669 | if ctx['num'] == idx: | |
6670 | logger.info("Test: Invalid Message Length") | |
6671 | return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], | |
6672 | 4 + 1 + 1 + 4, | |
6673 | EAP_TYPE_TNC, 0xe1, 75001) | |
6674 | ||
6675 | idx += 1 | |
6676 | if ctx['num'] == idx: | |
6677 | logger.info("Test: Start with Message Length") | |
6678 | return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], | |
6679 | 4 + 1 + 1 + 4, | |
6680 | EAP_TYPE_TNC, 0xa1, 1) | |
6681 | idx += 1 | |
6682 | if ctx['num'] == idx: | |
6683 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6684 | ||
6685 | idx += 1 | |
6686 | if ctx['num'] == idx: | |
6687 | logger.info("Test: Server used start flag again") | |
6688 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6689 | 4 + 1 + 1, | |
6690 | EAP_TYPE_TNC, 0x21) | |
6691 | idx += 1 | |
6692 | if ctx['num'] == idx: | |
6693 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6694 | 4 + 1 + 1, | |
6695 | EAP_TYPE_TNC, 0x21) | |
6696 | ||
6697 | idx += 1 | |
6698 | if ctx['num'] == idx: | |
6699 | logger.info("Test: Fragmentation and unexpected payload in ack") | |
6700 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6701 | 4 + 1 + 1, | |
6702 | EAP_TYPE_TNC, 0x21) | |
6703 | idx += 1 | |
6704 | if ctx['num'] == idx: | |
6705 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6706 | 4 + 1 + 1, | |
6707 | EAP_TYPE_TNC, 0x01) | |
6708 | idx += 1 | |
6709 | if ctx['num'] == idx: | |
6710 | return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], | |
6711 | 4 + 1 + 1 + 1, | |
6712 | EAP_TYPE_TNC, 0x01, 0) | |
6713 | ||
6714 | idx += 1 | |
6715 | if ctx['num'] == idx: | |
6716 | logger.info("Test: Server fragmenting and fragment overflow") | |
6717 | return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], | |
6718 | 4 + 1 + 1 + 4 + 1, | |
6719 | EAP_TYPE_TNC, 0xe1, 2, 1) | |
6720 | idx += 1 | |
6721 | if ctx['num'] == idx: | |
6722 | return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], | |
6723 | 4 + 1 + 1 + 2, | |
6724 | EAP_TYPE_TNC, 0x01, 2, 3) | |
6725 | ||
6726 | idx += 1 | |
6727 | if ctx['num'] == idx: | |
6728 | logger.info("Test: Server fragmenting and no message length in a fragment") | |
6729 | return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], | |
6730 | 4 + 1 + 1 + 1, | |
6731 | EAP_TYPE_TNC, 0x61, 2) | |
6732 | ||
6733 | idx += 1 | |
6734 | if ctx['num'] == idx: | |
6735 | logger.info("Test: TNC start followed by invalid TNCCS-Batch") | |
6736 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6737 | 4 + 1 + 1, | |
6738 | EAP_TYPE_TNC, 0x21) | |
6739 | idx += 1 | |
6740 | if ctx['num'] == idx: | |
6741 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6742 | resp = "FOO" | |
6743 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6744 | 4 + 1 + 1 + len(resp), | |
6745 | EAP_TYPE_TNC, 0x01) + resp | |
6746 | ||
6747 | idx += 1 | |
6748 | if ctx['num'] == idx: | |
6749 | logger.info("Test: TNC start followed by invalid TNCCS-Batch (2)") | |
6750 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6751 | 4 + 1 + 1, | |
6752 | EAP_TYPE_TNC, 0x21) | |
6753 | idx += 1 | |
6754 | if ctx['num'] == idx: | |
6755 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6756 | resp = "</TNCCS-Batch><TNCCS-Batch>" | |
6757 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6758 | 4 + 1 + 1 + len(resp), | |
6759 | EAP_TYPE_TNC, 0x01) + resp | |
6760 | ||
6761 | idx += 1 | |
6762 | if ctx['num'] == idx: | |
6763 | logger.info("Test: TNCCS-Batch missing BatchId attribute") | |
6764 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6765 | 4 + 1 + 1, | |
6766 | EAP_TYPE_TNC, 0x21) | |
6767 | idx += 1 | |
6768 | if ctx['num'] == idx: | |
6769 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6770 | resp = "<TNCCS-Batch foo=3></TNCCS-Batch>" | |
6771 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6772 | 4 + 1 + 1 + len(resp), | |
6773 | EAP_TYPE_TNC, 0x01) + resp | |
6774 | ||
6775 | idx += 1 | |
6776 | if ctx['num'] == idx: | |
6777 | logger.info("Test: Unexpected IF-TNCCS BatchId") | |
6778 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6779 | 4 + 1 + 1, | |
6780 | EAP_TYPE_TNC, 0x21) | |
6781 | idx += 1 | |
6782 | if ctx['num'] == idx: | |
6783 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6784 | resp = "<TNCCS-Batch BatchId=123456789></TNCCS-Batch>" | |
6785 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6786 | 4 + 1 + 1 + len(resp), | |
6787 | EAP_TYPE_TNC, 0x01) + resp | |
6788 | ||
6789 | idx += 1 | |
6790 | if ctx['num'] == idx: | |
6791 | logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message end tags") | |
6792 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6793 | 4 + 1 + 1, | |
6794 | EAP_TYPE_TNC, 0x21) | |
6795 | idx += 1 | |
6796 | if ctx['num'] == idx: | |
6797 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6798 | resp = "<TNCCS-Batch BatchId=2><IMC-IMV-Message><TNCC-TNCS-Message></TNCCS-Batch>" | |
6799 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6800 | 4 + 1 + 1 + len(resp), | |
6801 | EAP_TYPE_TNC, 0x01) + resp | |
6802 | idx += 1 | |
6803 | if ctx['num'] == idx: | |
6804 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6805 | ||
6806 | idx += 1 | |
6807 | if ctx['num'] == idx: | |
6808 | logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message Type") | |
6809 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6810 | 4 + 1 + 1, | |
6811 | EAP_TYPE_TNC, 0x21) | |
6812 | idx += 1 | |
6813 | if ctx['num'] == idx: | |
6814 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6815 | resp = "<TNCCS-Batch BatchId=2><IMC-IMV-Message></IMC-IMV-Message><TNCC-TNCS-Message></TNCC-TNCS-Message></TNCCS-Batch>" | |
6816 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6817 | 4 + 1 + 1 + len(resp), | |
6818 | EAP_TYPE_TNC, 0x01) + resp | |
6819 | idx += 1 | |
6820 | if ctx['num'] == idx: | |
6821 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6822 | ||
6823 | idx += 1 | |
6824 | if ctx['num'] == idx: | |
6825 | logger.info("Test: Missing TNCC-TNCS-Message XML end tag") | |
6826 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6827 | 4 + 1 + 1, | |
6828 | EAP_TYPE_TNC, 0x21) | |
6829 | idx += 1 | |
6830 | if ctx['num'] == idx: | |
6831 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6832 | resp = "<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML></TNCC-TNCS-Message></TNCCS-Batch>" | |
6833 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6834 | 4 + 1 + 1 + len(resp), | |
6835 | EAP_TYPE_TNC, 0x01) + resp | |
6836 | idx += 1 | |
6837 | if ctx['num'] == idx: | |
6838 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6839 | ||
6840 | idx += 1 | |
6841 | if ctx['num'] == idx: | |
6842 | logger.info("Test: Missing TNCC-TNCS-Message Base64 start tag") | |
6843 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6844 | 4 + 1 + 1, | |
6845 | EAP_TYPE_TNC, 0x21) | |
6846 | idx += 1 | |
6847 | if ctx['num'] == idx: | |
6848 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6849 | resp = "<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type></TNCC-TNCS-Message></TNCCS-Batch>" | |
6850 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6851 | 4 + 1 + 1 + len(resp), | |
6852 | EAP_TYPE_TNC, 0x01) + resp | |
6853 | idx += 1 | |
6854 | if ctx['num'] == idx: | |
6855 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6856 | ||
6857 | idx += 1 | |
6858 | if ctx['num'] == idx: | |
6859 | logger.info("Test: Missing TNCC-TNCS-Message Base64 end tag") | |
6860 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6861 | 4 + 1 + 1, | |
6862 | EAP_TYPE_TNC, 0x21) | |
6863 | idx += 1 | |
6864 | if ctx['num'] == idx: | |
6865 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6866 | resp = "<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>abc</TNCC-TNCS-Message></TNCCS-Batch>" | |
6867 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6868 | 4 + 1 + 1 + len(resp), | |
6869 | EAP_TYPE_TNC, 0x01) + resp | |
6870 | idx += 1 | |
6871 | if ctx['num'] == idx: | |
6872 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6873 | ||
6874 | idx += 1 | |
6875 | if ctx['num'] == idx: | |
6876 | logger.info("Test: TNCC-TNCS-Message Base64 message") | |
6877 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6878 | 4 + 1 + 1, | |
6879 | EAP_TYPE_TNC, 0x21) | |
6880 | idx += 1 | |
6881 | if ctx['num'] == idx: | |
6882 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6883 | resp = "<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>aGVsbG8=</Base64></TNCC-TNCS-Message></TNCCS-Batch>" | |
6884 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6885 | 4 + 1 + 1 + len(resp), | |
6886 | EAP_TYPE_TNC, 0x01) + resp | |
6887 | idx += 1 | |
6888 | if ctx['num'] == idx: | |
6889 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6890 | ||
6891 | idx += 1 | |
6892 | if ctx['num'] == idx: | |
6893 | logger.info("Test: Invalid TNCC-TNCS-Message XML message") | |
6894 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6895 | 4 + 1 + 1, | |
6896 | EAP_TYPE_TNC, 0x21) | |
6897 | idx += 1 | |
6898 | if ctx['num'] == idx: | |
6899 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6900 | resp = "<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML>hello</XML></TNCC-TNCS-Message></TNCCS-Batch>" | |
6901 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6902 | 4 + 1 + 1 + len(resp), | |
6903 | EAP_TYPE_TNC, 0x01) + resp | |
6904 | idx += 1 | |
6905 | if ctx['num'] == idx: | |
6906 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6907 | ||
6908 | idx += 1 | |
6909 | if ctx['num'] == idx: | |
6910 | logger.info("Test: Missing TNCCS-Recommendation type") | |
6911 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6912 | 4 + 1 + 1, | |
6913 | EAP_TYPE_TNC, 0x21) | |
6914 | idx += 1 | |
6915 | if ctx['num'] == idx: | |
6916 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6917 | resp = '<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML><TNCCS-Recommendation foo=1></TNCCS-Recommendation></XML></TNCC-TNCS-Message></TNCCS-Batch>' | |
6918 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6919 | 4 + 1 + 1 + len(resp), | |
6920 | EAP_TYPE_TNC, 0x01) + resp | |
6921 | idx += 1 | |
6922 | if ctx['num'] == idx: | |
6923 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6924 | ||
6925 | idx += 1 | |
6926 | if ctx['num'] == idx: | |
6927 | logger.info("Test: TNCCS-Recommendation type=none") | |
6928 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6929 | 4 + 1 + 1, | |
6930 | EAP_TYPE_TNC, 0x21) | |
6931 | idx += 1 | |
6932 | if ctx['num'] == idx: | |
6933 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6934 | resp = '<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML><TNCCS-Recommendation type="none"></TNCCS-Recommendation></XML></TNCC-TNCS-Message></TNCCS-Batch>' | |
6935 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6936 | 4 + 1 + 1 + len(resp), | |
6937 | EAP_TYPE_TNC, 0x01) + resp | |
6938 | idx += 1 | |
6939 | if ctx['num'] == idx: | |
6940 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6941 | ||
6942 | idx += 1 | |
6943 | if ctx['num'] == idx: | |
6944 | logger.info("Test: TNCCS-Recommendation type=isolate") | |
6945 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6946 | 4 + 1 + 1, | |
6947 | EAP_TYPE_TNC, 0x21) | |
6948 | idx += 1 | |
6949 | if ctx['num'] == idx: | |
6950 | logger.info("Received TNCCS-Batch: " + req[6:]) | |
6951 | resp = '<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML><TNCCS-Recommendation type="isolate"></TNCCS-Recommendation></XML></TNCC-TNCS-Message></TNCCS-Batch>' | |
6952 | return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], | |
6953 | 4 + 1 + 1 + len(resp), | |
6954 | EAP_TYPE_TNC, 0x01) + resp | |
6955 | idx += 1 | |
6956 | if ctx['num'] == idx: | |
6957 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6958 | ||
6959 | logger.info("No more test responses available - test case completed") | |
6960 | global eap_proto_tnc_test_done | |
6961 | eap_proto_tnc_test_done = True | |
6962 | return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) | |
6963 | ||
6964 | srv = start_radius_server(tnc_handler) | |
6965 | ||
6966 | try: | |
6967 | hapd = start_ap(apdev[0]['ifname']) | |
6968 | ||
6969 | i = 0 | |
6970 | while not eap_proto_tnc_test_done: | |
6971 | i += 1 | |
6972 | logger.info("Running connection iteration %d" % i) | |
6973 | frag = 1400 | |
6974 | if i == 8: | |
6975 | frag = 150 | |
6976 | dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", | |
6977 | eap="TNC", identity="tnc", fragment_size=str(frag), | |
6978 | wait_connect=False) | |
6979 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) | |
6980 | if ev is None: | |
6981 | raise Exception("Timeout on EAP start") | |
6982 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD", | |
6983 | "CTRL-EVENT-EAP-STATUS"], timeout=5) | |
6984 | if ev is None: | |
6985 | raise Exception("Timeout on EAP method start") | |
6986 | time.sleep(0.1) | |
6987 | dev[0].request("REMOVE_NETWORK all") | |
6988 | dev[0].wait_disconnected(timeout=1) | |
6989 | dev[0].dump_monitor() | |
6990 | finally: | |
6991 | stop_radius_server(srv) |